python机器学习——点评评论分析

(一)选题背景:

随着广大用户“即需要、即外卖、即使用”的方便快捷的“外卖生活方式”的形成和普及,如今外卖行业不仅可以满足用户餐饮商品的在线即时购物需求,还可以满足饮食、水果、酒水饮料、家居日用、母婴用品、数码家电、服饰鞋包、美妆护肤、医药等各种品类商品。对于服务行业来说,好评、差评有什么作用呢?最直观的影响,就是后续客户的购买意愿或商家的名誉会受到影响。所以预测好差评对人们进行购物有着重要的意义。于是通过机器学习设计了一套程序用于判断好评、差评。

(二)机器学习设计案例:从网站中下载相关的数据集,对数据集进行整理,python的环境中,给数据集中的文件打上标签,对数据进行预处理,并运用split分割数据,用贝叶斯模型建立训练模型,最后模型评估并验证。

(三)机器学习的实现步骤

数据来源:大众点评3W条评论数据(带标签)_数据集-阿里云天池 (aliyun.com)

 

 

  1. 下载数据集

 

 

 

 

 

2.导入所需要的库

 

1 import numpy as np
2 import pandas as pd
3 from sklearn.model_selection import train_test_split
4 from sklearn.feature_extraction.text import TfidfVectorizer
5 from sklearn.naive_bayes import MultinomialNB
6 from sklearn.model_selection import cross_val_score
7 import jieba

 

 1 """
 2 文本预测
 3 
 4 得出信息:
 5 - 行:32483条数据  缺失值:stars 跟cus_comment
 6 - 列:14列
 7     - 目标:stars 星级评分
 8  - 特征:cus_comment:评价内容 ->> 词汇决定好评/差评
 9 """
10 dz_data = pd.read_csv("./data.csv")
11 dz_data.info()
12 dz_data.head()

 1
"""
1-2:差评 --- >0 2 3 4-5:好评 --- >1 4 5 3:中评 --- >干扰干扰项! ---> np.nan
"""
6 7 rpl_data = {1.0:0, 2.0:0, 3.0:np.nan, 4.0:1, 5.0:1} #对目标值进行替换取代 8 9 dz_data["label"] = dz_data["stars"].map(rpl_data) 10 11 dz_data.info() 12 13 dz_data.head()

 

 

1 # 注意:删除缺失值
2 
3 dz_data_2 = dz_data.dropna()
4 
5 dz_data_2.info()
6 
7 dz_data.head()

 

 


 

3.数据分割

 

 1 from sklearn.model_selection import train_test_split
 2# 特征 目标
 3 
 4 x_train, x_test, y_train, y_test = train_test_split(dz_data_2["cus_comment"], dz_data_2["label"], random_state=3, test_size=0.25)
 5 print(len(y_train))
 6 print(len(y_test))
 7 print(len(x_train))
 8 print(len(x_test))

 1 x_train 

 

1 #去除停用词   把没作用的词去除
2 
3 f = open("stopwords.txt", encoding="utf-8")    #使用停用词表
4 
5 stop_words = f.readlines()
6 
7 stop_words = [word.strip() for word in stop_words]
8 
9 stop_words

 

1 #使用 tf-idf 进行文本处理用于信息检索与数据挖掘
2 
3 from sklearn.feature_extraction.text import TfidfVectorizer
4 
5 # ngram_range=(1,2) ->> 表示选取1-2个词作为组合方式
6 
7 tf_idf = TfidfVectorizer(stop_words=stop_words, max_features=4000, ngram_range=(1,2))
8 
9 tf_idf.fit(x_train)

 

4.建立模型

1  #贝叶斯模型
2 
3 from sklearn.naive_bayes import MultinomialNB      
4 
5 mt_cls = MultinomialNB()    #实义化
6 
7 mt_cls.fit(tf_idf.transform(x_train), y_train)    #训练

 

模型评估

1 pred_proba = mt_cls.predict_proba(tf_idf.transform(x_test))[:,1]
2 pred_proba
3 mt_cls.score(tf_idf.transform(x_test), y_test)

 

 

看多次评分结果 ->> 交叉验证

 

 5.测试模型

  1. 首先导入 jieba 库:import jieba
  2. 对需要分词的文本(test_s)进行分词处理,将分词结果用空格隔开并存储到列表中:s_fenci = " ".join(list(jieba.cut(test_s)))
  3. 将分词结果转换为 pandas.Series 格式:s_fenci = pd.Series(s_fenci)
  4. 将处理后的文本输入到模型中进行预测,并获取其概率值:proba = model.predict_proba(tf_idf.transform(s_fenci))[:,1][0]
  5. jieba 的分词操作主要体现在第 2 行代码中的 list(jieba.cut(test_s)) 这个部分。其中,jieba.cut(test_s) 会将字符串 test_s 进行分词处理,并返回一个可迭代的生成器对象。list() 函数则将其转换为列表格式,方便进行 join 操作
 1 test1 = "感觉这边环境不是很好,但是,挺好吃的!好评!!!"
 2 
 3 test2 = "这是我在长沙吃的最好的一顿,第一个上来的毛豆,配上灵魂酱汁YYDS。第二个豆花,也太好吃了把!花甲的汤汁也是无敌了"
 4 
 5 test3 = "朋友说很好吃,抱有非常大的期望,但结果很失望!!一点都不好吃"
 6 
 7 test4 = "差评!!。"
 8 
 9 import jieba                          #用jieba进行分词
10 
11 def pred(model, test_s):
12 
13     s_fenci = " ".join(list(jieba.cut(test_s)))
14 
15     s_fenci = pd.Series(s_fenci)
16 
17 #     print(s_fenci)
18 
19     proba = model.predict_proba(tf_idf.transform(s_fenci))[:,1][0]
20 
21 #     print(proba)
22 
23 return proba
24 
25 print(f"test1预测为好评的概率是:{pred(mt_cls, test1)}")
26 
27 print(f"           差评的概率是:{1-pred(mt_cls, test1)}")
28 
29 print(f"test2预测为好评的概率是:{pred(mt_cls, test2)}")
30 
31 print(f"           差评的概率是:{1-pred(mt_cls, test2)}")
32 
33 print(f"test3预测为好评的概率是:{pred(mt_cls, test3)}")
34 
35 print(f"           差评的概率是:{1-pred(mt_cls, test3)}")
36 
37 print(f"test4预测为好评的概率是:{pred(mt_cls, test4)}")
38 
39 print(f"           差评的概率是:{1-pred(mt_cls, test4)}")

 

 

差评测试中由于数据样本少,导致预测不准确

 1 test5 = "感觉很一般吧,东西没听说的那么好吃,有点些东西是冷的,不太新鲜"
 2 
 3 test6 = "一直网上看人说不错,但是我吃了没说的那么好吃,可能有点虚化了"
 4 
 5 test7 = "垃圾垃圾垃圾别去"
 6 
 7 test8 = "东西不新鲜是冷的"
 8 
 9 print(f"test5预测为好评的概率是:{pred(mt_cls, test5)}")     #结果极其不准确
10 
11 print(f"           差评的概率是:{1-pred(mt_cls, test5)}")
12 
13 print(f"test6预测为好评的概率是:{pred(mt_cls, test6)}")
14 
15 print(f"           差评的概率是:{1-pred(mt_cls, test6)}")
16 
17 print(f"test7预测为好评的概率是:{pred(mt_cls, test7)}")
18 
19 print(f"           差评的概率是:{1-pred(mt_cls, test7)}")
20 
21 print(f"test8预测为好评的概率是:{pred(mt_cls, test8)}")
22 
23 print(f"           差评的概率是:{1-pred(mt_cls, test8)}")

 

 

 

 

解决办法:添加差评样本的数据,复制差评信息使得与好评信息量基本一致

 1 dz_data_2["label"].value_counts()
 2 
 3 # 获取目标为0的目标数据
 4 
 5 y_lower = y_train[y_train==0]
 6 
 7 # 获取目标为0的特征数据
 8 
 9 x_lower = x_train[y_train==0]
10 
11 x_lower
12 
13 y_lower

 

 

 1 y_train_2 = y_train
 2 
 3 x_train_2 = x_train
 4 
 5 #追加十次
 6 
 7 for count in range(10):
 8 
 9     y_train_2 = y_train_2.append(y_lower)
10 
11 x_train_2 = x_train_2.append(x_lower)
12 
13 y_train_2.value_counts()    #好评与差评数量一致

 

采用重构训练集训练

1 mt_cls_2 = MultinomialNB()     
2 mt_cls_2.fit(tf_idf.transform(x_train_2), y_train_2)

 

#模型预测

1 pred_proba_2 = mt_cls_2.predict_proba(tf_idf.transform(x_test))[:,1]
2 pred_proba_2

 

#模型评分

1 mt_cls_2.score(tf_idf.transform(x_test), y_test)

 

多次验证

 1 print(f"test5预测为好评的概率是:{pred(mt_cls_2, test1)}")     
 2 
 3 print(f"           差评的概率是:{1-pred(mt_cls_2, test1)}")
 4 
 5 print(f"test6预测为好评的概率是:{pred(mt_cls_2, test2)}")
 6 
 7 print(f"           差评的概率是:{1-pred(mt_cls_2, test2)}")
 8 
 9 print(f"test7预测为好评的概率是:{pred(mt_cls_2, test3)}")
10 
11 print(f"           差评的概率是:{1-pred(mt_cls_2, test3)}")
12 
13 print(f"test8预测为好评的概率是:{pred(mt_cls_2, test4)}")
14 
15 print(f"           差评的概率是:{1-pred(mt_cls_2, test4)}")

  #结果准确

 1 test5 = "感觉很一般吧,东西没听说的那么好吃,有点些东西是冷的,不太新鲜"
 2 test6 = "一直网上看人说不错,但是我吃了没说的那么好吃,可能有点虚化了"
 3 test7 = "垃圾垃圾垃圾别去"
 4 test8 = "东西不新鲜是冷的"
 5 print(f"test5预测为好评的概率是:{pred(mt_cls_2, test5)}")     #结果准确
 6 print(f"           差评的概率是:{1-pred(mt_cls_2, test5)}")
 7 print(f"test6预测为好评的概率是:{pred(mt_cls_2, test6)}")
 8 print(f"           差评的概率是:{1-pred(mt_cls_2, test6)}")
 9 print(f"test7预测为好评的概率是:{pred(mt_cls_2, test7)}")
10 print(f"           差评的概率是:{1-pred(mt_cls_2, test7)}")
11 print(f"test8预测为好评的概率是:{pred(mt_cls_2, test8)}")
12 print(f"           差评的概率是:{1-pred(mt_cls_2, test8)}")

 

(四)总结

收获:机器学习就是从数据中挖掘出有价值的信息数据本身是无意识的,它不能自动呈现出有用的信息。要给数据一个抽象的表示接着基于表示进行建模然后估计模型的参数,也就是计算;了应对大规模的数据所带来的问题,我们还需要设计一些高效的实现手段,包括硬件层面和算法层面。

改进建议:可以进行多次训练和添加更多的数据集来提高机器的判断正确率

全代码:

  1 import numpy as np
  2 
  3 import pandas as pd
  4 
  5 from sklearn.model_selection import train_test_split
  6 
  7 from sklearn.feature_extraction.text import TfidfVectorizer
  8 
  9 from sklearn.naive_bayes import MultinomialNB
 10 
 11 from sklearn.model_selection import cross_val_score
 12 
 13 import jieba
 14 
 15 
 16 """
 17 文本预测
 18 
 19 得出信息:
 20 - 行:32483条数据  缺失值:stars 跟cus_comment
 21 - 列:14列
 22     - 目标:stars 星级评分
 23     - 特征:cus_comment:评价内容 ->> 词汇决定好评/差评
 24 """
 25 
 26 dz_data = pd.read_csv("./某点评评论.csv") #使用 pd.read_csv() 方法读取文件中的数据
 27 
 28 dz_data.info()
 29 
 30 dz_data.head()
 31 #使用 dz_data.info() 和 dz_data.head() 等方法查看数据信息和前面几行数据
 32 
 33 """
 34 1-2:差评 --- >0
 35 4-5:好评 --- >1
 36 3:中评 --- >干扰干扰项! ---> np.nan
 37 """
 38 
 39 rpl_data = {1.0:0, 2.0:0, 3.0:np.nan, 4.0:1, 5.0:1}    #对目标值进行替换取代
 40 
 41 dz_data["label"] = dz_data["stars"].map(rpl_data)
 42 
 43 dz_data.info()
 44 
 45 dz_data.head()
 46 
 47 # 注意:删除缺失值 
 48 
 49 dz_data_2 = dz_data.dropna()
 50 
 51 dz_data_2.info()
 52 
 53 dz_data.head()
 54 
 55 from sklearn.model_selection import train_test_split  #使用 train_test_split() 方法将数据划分成训练集和测试集
 56 
 57 # 特征 目标
 58 
 59 x_train, x_test, y_train, y_test = train_test_split(dz_data_2["cus_comment"], dz_data_2["label"], random_state=3, test_size=0.25)
 60 
 61 print(len(y_train))
 62 
 63 print(len(y_test))
 64 
 65 print(len(x_train))
 66 
 67 print(len(x_test))
 68 
 69 f = open("stopwords.txt", encoding="utf-8")    #使用停用词表
 70 
 71 stop_words = f.readlines()
 72 
 73 stop_words = [word.strip() for word in stop_words]
 74 
 75 stop_words
 76 
 77 print(len(stop_words))
 78 
 79 #使用 tf-idf 进行文本处理
 80 
 81 from sklearn.feature_extraction.text import TfidfVectorizer
 82 
 83 # ngram_range=(1,2) ->> 表示选取1-2个词作为组合方式
 84 
 85 tf_idf = TfidfVectorizer(stop_words=stop_words, max_features=4000, ngram_range=(1,2)) #使用 TfidfVectorizer() 方法实现文本特征提取
 86 
 87 # fit ->> 训练
 88 
 89 # transform ->> 转换数据
 90 
 91 # fit_transform ->> 训练&转换数据
 92 
 93 tf_idf.fit(x_train)
 94 
 95 from sklearn.naive_bayes import MultinomialNB      #采用贝叶斯模型
 96 
 97 mt_cls = MultinomialNB()    #实例化
 98 
 99 mt_cls.fit(tf_idf.transform(x_train), y_train)    #训练
100 
101 # 好评差评的概率
102 
103 pred_proba = mt_cls.predict_proba(tf_idf.transform(x_test))[:,1]
104 
105 pred_proba
106 
107 #模型评分
108 
109 mt_cls.score(tf_idf.transform(x_test), y_test)
110 
111 from sklearn.model_selection import cross_val_score
112 
113 scores = cross_val_score(mt_cls, tf_idf.transform(x_test), y_test, cv=10)
114 
115 np.mean(scores)    #多测预测取平均值
116 
117 test1 = "感觉这边环境不是很好,但是,挺好吃的!好评!!!"
118 
119 test2 = "这是我在长沙吃的最好的一顿,第一个上来的毛豆,配上灵魂酱汁YYDS。第二个豆花,也太好吃了把!花甲的汤汁也是无敌了"
120 
121 test3 = "朋友说很好吃,抱有非常大的期望,但结果很失望!!一点都不好吃"
122 
123 test4 = "差评!!。"
124 
125 import jieba
126 # 注意1:test系列没有做分词处理 ->> 以空格连接词语为一整个字符串
127 
128 # 注意2:处理完后,进行tf-idf处理
129 
130 # 注意3:预测得到概率
131 
132 def pred(model, test_s):
133 
134 s_fenci = " ".join(list(jieba.cut(test_s)))
135 
136 s_fenci = pd.Series(s_fenci)
137 
138 #     print(s_fenci)
139 
140 proba = model.predict_proba(tf_idf.transform(s_fenci))[:,1][0]
141 
142 #     print(proba)
143 
144 return proba
145 
146 print(f"test1预测为好评的概率是:{pred(mt_cls, test1)}")
147 
148 print(f"           差评的概率是:{1-pred(mt_cls, test1)}")
149 
150 print(f"test2预测为好评的概率是:{pred(mt_cls, test2)}")
151 
152 print(f"           差评的概率是:{1-pred(mt_cls, test2)}")
153 
154 print(f"test3预测为好评的概率是:{pred(mt_cls, test3)}")
155 
156 print(f"           差评的概率是:{1-pred(mt_cls, test3)}")
157 
158 print(f"test4预测为好评的概率是:{pred(mt_cls, test4)}")
159 
160 print(f"           差评的概率是:{1-pred(mt_cls, test4)}")
161 
162 #差评测试
163 
164 test5 = "感觉很一般吧,东西没听说的那么好吃,有点些东西是冷的,不太新鲜"
165 
166 test6 = "一直网上看人说不错,但是我吃了没说的那么好吃,可能有点虚化了"
167 
168 test7 = "垃圾垃圾垃圾别去"
169 
170 test8 = "东西不新鲜是冷的"
171 
172 dz_data_2["label"].value_counts()
173 
174 # 获取目标为0的目标数据
175 
176 y_lower = y_train[y_train==0]
177 
178 # 获取目标为0的特征数据
179 
180 x_lower = x_train[y_train==0]
181 
182 x_lower
183 
184 y_lower
185 
186 y_train_2 = y_train
187 
188 x_train_2 = x_train
189 
190 #追加十次
191 
192 for count in range(10):
193 
194 y_train_2 = y_train_2.append(y_lower)
195 
196 x_train_2 = x_train_2.append(x_lower)
197 
198 y_train_2.value_counts()    #好评与差评数量一致
199 
200 mt_cls_2 = MultinomialNB()     #采用重构训练集训练
201 
202 mt_cls_2.fit(tf_idf.transform(x_train_2), y_train_2)
203 
204 #模型预测
205 
206 pred_proba_2 = mt_cls_2.predict_proba(tf_idf.transform(x_test))[:,1]
207 
208 pred_proba_2
209 
210 #模型评分
211 
212 mt_cls_2.score(tf_idf.transform(x_test), y_test)
213 
214 from sklearn.model_selection import cross_val_score
215 
216 scores = cross_val_score(mt_cls_2, tf_idf.transform(x_test), y_test, cv=10) #使用新的训练集重新构建模型 mt_cls_2,进行预测并展示模型评分和预测结果
217 
218 np.mean(scores)    #多测预测取平均值
219 
220 print(f"test5预测为好评的概率是:{pred(mt_cls_2, test1)}")     #结果准确
221 
222 print(f"           差评的概率是:{1-pred(mt_cls_2, test1)}")
223 
224 print(f"test6预测为好评的概率是:{pred(mt_cls_2, test2)}")
225 
226 print(f"           差评的概率是:{1-pred(mt_cls_2, test2)}")
227 
228 print(f"test7预测为好评的概率是:{pred(mt_cls_2, test3)}")
229 
230 print(f"           差评的概率是:{1-pred(mt_cls_2, test3)}")
231 
232 print(f"test8预测为好评的概率是:{pred(mt_cls_2, test4)}")
233 
234 print(f"           差评的概率是:{1-pred(mt_cls_2, test4)}")
235 
236 test5 = "感觉很一般吧,东西没听说的那么好吃,有点些东西是冷的,不太新鲜"
237 
238 test6 = "一直网上看人说不错,但是我吃了没说的那么好吃,可能有点虚化了"
239 
240 test7 = "垃圾垃圾垃圾别去"
241 
242 test8 = "东西不新鲜是冷的"
243 
244 #再次预测
245 
246 print(f"test5预测为好评的概率是:{pred(mt_cls_2, test5)}")     #结果准确
247 
248 print(f"           差评的概率是:{1-pred(mt_cls_2, test5)}")
249 
250 print(f"test6预测为好评的概率是:{pred(mt_cls_2, test6)}")
251 
252 print(f"           差评的概率是:{1-pred(mt_cls_2, test6)}")
253 
254 print(f"test7预测为好评的概率是:{pred(mt_cls_2, test7)}")
255 
256 print(f"           差评的概率是:{1-pred(mt_cls_2, test7)}")
257 
258 print(f"test8预测为好评的概率是:{pred(mt_cls_2, test8)}")
259 
260 print(f"           差评的概率是:{1-pred(mt_cls_2, test8)}")

 

posted @ 2023-06-05 19:09  Kkk22  阅读(637)  评论(0)    收藏  举报