一、本案例采集京东网站热水器不同品牌的评论数据进行分析
1.导入数据
1 import pandas as pd
2 data = pd.read_csv('comment.csv')
3 data.head()
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()
②由于海尔品牌销售最好,以下主要分析海尔品牌热水器
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()
3.数据预处理
①首先取出评论字段所有数据
1 comment_text = data['评论'].drop_duplicates() #去重
②提出前面标红的无关内容
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) #剔除评论中包含的品牌名
③取出海尔品牌的所有评论
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)
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
②数据准备及转为字典和词袋
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)
由图知,主题个数在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)
一致性越高越好,由图只,在主题数为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)
- 两个主题时
由第一幅图可知:安装、师傅、送货、海尔、京东、服务、热水器可以看出海尔热水器在京东上送货、安装、师傅态度各方面较好
由第一幅图可知:不错、海尔、加热、买东西、质量、品牌、热水器、挺、价格、便宜、外观、值得 可以看出客户对海尔热水器的价格、外观、品牌上有好的口碑
- 三个主题时
图一可知:安装、海尔、元、师傅、说、买、热水器、棒、京东、安装费、配件、花、材料费、收费、收、客服、装、售后、贵、材料、装修、费用 比前面两个主题时增加了安装费、材料费贵等不好的评价。所以综合上,三个主题比较合理,好的服务可能会带来额外的费用,毕竟人力成本高。