电商商品评论主题分析(LDA)

下面代码的意思是从评论数据中抽取品牌是美的的数据(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其实也是聚类的,主要是处理字符串的,对字符串进行聚类。



你可能感兴趣的:(机器学习实战,自然语言处理,商品评论,主题分析,LDA)