一、本案例采集京东网站热水器不同品牌的评论数据进行分析
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)
- 两个主题时
由第一幅图可知:安装、师傅、送货、海尔、京东、服务、热水器可以看出海尔热水器在京东上送货、安装、师傅态度各方面较好
由第一幅图可知:不错、海尔、加热、买东西、质量、品牌、热水器、挺、价格、便宜、外观、值得 可以看出客户对海尔热水器的价格、外观、品牌上有好的口碑
- 三个主题时
图一可知:安装、海尔、元、师傅、说、买、热水器、棒、京东、安装费、配件、花、材料费、收费、收、客服、装、售后、贵、材料、装修、费用 比前面两个主题时增加了安装费、材料费贵等不好的评价。所以综合上,三个主题比较合理,好的服务可能会带来额外的费用,毕竟人力成本高。