羊城地区heyTea部分门店顾客评价数据可视化挖掘分析

羊城地区HeyTea门店顾客评价数据可视化挖掘分析

开题背景

众所周知,HEYTEA,曾名“皇茶”,是一家由深圳美西西餐饮管理有限公司运营的中国连锁茶饮品牌。2012年,喜茶HEYTEA起源于江边里的一条小巷,为了与层出不穷的山寨品牌区分开来,故全面升级为注册品牌喜茶HEYTEA。由聂云宸于2012年创立,总部设在深圳市南山区航天科技广场,旗下拥有茶饮品牌“喜茶”和烘焙品牌“喜茶热麦”。

该公司依赖社交媒体上的口碑营销以减少广告支出。年轻消费者是其主要客户。大多数店面都在一二线城市的繁华购物中心。其知名产品为芝士奶盖。喜茶为芝士现泡茶的原创者。自创立以来,喜茶专注于呈现来自世界各地的优质茶香, 让这茶饮这一古老文化焕发出新的生命力。

在全国各大城市中,如此广为人知的一家奶茶店铺,我们自然会对其在广大消费者眼中的评价感到兴趣,这些评价对于慕名而来的消费者,也有着极高的参考价值。毕竟,一家企业的好和坏,并不能由单一的门店的产品质量来讨论,故而,这里在羊城地域,随机抽样择取了其所有门店中的部分顾客评价,并对其展开分析,希望得出的结论,可以对未来的消费者提供一份有价值的参考。

环境配置

 1 !pip install pyLDAvis 

 1 !pip install wordcloud
 2 
 3 # 读取/预处理数据库
 4 
 5 import pandas as pd
 6 
 7 import numpy as np
 8 
 9 import time
10 
11 # 可视化工具
12 
13 import matplotlib.pyplot as plt
14 
15 import seaborn as sns
16 
17 from wordcloud import WordCloud, ImageColorGenerator # 词云可视化
18 
19 # 分词工具
20 
21 import jieba
22 
23 import jieba.posseg as psg
24 
25 import re
26 
27 # 文本特征提取工具
28 
29 from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer, HashingVectorizer
30 
31 from sklearn.decomposition import LatentDirichletAllocation
32 
33 # LDA主题模型可视化
34 
35 import pyLDAvis
36 
37 import pyLDAvis.sklearn
38 
39 import paddlenlp

 

数据源文件如下:

数据包括评价文本及评价时间两个字段。

2 数据读取与预处理

2.1数据读取

1 data = pd.read_excel("data/data155443/xicha_meituan_data.xlsx")
2 
3 # 词典文件路径 可以分特定词  
4 
5 dic_file = r"file/dict.txt"
6 
7 stop_file = r"file/cn_stopwords.txt"

 

2.2数据预处理

 1 data.info() 

1 # 去除无内容的评价

2 data = data.dropna()

4 data.head(5) 

2.2.1针对文本数据内容的预处理

 1 # 分词函数
 2 
 3 def chinese_word_cut(mytext):
 4 
 5     jieba.load_userdict(dic_file)
 6 
 7     jieba.initialize()
 8 
 9     try:
10 
11         stopword_list = open(stop_file,encoding ='utf-8')
12 
13     except:
14 
15         stopword_list = []
16 
17         print("error in stop_file")
18 
19     stop_list = []
20 
21     flag_list = ['n','nz','vn','a','an','ad','i']
22 
23     for line in stopword_list:
24 
25         line = re.sub(u'\n|\\r', '', line)
26 
27         stop_list.append(line)
28 
29    
30 
31     word_list = []
32 
33     #jieba分词
34 
35     seg_list = psg.cut(mytext,use_paddle=True)
36 
37     for seg_word in seg_list:
38 
39         word = seg_word.word  
40 
41         find = 0
42 
43         if seg_word.flag == 'x':
44 
45             find=1
46 
47         for stop_word in stop_list:
48 
49             if stop_word == word :    
50 
51                     find = 1
52 
53                     break
54 
55         if find == 0 : # and seg_word.flag in flag_list
56 
57             word_list.append(word)      
58 
59     return (" ").join(word_list)
60 
61 # 计算分词后文本的词频
62 
63 def count_frequencies(word_list):
64 
65     freq = dict()
66 
67     for sentence in word_list:
68 
69         for w in sentence.split(' '):
70 
71             if w not in freq.keys():
72 
73                 freq[w] = 1
74 
75             else:
76 
77                 freq[w] += 1
78 
79     return freq
80 
81 data["cutted_comment"] = data.comment.apply(chinese_word_cut)

1 freq = count_frequencies(data["cutted_comment"])
2 
3 freq = sorted(freq.items(),key=lambda x:x[1],reverse=True)
4 
5 freq[:15]

 1 len(freq) 

1 # 去除过短的评论
2 
3 t_data = data[data['cutted_comment'].str.len()>5]
4 
5 t_data = t_data.reset_index().drop(columns='index')

2.2.2 评价时间字段数据预处理

1 t=time.localtime(1650933910610/1000)

2 time.strftime("%Y-%m-%d %H:%M:%S",t).split(' ') 

 1 _date=[]
 2 
 3 _date_month=[]
 4 
 5 _date_day=[]
 6 
 7 _time=[]
 8 
 9 _time_hour=[]
10 
11 for i in t_data['comment_time']:
12 
13     arr=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(i/1000)).split(' ')
14 
15     _date.append(arr[0])
16 
17     _date_month.append(arr[0].split('-')[1])
18 
19     _date_day.append(arr[0].split('-')[2])
20 
21     _time.append(arr[1])
22 
23     _time_hour.append(arr[1].split(':')[0])
24 
25 t_data.insert(2,value=_date_month,column='_date_month')
26 
27 t_data.insert(3,value=_date_day,column='_date_day')
28 
29 t_data.insert(4,value=_time_hour,column='_time_hour')
30 
31 t_data.head(5)

 

2.2.3 基于paddleNLP.TaskFlow评价情感分析

 1 sa = paddlenlp.Taskflow('sentiment_analysis') 

1 sentiment_analysis_data = sa(t_data['comment'].to_list())
2 
3 sentiment_analysis_data_df = pd.DataFrame(sentiment_analysis_data)
4 
5 sentiment_analysis_data_df.head(5)

1 t_data['label'] = sentiment_analysis_data_df['label']
2 
3 t_data['score'] = sentiment_analysis_data_df['score']
4 
5 # 保存
6 
7 t_data.to_excel('file/data.xlsx',index=False,encoding='utf8')
8 
9 t_data.head(5)

 1 t_data.info() 

抽样区域内门店评价数据可视化实现

2.1店内图文及词云可视化显示

 1 def plt_imshow(x, ax=None, show=True):
 2 
 3     if ax is None:
 4 
 5         fig, ax = plt.subplots()
 6 
 7     ax.imshow(x)
 8 
 9     ax.axis("off")
10 
11     if show: plt.show()
12 
13     return ax
14 
15 wcd = WordCloud(background_color='white',
16 
17     max_words=200,
18 
19     font_path = 'file/font/SIMHEI.TTF',
20 
21     mode="RGBA",
22 
23     max_font_size=180,
24 
25     width = 1300,
26 
27     height = 800,
28 
29     scale=10
30 
31 )
32 
33 wcd.generate_from_frequencies(dict(freq))
34 
35 ax=plt_imshow(wcd)
36 
37 ax.figure.savefig('file/pic/wordcloud0.png',dpi=1000)

我们可以得知:利用WordCloud库和处理后的评价数据进行词云图制作,得到下图,可以看到“好喝”、“不错”、“味道”等词在评价中经常出现,可以体现出顾客在喜茶门店具有较好的服务感知满意度;

“芝士”、“葡萄”、“芒果”、“草莓”等词也的出现频率也是不低,对此,我们可知:服务产品中水果类饮品较多样顾客对该类商品有较深的印象;

“环境”、“口味”、“味道”、“清爽”等词,则形象生动地表明了顾客对门店服务支持设施和显性服务有一定的关注。

 1 plt.figure(figsize=(19,6))
 2 
 3 ax=sns.countplot(
 4 
 5     t_data['_date_month'],
 6 
 7     saturation =1,
 8 
 9     palette=sns.color_palette(palette='OrRd_d',desat=0.9,n_colors=12),
10 
11     )
12 
13 plt.title('Number of monthly reviews of HEYTEA',fontsize=30)
14 
15 plt.xlabel('Month',fontsize=30)
16 
17 plt.ylabel("Count",fontsize=30)
18 
19 plt.savefig('file/pic/每月评价数.png',dpi=1000)

 

根据这一则数据我们可知:喜茶评价数据大多在上半年3到6月份,下半年评价数据较少。因此,我们可以推断出:春季是奶茶饮品的旺季,而从盛夏至严冬的时段,这一类产品显然不如春季之时受消费者欢迎。

 1 plt.figure(figsize=(19,6))
 2 
 3 ax=sns.countplot(
 4 
 5     t_data['_date_day'],
 6 
 7     saturation =1,
 8 
 9     palette=sns.color_palette(palette='PuBu',desat=1,n_colors=10)
10 
11     )
12 
13 plt.title('Number of Daily reviews of HEYTEA',fontsize=30)
14 
15 plt.xlabel('Day',fontsize=30)
16 
17 plt.ylabel("Count",fontsize=30)
18 
19 plt.savefig('file/pic/一个月中每日评价数.png',dpi=1000)

我们进一步对喜茶12个月中每天评价数据进行统计,则可以得到下图。如图所示,在每月12号、18号和29号评价数据较多;在1号、11号和19号较少,对此,相应调整店内原材料以及人员的配比,也会是提高营业效益的一种方式。

 1 plt.figure(figsize=(19,6))
 2 
 3 ax=sns.countplot(
 4 
 5     t_data['_time_hour'],
 6 
 7     saturation=1,
 8 
 9     palette=sns.color_palette(palette='OrRd_d',desat=1)
10 
11     )
12 
13 plt.title('Number of Hours reviews of HEYTEA',fontsize=30)
14 
15 plt.xlabel('Every hour of the day',fontsize=30)
16 
17 plt.ylabel("Count",fontsize=30)
18 
19 plt.savefig('file/pic/一个天中24小时评价数.png',dpi=1000)

 

 1 # 消极评论每天各个时段散点图
 2 
 3 plt.figure(figsize=(12,9))
 4 
 5 sns.swarmplot(y=t_data['_time_hour'],x=t_data['label'])
 6 
 7 plt.title('HEYTEA Distribution of good and bad reviews in various time periods of the day',fontsize=15)
 8 
 9 plt.xlabel('Label',fontsize=20)
10 
11 plt.ylabel('per hours of day',fontsize=20)

 

1 plt.savefig('file/pic/一天内各个时段好差评数据分布.png',dpi=1000)
2 
3 # 消极评论每个月散点图
4 
5 plt.figure(figsize=(12,9))
6 
7 sns.swarmplot(y=t_data['_date_month'],x=t_data['label'])

 

1 # 消极评论每个月内散点图
2 
3 plt.figure(figsize=(12,9))
4 
5 sns.swarmplot(y=t_data['_date_day'],x=t_data['label'])

1 sns.countplot(t_data['label'])
2 
3 plt.title(r"HEYTEA Negative vs. positive reviews",fontsize=15)
4 
5 plt.ylabel('Count',fontsize=15)
6 
7 plt.xlabel('HEYTEA Comment Label',fontsize=15)
8 
9 plt.savefig('file/pic/喜茶评价积极与消极比较.png',dpi=1000)

 

ax=sns.barplot(

 1     y=[len(t_data['comment']),len(t_data['comment'].unique())],
 2 
 3     x=['all_comment','unique_comment'],
 4 
 5 )
 6 
 7 plt.title('HEYTEA comments''s uniqueness',fontsize=15)
 8 
 9 plt.ylabel('Count',fontsize=15)
10 
11 plt.savefig('file/pic/喜茶评价唯一性.png',dpi=1000)

 

 1 ax=sns.barplot(
 2 
 3     y=[len(t_data['comment']),len(t_data['comment'].unique())],
 4 
 5     x=['all_comment','unique_comment'],
 6 
 7 )
 8 
 9 plt.title('HEYTEA comments''s uniqueness',fontsize=15)
10 
11 plt.ylabel('Count',fontsize=15)
12 
13 plt.savefig('file/pic/喜茶评价唯一性.png',dpi=1000)

1 print('消极评论占比',sum(t_data['label']=='negative')/len(t_data))
2 
3 # 消极评论词云图
4 
5 freq_negative = count_frequencies(t_data[t_data['label']=='negative']['cutted_comment'])
6 
7 freq_negative = sorted(freq_negative.items(),key=lambda x:x[1],reverse=True)
8 
9 freq_negative[:15]

 1 wcd = WordCloud(background_color='white',
 2 
 3     max_words=150,
 4 
 5     font_path = 'file/font/SIMHEI.TTF',
 6 
 7     mode="RGBA",
 8 
 9     max_font_size=160,
10 
11     width = 1000,
12 
13     height = 500,
14 
15     scale=10)
16 
17 wcd.generate_from_frequencies(dict(freq_negative[4:]))
18 
19 ax=plt_imshow(wcd)
20 
21 ax.figure.savefig('file/pic/wordcloud_negative.png',dpi=1000)

挖掘——LDA模型主题

3.1提取文本特征

 1 n_features = 1000 #提取1000个特征词语
 2 
 3 cv_vectorizer = CountVectorizer(max_df = 0.90,
 4 
 5                                 max_features=n_features,
 6 
 7                                 min_df = 5)
 8 
 9 cv = cv_vectorizer.fit_transform(t_data.cutted_comment)
10 
11 # tfidf提取文本特征
12 
13 tfidf_vectorizer = TfidfVectorizer(max_df = 0.95,
14 
15                                 max_features=500)
16 
17 tfidf = tfidf_vectorizer.fit_transform(t_data.cutted_comment)
18 
19 hash_vectorizer = HashingVectorizer()
20 
21 hashing = hash_vectorizer.fit_transform(data.cutted_comment)

3.2 LDA困惑度与主题数选择

 1 plexs = []
 2 
 3 n_max_topics = 50
 4 
 5 for i in range(1,n_max_topics):
 6 
 7     print(i,end='..')
 8 
 9     lda = LatentDirichletAllocation(n_components=i,
10 
11                                     doc_topic_prior=1/i,
12 
13                                     topic_word_prior=1/i,
14 
15                                     learning_method='batch')
16 
17     lda.fit(cv)
18 
19     plexs.append(lda.perplexity(cv))

 1 n_t=50#区间最右侧的值。注意:不能大于n_max_topics
 2 
 3 x=list(range(1,n_t))
 4 
 5 plt.plot(x,plexs[:n_t], linestyle='-.')
 6 
 7 plt.xlabel("number of topics")
 8 
 9 plt.ylabel("perplexity")
10 
11 plt.legend(('perplexity_value'))
12 
13 plt.title("LDA Model Perplexity Value")
14 
15 plt.savefig('file/pic/PerplexityValue.png',dpi=1000)
16 
17 plt.show()

3.3 LDA模型训练与模型结果

 1 n_topics = 4
 2 
 3 lda = LatentDirichletAllocation(n_components=n_topics,max_iter=100,
 4 
 5                                     doc_topic_prior=1/n_topics,
 6 
 7                                     topic_word_prior=0.01,
 8 
 9                                     learning_method='batch')
10 
11 lda.fit(cv)

 

def print_top_words(model, feature_names, n_top_words):

 1     tword = []
 2 
 3     for topic_idx, topic in enumerate(model.components_):
 4 
 5         print("Topic #%d:" % topic_idx)
 6 
 7         topic_w = " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
 8 
 9         tword.append(topic_w)
10 
11         print(topic_w)
12 
13     return tword
14 
15 # 输出每个主题及其主题词
16 
17 n_top_words = 15
18 
19 cv_vectorizer_name = cv_vectorizer.get_feature_names()
20 
21 topic_word = print_top_words(lda, cv_vectorizer_name, n_top_words)

 

 1 # LDA模型还可以用于文本分类
 2 
 3 topics=lda.transform(cv)
 4 
 5 topic = []
 6 
 7 for t in topics:
 8 
 9     topic.append("Topic #"+str(list(t).index(np.max(t))))
10 
11 t_data['概率最大的主题序号']=topic
12 
13 t_data['每个主题对应概率']=list(topics)
14 
15 t_data.to_excel("data_topic_test0.xlsx",index=False)

3.4 LDA模型结果可视化

 1 pyLDAvis.enable_notebook()
 2 
 3 pic = pyLDAvis.sklearn.prepare(lda, cv,cv_vectorizer)
 4 
 5 pyLDAvis.display(pic)
 6 
 7 pyLDAvis.save_html(pic, 'file/pic/lda_pass'+str(n_topics)+'.html')
 8 
 9 pyLDAvis.display(pic)
10 
11 #去工作路径下找保存好的html文件

在文件下找到生成的html文件,用浏览器打开可以看到具体结果

运行结果如图所示:

3.5测试调查结果

结合LDA主题挖掘与情感分析统计的结果,可以得出hey Tea在羊城(广州)地区的门店主要的运营问题是排队时间过长的结论,同时可以推断该问题在中午的13点与下午的17点经常频发。

完整代码附上:

  1 !pip install pyLDAvis
  2 
  3 !pip install wordcloud
  4 
  5 # 读取/预处理数据库
  6 
  7 import pandas as pd
  8 
  9 import numpy as np
 10 
 11 import time
 12 
 13 # 可视化工具
 14 
 15 import matplotlib.pyplot as plt
 16 
 17 import seaborn as sns
 18 
 19 from wordcloud import WordCloud, ImageColorGenerator # 词云可视化
 20 
 21 # 分词工具
 22 
 23 import jieba
 24 
 25 import jieba.posseg as psg
 26 
 27 import re
 28 
 29 # 文本特征提取工具
 30 
 31 from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer, HashingVectorizer
 32 
 33 from sklearn.decomposition import LatentDirichletAllocation
 34 
 35 # LDA主题模型可视化
 36 
 37 import pyLDAvis
 38 
 39 import pyLDAvis.sklearn
 40 
 41 import paddlenlp
 42 
 43 data = pd.read_excel("data/data155443/xicha_meituan_data.xlsx")
 44 
 45 # 词典文件路径 可以分特定词  如
 46 
 47 dic_file = r"file/dict.txt"
 48 
 49 stop_file = r"file/cn_stopwords.txt"
 50 
 51 data.info()
 52 
 53 # 去除无内容的评价
 54 
 55 data = data.dropna()
 56 
 57 data.head(5)
 58 
 59 # 分词函数
 60 
 61 def chinese_word_cut(mytext):
 62 
 63     jieba.load_userdict(dic_file)
 64 
 65     jieba.initialize()
 66 
 67     try:
 68 
 69         stopword_list = open(stop_file,encoding ='utf-8')
 70 
 71     except:
 72 
 73         stopword_list = []
 74 
 75         print("error in stop_file")
 76 
 77     stop_list = []
 78 
 79     flag_list = ['n','nz','vn','a','an','ad','i']
 80 
 81     for line in stopword_list:
 82 
 83         line = re.sub(u'\n|\\r', '', line)
 84 
 85         stop_list.append(line)
 86 
 87    
 88 
 89     word_list = []
 90 
 91     #jieba分词
 92 
 93     seg_list = psg.cut(mytext,use_paddle=True)
 94 
 95     for seg_word in seg_list:
 96 
 97         word = seg_word.word  
 98 
 99         find = 0
100 
101         if seg_word.flag == 'x':
102 
103             find=1
104 
105         for stop_word in stop_list:
106 
107             if stop_word == word :    
108 
109                     find = 1
110 
111                     break
112 
113         if find == 0 : # and seg_word.flag in flag_list
114 
115             word_list.append(word)      
116 
117     return (" ").join(word_list)
118 
119 # 计算分词后文本的词频
120 
121 def count_frequencies(word_list):
122 
123     freq = dict()
124 
125     for sentence in word_list:
126 
127         for w in sentence.split(' '):
128 
129             if w not in freq.keys():
130 
131                 freq[w] = 1
132 
133             else:
134 
135                 freq[w] += 1
136 
137     return freq
138 
139 data["cutted_comment"] = data.comment.apply(chinese_word_cut)
140 
141 freq = count_frequencies(data["cutted_comment"])
142 
143 freq = sorted(freq.items(),key=lambda x:x[1],reverse=True)
144 
145 freq[:15]
146 
147 len(freq)
148 
149 # 去除过短的评论
150 
151 t_data = data[data['cutted_comment'].str.len()>5]
152 
153 t_data = t_data.reset_index().drop(columns='index')
154 
155 # 例子
156 
157 t=time.localtime(1650933910610/1000)
158 
159 time.strftime("%Y-%m-%d %H:%M:%S",t).split(' ')
160 
161 _date=[]
162 
163 _date_month=[]
164 
165 _date_day=[]
166 
167 _time=[]
168 
169 _time_hour=[]
170 
171 for i in t_data['comment_time']:
172 
173     arr=time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(i/1000)).split(' ')
174 
175     _date.append(arr[0])
176 
177     _date_month.append(arr[0].split('-')[1])
178 
179     _date_day.append(arr[0].split('-')[2])
180 
181     _time.append(arr[1])
182 
183     _time_hour.append(arr[1].split(':')[0])
184 
185 t_data.insert(2,value=_date_month,column='_date_month')
186 
187 t_data.insert(3,value=_date_day,column='_date_day')
188 
189 t_data.insert(4,value=_time_hour,column='_time_hour')
190 
191 t_data.head(5)
192 
193 sa = paddlenlp.Taskflow('sentiment_analysis')
194 
195 sentiment_analysis_data = sa(t_data['comment'].to_list())
196 
197 sentiment_analysis_data_df = pd.DataFrame(sentiment_analysis_data)
198 
199 sentiment_analysis_data_df.head(5)
200 
201 t_data['label'] = sentiment_analysis_data_df['label']
202 
203 t_data['score'] = sentiment_analysis_data_df['score']
204 
205 # 保存一下
206 
207 t_data.to_excel('file/data.xlsx',index=False,encoding='utf8')
208 
209 t_data.head(5)
210 
211 t_data.info()
212 
213 def plt_imshow(x, ax=None, show=True):
214 
215     if ax is None:
216 
217         fig, ax = plt.subplots()
218 
219     ax.imshow(x)
220 
221     ax.axis("off")
222 
223     if show: plt.show()
224 
225     return ax
226 
227 wcd = WordCloud(background_color='white',
228 
229     max_words=200,
230 
231     font_path = 'file/font/SIMHEI.TTF',
232 
233     mode="RGBA",
234 
235     max_font_size=180,
236 
237     width = 1300,
238 
239     height = 800,
240 
241     scale=10
242 
243 )
244 
245 wcd.generate_from_frequencies(dict(freq))
246 
247 ax=plt_imshow(wcd)
248 
249 ax.figure.savefig('file/pic/wordcloud0.png',dpi=1000)
250 
251 plt.figure(figsize=(19,6))
252 
253 ax=sns.countplot(
254 
255     t_data['_date_month'],
256 
257     saturation =1,
258 
259     palette=sns.color_palette(palette='OrRd_d',desat=0.9,n_colors=12),
260 
261     )
262 
263 plt.title('Number of monthly reviews of HEYTEA',fontsize=30)
264 
265 plt.xlabel('Month',fontsize=30)
266 
267 plt.ylabel("Count",fontsize=30)
268 
269 plt.savefig('file/pic/每月评价数.png',dpi=1000)
270 
271 plt.figure(figsize=(19,6))
272 
273 ax=sns.countplot(
274 
275     t_data['_date_day'],
276 
277     saturation =1,
278 
279     palette=sns.color_palette(palette='PuBu',desat=1,n_colors=10)
280 
281     )
282 
283 plt.title('Number of Daily reviews of HEYTEA',fontsize=30)
284 
285 plt.xlabel('Day',fontsize=30)
286 
287 plt.ylabel("Count",fontsize=30)
288 
289 plt.savefig('file/pic/一个月中每日评价数.png',dpi=1000)
290 
291 plt.figure(figsize=(19,6))
292 
293 ax=sns.countplot(
294 
295     t_data['_time_hour'],
296 
297     saturation=1,
298 
299     palette=sns.color_palette(palette='OrRd_d',desat=1)
300 
301     )
302 
303 plt.title('Number of Hours reviews of HEYTEA',fontsize=30)
304 
305 plt.xlabel('Every hour of the day',fontsize=30)
306 
307 plt.ylabel("Count",fontsize=30)
308 
309 plt.savefig('file/pic/一个天中24小时评价数.png',dpi=1000)
310 
311 # 消极评论每天各个时段散点图
312 
313 plt.figure(figsize=(12,9))
314 
315 sns.swarmplot(y=t_data['_time_hour'],x=t_data['label'])
316 
317 plt.title('HEYTEA Distribution of good and bad reviews in various time periods of the day',fontsize=15)
318 
319 plt.xlabel('Label',fontsize=20)
320 
321 plt.ylabel('per hours of day',fontsize=20)
322 
323 plt.savefig('file/pic/一天内各个时段好差评数据分布.png',dpi=1000)
324 
325 # 消极评论每个月散点图
326 
327 plt.figure(figsize=(12,9))
328 
329 sns.swarmplot(y=t_data['_date_month'],x=t_data['label'])
330 
331 # 消极评论每个月内散点图
332 
333 plt.figure(figsize=(12,9))
334 
335 sns.swarmplot(y=t_data['_date_day'],x=t_data['label'])
336 
337 sns.countplot(t_data['label'])
338 
339 plt.title(r"HEYTEA Negative vs. positive reviews",fontsize=15)
340 
341 plt.ylabel('Count',fontsize=15)
342 
343 plt.xlabel('HEYTEA Comment Label',fontsize=15)
344 
345 plt.savefig('file/pic/喜茶评价积极与消极比较.png',dpi=1000)
346 
347 ax=sns.barplot(
348 
349     y=[len(t_data['comment']),len(t_data['comment'].unique())],
350 
351     x=['all_comment','unique_comment'],
352 
353 )
354 
355 plt.title('HEYTEA comments''s uniqueness',fontsize=15)
356 
357 plt.ylabel('Count',fontsize=15)
358 
359 plt.savefig('file/pic/喜茶评价唯一性.png',dpi=1000)
360 
361 print('消极评论占比',sum(t_data['label']=='negative')/len(t_data))
362 
363 # 消极评论词云图
364 
365 freq_negative = count_frequencies(t_data[t_data['label']=='negative']['cutted_comment'])
366 
367 freq_negative = sorted(freq_negative.items(),key=lambda x:x[1],reverse=True)
368 
369 freq_negative[:15]
370 
371 wcd = WordCloud(background_color='white',
372 
373     max_words=150,
374 
375     font_path = 'file/font/SIMHEI.TTF',
376 
377     mode="RGBA",
378 
379     max_font_size=160,
380 
381     width = 1000,
382 
383     height = 500,
384 
385     scale=10)
386 
387 wcd.generate_from_frequencies(dict(freq_negative[4:]))
388 
389 ax=plt_imshow(wcd)
390 
391 ax.figure.savefig('file/pic/wordcloud_negative.png',dpi=1000)
392 
393 n_features = 1000 #提取1000个特征词语
394 
395 cv_vectorizer = CountVectorizer(max_df = 0.90,
396 
397                                 max_features=n_features,
398 
399                                 min_df = 5)
400 
401 cv = cv_vectorizer.fit_transform(t_data.cutted_comment)
402 
403 # tfidf提取文本特征
404 
405 tfidf_vectorizer = TfidfVectorizer(max_df = 0.95,
406 
407                                 max_features=500)
408 
409 tfidf = tfidf_vectorizer.fit_transform(t_data.cutted_comment)
410 
411 hash_vectorizer = HashingVectorizer()
412 
413 hashing = hash_vectorizer.fit_transform(data.cutted_comment)
414 
415 plexs = []
416 
417 n_max_topics = 50
418 
419 for i in range(1,n_max_topics):
420 
421     print(i,end='..')
422 
423     lda = LatentDirichletAllocation(n_components=i,
424 
425                                     doc_topic_prior=1/i,
426 
427                                     topic_word_prior=1/i,
428 
429                                     learning_method='batch')
430 
431     lda.fit(cv)
432 
433     plexs.append(lda.perplexity(cv))
434 
435 n_t=50#区间最右侧的值。注意:不能大于n_max_topics
436 
437 x=list(range(1,n_t))
438 
439 plt.plot(x,plexs[:n_t], linestyle='-.')
440 
441 plt.xlabel("number of topics")
442 
443 plt.ylabel("perplexity")
444 
445 plt.legend(('perplexity_value'))
446 
447 plt.title("LDA Model Perplexity Value")
448 
449 plt.savefig('file/pic/PerplexityValue.png',dpi=1000)
450 
451 plt.show()
452 
453 n_topics = 4
454 
455 lda = LatentDirichletAllocation(n_components=n_topics,max_iter=100,
456 
457                                     doc_topic_prior=1/n_topics,
458 
459                                     topic_word_prior=0.01,
460 
461                                     learning_method='batch')
462 
463 lda.fit(cv)
464 
465 def print_top_words(model, feature_names, n_top_words):
466 
467     tword = []
468 
469     for topic_idx, topic in enumerate(model.components_):
470 
471         print("Topic #%d:" % topic_idx)
472 
473         topic_w = " ".join([feature_names[i] for i in topic.argsort()[:-n_top_words - 1:-1]])
474 
475         tword.append(topic_w)
476 
477         print(topic_w)
478 
479     return tword
480 
481 # 输出每个主题及其主题词
482 
483 n_top_words = 15
484 
485 cv_vectorizer_name = cv_vectorizer.get_feature_names()
486 
487 topic_word = print_top_words(lda, cv_vectorizer_name, n_top_words)
488 
489 # LDA模型还可以用于文本分类
490 
491 topics=lda.transform(cv)
492 
493 topic = []
494 
495 for t in topics:
496 
497     topic.append("Topic #"+str(list(t).index(np.max(t))))
498 
499 t_data['概率最大的主题序号']=topic
500 
501 t_data['每个主题对应概率']=list(topics)
502 
503 t_data.to_excel("data_topic_test0.xlsx",index=False)
504 
505 pyLDAvis.enable_notebook()
506 
507 pic = pyLDAvis.sklearn.prepare(lda, cv,cv_vectorizer)
508 
509 pyLDAvis.display(pic)
510 
511 pyLDAvis.save_html(pic, 'file/pic/lda_pass'+str(n_topics)+'.html')
512 
513 pyLDAvis.display(pic)
514 
515 #去工作路径下找保存好的html文件
posted @ 2022-12-22 01:24  六眼飞鱼Rayenos  阅读(228)  评论(0)    收藏  举报