一、本案例采集京东网站热水器不同品牌的评论数据进行分析

1.导入数据

1 import pandas as pd
2 data = pd.read_csv('comment.csv')
3 data.head()

lda各个主题的情感得分 lda情感分析_lda各个主题的情感得分

2.数据探索

①绘制各品牌的销售情况

1 brand_dis = data['品牌'].value_counts()  #统计各类品牌的销量.sort_values()
2 import matplotlib.pyplot as plt
3 plt.rcParams['font.sans-serif'] = 'SimHei'
4 plt.pie(brand_dis,autopct='%0.2f%%',labels=brand_dis.index)
5 plt.legend(loc =[1,0.5])
6 plt.show()

lda各个主题的情感得分 lda情感分析_词云_02

 ②由于海尔品牌销售最好,以下主要分析海尔品牌热水器

1 import re
2 plt.rcParams['font.sans-serif'] = 'SimHei'
3 label =haier.reset_index()['index'].apply(lambda x:re.sub('[海尔\(Haier\)|海尔\(Haier\) ]','',x))
4 plt.bar(range(len(haier)),haier.values)
5 plt.title('海尔销售前10的型号')
6 plt.xticks(range(len(haier)),label,rotation=290)
7 plt.show()

 

lda各个主题的情感得分 lda情感分析_lda各个主题的情感得分_03

 3.数据预处理

①首先取出评论字段所有数据

1 comment_text = data['评论'].drop_duplicates()  #去重

lda各个主题的情感得分 lda情感分析_lda各个主题的情感得分_04

 ②提出前面标红的无关内容

1 comment_text  =comment_text.dropna()   #去除空值,否则做.apply(lambda x:x.replace('\\n',''))执行报错
 2 comment_text = comment_text.apply(lambda x:x.replace('\\n',''))  #去除\n符号
 3 comment_text = comment_text.apply(lambda x:re.sub('&[a-z]+;','',x))  #去除网页……类型字符
 4 
 5 #自定义函数(剔除空调型号)
 6 lt = pd.Series(data["型号"].unique()).dropna() #品牌类型
 7 def drop_brand(x):
 8     for i in lt:
 9         try:
10             x = re.sub(i,'',x)
11         except:
12             pass
13     return x
14 
15 comment_text = comment_text.apply(drop_brand)   #剔除评论中包含的品牌名

lda各个主题的情感得分 lda情感分析_词云_05

 ③取出海尔品牌的所有评论

1 comment_haier = comment_text[data['品牌']=='海尔']

④jieba分词并剔除停用词和空行

1 #结巴分词
2 import jieba
3 haier_cut = comment_haier.apply(jieba.lcut)
4 stop_word = pd.read_csv('stopword.txt',encoding='gbk',sep='haha',header=None)
5 stop_word = [',','。',' ']+list(stop_word[0])
6 haier_stop = haier_cut.apply(lambda x:[i for i in x if i not in stop_word])  #剔除停用词
7 haier_stop = haier_stop[haier_stop.apply(lambda x:len(x)!=0)] #去除空行

⑤统计词频

1 #统计词频
2 tem_lt = []
3 [tem_lt.append(j) for i in haier_stop for j in i]
4 
5 haier_count = pd.Series(tem_lt).value_counts()

⑥绘制词云图

1 #绘制词云图
2 import matplotlib.pyplot as plt
3 from wordcloud import WordCloud
4 mask = plt.imread('duihuakuan.jpg')
5 wc = WordCloud(font_path='C:/Windows/Fonts/simhei.ttf',mask=mask,background_color='white')
6 wc.fit_words(haier_count)
7 plt.imshow(wc)

lda各个主题的情感得分 lda情感分析_词云_06

 4.情感倾向分析

①导入情感词典

1 score = pd.read_csv('BosonNLP_sentiment_score.txt',sep =' ',header=None)  #导入情感词评分
 2 score.columns = ['word','score']
 3 
 4 not_word = pd.read_csv('not.csv')  #导入否定词
 5 not_word.columns=['notword']
 6 not_word['notscore']=-1
 7 
 8 degree = pd.read_csv('degree.csv')   #导入副词
 9 degree.columns = ['degreeword','descore']
10 degree['descore']/=-100

②定义情感评分函数及调用

1 def get_score(x=None):   #x=None是可以直接被appl调用
 2     tem_d = pd.DataFrame(x,columns=['word1'])
 3     td_s = pd.merge(tem_d,score,how='left',left_on='word1',right_on='word')
 4     tds_d = pd.merge(td_s,degree,how='left',left_on='word1',right_on='degreeword')
 5     index = tds_d[tds_d['descore'].notna()].index
 6     length = len(tem_d)
 7 
 8     for i in index:
 9         if i<length-1:
10             tds_d['score'][i+1]*=tds_d['descore'][i]
11 
12     tdsd_n = pd.merge(tds_d,not_word,how='left',left_on='word1',right_on='notword')
13     index1 = tdsd_n[tdsd_n['notscore'].notna()].index
14 
15     for i in index1:
16         if i<length-1:
17             tdsd_n['score'][i+1]=tdsd_n['score'][i+1]*tdsd_n['notscore'][i]
18     return tdsd_n['score'].sum()
19 
20 y =haier_stop.apply(get_score)

③划分情感

1 # 划分正面评论与负面评论
2 ind = y > 0
3 message_ = data_after_stop.apply(lambda x: ' '.join(x))
4 message_[ind].to_csv('hai_pcomment.txt',index=False)
5 message_[-ind].to_csv('hai_ncomment.txt',index=False)

5.LDA分析

①导入数据

1 pos_com = pd.read_csv('hai_pcomment.txt',header=None)
2 neg_com = pd.read_csv('hai_ncomment.txt',header=None)
1 pos_com.columns = ['comment']
2 pos_com['comment'] = pos_com['comment'].str.split(' ')
3 pos_com

lda各个主题的情感得分 lda情感分析_lda各个主题的情感得分_07

 ②数据准备及转为字典和词袋

1 from gensim.corpora import Dictionary
2 
3 pos_com = list(pos_com['comment'])  #转化为二维数组
4 
5 dic = Dictionary(pos_com)  #构成词典
6 
7 corpus = [dic.doc2bow(i) for i in pos_com]  #词袋形象地解释便是:将文本中的词放入一个袋子里,在袋子中,词拥有两个属性编号和数目(id,num)。
#一个词袋对应一篇文档。由元组(id,num)构成的 [(0, 1), (1, 2), (2, 1)] 则称作稀疏向量。一般语料库都是用这种方式来表示(gensim中)。

③LDA训练及最佳主题选择

LDA训练

1 def choose_topic(corpus,dic):
 2         '''
 3         @description: 生成模型
 4         @param 
 5         @return: 生成主题数分别为1-15的LDA主题模型,并保存起来。
 6         '''
 7         for i in range(1,16):
 8             print('目前的topic个数:{}'.format(i))
 9             temp = 'lda_{}'.format(i)
10             tmp = LdaModel(corpus, num_topics=i, id2word=dic, passes=20)
11             file_path = './{}.model'.format(temp)
12             tmp.save(file_path)
13             print('------------------')

 加载模型并通过困惑度评价主题个数

1 def plot_perplexity(corpus):
 2     x_list = []
 3     y_list = []
 4     for i in range(1,16):
 5         temp_model = 'lda_{}.model'.format(i)
 6         try:
 7             lda = models.ldamodel.LdaModel.load(temp_model)
 8             perplexity = lda.log_perplexity(corpus)  #计算困惑度,困惑度越低越好
 9             x_list.append(i)
10             y_list.append(perplexity)
11         except Exception as e:
12             print(e)
13     plt.rcParams['']
14     plt.plot(x_list, y_list)
15     plt.xlabel('num topics')
16     plt.ylabel('perplexity score')
17     plt.legend(('perplexity_values'), loc='best')
18     plt.show()
19 
20 plot_perplexity(corpus)

lda各个主题的情感得分 lda情感分析_lda各个主题的情感得分_08

 由图知,主题个数在9的时候下降较快。所以主题数为9可能合适。下面在看看一致性

1 from gensim.models import CoherenceModel
 2 def visible_model(topic_num, corpus):
 3         '''
 4         @description: 可视化模型
 5         @param :topic_num:主题的数量
 6         @return: 可视化lda模型
 7         '''
 8         x_list = []
 9         y_list = []
10         for i in range(1,16):
11             temp_model = 'lda_{}.model'.format(i)
12             try:
13                 lda = models.ldamodel.LdaModel.load(temp_model)
14                 cv_tmp = CoherenceModel(model=lda, corpus=corpus, dictionary=dic,coherence='u_mass')
15                 #计算一致性
16                 x_list.append(i)
17                 y_list.append(cv_tmp.get_coherence())  
18             except:
19                 print('没有这个模型:{}'.format(temp_model))
20         plt.rcParams['axes.unicode_minus'] = False
21         plt.plot(x_list, y_list)
22         plt.xlabel('num topics')
23         plt.ylabel('coherence score')
24         plt.legend(('coherence_values'), loc='best')
25         plt.show()
26   visible_model(16, corpus)

lda各个主题的情感得分 lda情感分析_词云_09

 一致性越高越好,由图只,在主题数为1的时候合适,与上面困惑度相矛盾,因此根据分析需要进一步展开分析

④对模型可视化主题,进一步分析

1 import pyLDAvis.gensim  
2 from gensim import models
3 model_name =  'lda_2.model'   #两个主题时
4 pos_model = models.ldamodel.LdaModel.load(model_name)
5 vis_data = pyLDAvis.gensim.prepare(pos_model, corpus, dic)
6 pyLDAvis.show(vis_data, open_browser=False)
  • 两个主题时

lda各个主题的情感得分 lda情感分析_lda各个主题的情感得分_10

 

lda各个主题的情感得分 lda情感分析_词云_11

由第一幅图可知:安装、师傅、送货、海尔、京东、服务、热水器可以看出海尔热水器在京东上送货、安装、师傅态度各方面较好

由第一幅图可知:不错、海尔、加热、买东西、质量、品牌、热水器、挺、价格、便宜、外观、值得  可以看出客户对海尔热水器的价格、外观、品牌上有好的口碑

  •  三个主题时

lda各个主题的情感得分 lda情感分析_词云_12

 

lda各个主题的情感得分 lda情感分析_词云_13

 

lda各个主题的情感得分 lda情感分析_导入数据_14

 图一可知:安装、海尔、元、师傅、说、买、热水器、棒、京东、安装费、配件、花、材料费、收费、收、客服、装、售后、贵、材料、装修、费用 比前面两个主题时增加了安装费、材料费贵等不好的评价。所以综合上,三个主题比较合理,好的服务可能会带来额外的费用,毕竟人力成本高。

LDA参照知乎:https://www.zhihu.com/topic/19565464/hot