下面代码的意思是从评论数据中抽取品牌是美的的数据(15-1)
#-*- coding: utf-8 -*-
import pandas as pd
inputfile = '../data/huizong.csv' #评论汇总文件
outputfile = '../data/meidi_jd.txt' #评论提取后保存路径
data = pd.read_csv(inputfile, encoding = 'utf-8')
data = data[[u'评论']][data[u'品牌'] == u'美的']
data.to_csv(outputfile, index = False, header = False, encoding = 'utf-8')
这里一句话概括接下来的去重概念,文本去重和机械压缩去重
文本去重指的是数据条之间的去重。
机械压缩去重指的是数据条内部,词语与词语之间的去重。
下面代码是用来文本去重的(15-2)。
#-*- coding: utf-8 -*-
import pandas as pd
inputfile = '../data/meidi_jd.txt' #评论文件
outputfile = '../data/meidi_jd_process_1.txt' #评论处理后保存路径
data = pd.read_csv(inputfile, encoding = 'utf-8', header = None)
l1 = len(data)
data = pd.DataFrame(data[0].unique())
l2 = len(data)
data.to_csv(outputfile, index = False, header = False, encoding = 'utf-8')
print(u'删除了%s条评论。' %(l1 - l2))
下面代码的作用是把评论前面的评分删除(15-3):
#-*- coding: utf-8 -*-
import pandas as pd
#参数初始化
inputfile1 = '../data/meidi_jd_process_end_负面情感结果.txt'
inputfile2 = '../data/meidi_jd_process_end_正面情感结果.txt'
outputfile1 = '../data/meidi_jd_neg.txt'
outputfile2 = '../data/meidi_jd_pos.txt'
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #读入数据
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None)
print("data1=",data1[0])
data1 = pd.DataFrame(data1[0].str.replace('.*?\d+?\\t ', '')) #用正则表达式修改数据
data2 = pd.DataFrame(data2[0].str.replace('.*?\d+?\\t ', ''))#这里的意思其实是用‘’(也就是代表什么都没有)来代替前面的符合特征的字符串,等效于实现了删除的功能
print("###############################")
print("data1=",data1[0])
#以上正则表达式的效果,可以通过把正则筛选前后的data[0]分别输出来进行比较
data1.to_csv(outputfile1, index = False, header = False, encoding = 'utf-8') #保存结果
data2.to_csv(outputfile2, index = False, header = False, encoding = 'utf-8')
接下来是进行分词(详细解释请见代码中注释)(15-4)
#-*- coding: utf-8 -*-
import pandas as pd
import jieba #导入结巴分词,需要自行下载安装
#参数初始化
inputfile1 = '../data/meidi_jd_neg.txt'
inputfile2 = '../data/meidi_jd_pos.txt'
outputfile1 = '../data/meidi_jd_neg_cut.txt'
outputfile2 = '../data/meidi_jd_pos_cut.txt'
data1 = pd.read_csv(inputfile1, encoding = 'utf-8', header = None) #读入数据
data2 = pd.read_csv(inputfile2, encoding = 'utf-8', header = None)
mycut = lambda s: ' '.join(jieba.cut(s)) #自定义简单分词函数,先识别句子中的中文单词,然后把中文单词通过空格连接起来
#上面一句代码中,s是入口参数,.join前面的空格表示把jieba库处理过后的s中的词语jieba.cut(s),用空格来连接。
data1 = data1[0].apply(mycut) #通过“广播”形式分词,加快速度。
data2 = data2[0].apply(mycut)
data1.to_csv(outputfile1, index = False, header = False, encoding = 'utf-8') #保存结果
data2.to_csv(outputfile2, index = False, header = False, encoding = 'utf-8')
接下来是去除停用词
#-*- coding: utf-8 -*-
import pandas as pd
#参数初始化
negfile = '../data/meidi_jd_neg_cut.txt'
posfile = '../data/meidi_jd_pos_cut.txt'
stoplist = '../data/stoplist.txt'
neg = pd.read_csv(negfile, encoding = 'utf-8', header = None) #读入数据
pos = pd.read_csv(posfile, encoding = 'utf-8', header = None)
stop = pd.read_csv(stoplist, encoding = 'utf-8', header = None, sep = 'tipdm',engine='python')
#sep设置分割词,由于csv默认以半角逗号为分割词,而该词恰好在停用词表中,因此会导致读取出错(这里的出错的意思就是代码运行报错,编译器直接不让编译通过)
#所以解决办法是手动设置一个不存在的分割词,如tipdm。
#这里先解释下什么是“停用词”,停用词指的是本文中出现频率很高、但是实际意义不大的词语,比如
#“今天好嗨森啊啊啊啊啊啊啊啊”,那么这句话中的“啊啊啊啊啊啊啊啊”就是停用词
#讲通俗点的话,停用词就是“废话”。 。
stop = [' ', ''] + list(stop[0]) #Pandas自动过滤了空格符,这里手动添加(在每条数据的开头加个空格)
#下面这段代码可以分为两小段,这两小段代码几乎一致,前面一个是针对负面评论,后一个是针对正面评论,所以只详解其中一个
neg[1] = neg[0].apply(lambda s: s.split(' ')) #定义一个分割函数,然后用apply广播
neg[2] = neg[1].apply(lambda x: [i for i in x if i not in stop]) #逐词判断是否停用词,思路同上
#上面这句代码的语法是:列表推导式子。意思是说,如果i不在停用词列表(stop)中,就保留该词语(也就是最前面的一个i),否则就进行删除
#上面的这句代码中,把for i in x看做整体,把if i not in stop看做判断语句,把最前面的i看做满足if语句之后的执行语句即可。
pos[1] = pos[0].apply(lambda s: s.split(' '))
pos[2] = pos[1].apply(lambda x: [i for i in x if i not in stop])
#上面的lamda s和lamda x中的s和x都是表示入口参数,apply的意思是,把apply前面的字符串当做入口参数,输入到appy后面所定义的函数中
最后是建立LDA模型:
from gensim import corpora, models
#负面主题分析
#这段代码和下面的“正面主题分析”几乎是完全一样的,作用讲得通俗点其实就是聚类。
neg_dict = corpora.Dictionary(neg[2]) #建立词典
neg_corpus = [neg_dict.doc2bow(i) for i in neg[2]] #建立语料库
neg_lda = models.LdaModel(neg_corpus, num_topics = 3, id2word = neg_dict) #LDA模型训练
for i in range(3):
neg_lda.print_topic(i) #输出每个主题(这个其实就是聚类结果的输出)
#正面主题分析
pos_dict = corpora.Dictionary(pos[2])
pos_corpus = [pos_dict.doc2bow(i) for i in pos[2]]
pos_lda = models.LdaModel(pos_corpus, num_topics = 3, id2word = pos_dict)
for i in range(3):
neg_lda.print_topic(i) #输出每个主题
结果类似于:
0.065*"安装" + 0.025*"热水器" + 0.020*"说" + 0.017*"买" + 0.017*"美的" + 0.016*"师傅" + 0.012*"元" + 0.011*"京东" + 0.009*"售后" + 0.009*"安装费"
0.035*"安装" + 0.023*"加热" + 0.023*"不错" + 0.013*"东西" + 0.011*"没用" + 0.011*"送货" + 0.010*"热水器" + 0.009*"师傅" + 0.009*"速度" + 0.009*"不好"
0.031*"买" + 0.031*"不错" + 0.016*"安装" + 0.014*"热水器" + 0.010*"价格" + 0.009*"加热" + 0.007*"元" + 0.007*"速度" + 0.007*"质量" + 0.006*"京东"
通俗解释下LDA算法干嘛的,我们知道:
K-means是聚类的,他主要是处理数据的,对数据进行聚类。
LDA其实也是聚类的,主要是处理字符串的,对字符串进行聚类。