先上结果:
糖水店的评论文本 | 模型预测的情感评分 |
---|---|
‘糖水味道不错,滑而不腻,赞一个,下次还会来’ | 0.91 |
‘味道一般,没啥特点’ | 0.52 |
‘排队老半天,环境很差,味道一般般’ | 0.05 |
模型的效果还可以的样子,yeah~接下来我们好好讲讲怎么做的哈,我们通过爬虫爬取了大众点评广州8家最热门糖水店的3W条评论信息以及评分作为训练数据,前面的分析我们得知样本很不均衡。接下来我们的整体思路就是:文本特征处理(分词、去停用词、TF-IDF)—机器学习建模—模型评价。
我们先不处理样本不均衡问题,直接建模后查看结果,接下来我们再按照两种方法处理样本不均衡,对比结果。
import pandas as pd
from matplotlib import pyplot as plt
import jieba
data = pd.read_csv('data.csv')
data.head()
cus_id | comment_time | comment_star | cus_comment | kouwei | huanjing | fuwu | shopID | stars | year | month | weekday | hour | comment_len | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 迷糊泰迪 | 2018-09-20 06:48:00 | sml-str40 | 南信 算是 广州 著名 甜品店 吧 好几个 时间段 路过 都 是 座无虚席 看着 餐单 上 ... | 非常好 | 好 | 好 | 518986 | 4.0 | 2018 | 9 | 3 | 6 | 145.0 |
1 | 稱霸幼稚園 | 2018-09-22 21:49:00 | sml-str40 | 中午 吃 完 了 所谓 的 早茶 回去 放下 行李 休息 了 会 就 来 吃 下午茶 了 服... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 5 | 21 | 255.0 |
2 | 爱吃的美美侠 | 2018-09-22 22:16:00 | sml-str40 | 冲刺 王者 战队 吃遍 蓉城 战队 有 特权 五月份 和 好 朋友 毕业 旅行 来 了 广州... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 5 | 22 | 255.0 |
3 | 姜姜会吃胖 | 2018-09-19 06:36:00 | sml-str40 | 都 说来 广州 吃 糖水 就要 来南信 招牌 姜撞奶 红豆 双皮奶 牛 三星 云吞面 一楼 ... | 非常好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 2 | 6 | 184.0 |
4 | forevercage | 2018-08-24 17:58:00 | sml-str50 | 一直 很 期待 也 最 爱 吃 甜品 广州 的 甜品 很 丰富 很 多样 来 之前 就 一直... | 非常好 | 很好 | 很好 | 518986 | 5.0 | 2018 | 8 | 4 | 17 | 255.0 |
大众点评的评分分为1-5分,1-2为差评,4-5为好评,3为中评,因此我们把1-2记为0,4-5记为1,3为中评,对我们的情感分析作用不大,丢弃掉这部分数据,但是可以作为训练语料模型的语料。我们的情感评分可以转化为标签值为1的概率值,这样我们就把情感分析问题转为文本分类问题了。
#构建label值
def zhuanhuan(score):
if score > 3:
return 1
elif score < 3:
return 0
else:
return None
#特征值转换
data['target'] = data['stars'].map(lambda x:zhuanhuan(x))
data_model = data.dropna()
data_model
cus_id | comment_time | comment_star | cus_comment | kouwei | huanjing | fuwu | shopID | stars | year | month | weekday | hour | comment_len | target | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 迷糊泰迪 | 2018-09-20 06:48:00 | sml-str40 | 南信 算是 广州 著名 甜品店 吧 好几个 时间段 路过 都 是 座无虚席 看着 餐单 上 ... | 非常好 | 好 | 好 | 518986 | 4.0 | 2018 | 9 | 3 | 6 | 145.0 | 1.0 |
1 | 稱霸幼稚園 | 2018-09-22 21:49:00 | sml-str40 | 中午 吃 完 了 所谓 的 早茶 回去 放下 行李 休息 了 会 就 来 吃 下午茶 了 服... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 5 | 21 | 255.0 | 1.0 |
2 | 爱吃的美美侠 | 2018-09-22 22:16:00 | sml-str40 | 冲刺 王者 战队 吃遍 蓉城 战队 有 特权 五月份 和 好 朋友 毕业 旅行 来 了 广州... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 5 | 22 | 255.0 | 1.0 |
3 | 姜姜会吃胖 | 2018-09-19 06:36:00 | sml-str40 | 都 说来 广州 吃 糖水 就要 来南信 招牌 姜撞奶 红豆 双皮奶 牛 三星 云吞面 一楼 ... | 非常好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 2 | 6 | 184.0 | 1.0 |
4 | forevercage | 2018-08-24 17:58:00 | sml-str50 | 一直 很 期待 也 最 爱 吃 甜品 广州 的 甜品 很 丰富 很 多样 来 之前 就 一直... | 非常好 | 很好 | 很好 | 518986 | 5.0 | 2018 | 8 | 4 | 17 | 255.0 | 1.0 |
6 | superclampfa | 2018-08-15 00:39:00 | sml-str40 | 补发 点评 目前为止 吃 过 的 最 好吃 的 双皮奶 没有 之一 去 广州 一定 要 尝试... | 非常好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 8 | 2 | 0 | 255.0 | 1.0 |
8 | 初小正 | 2018-09-15 22:26:00 | sml-str40 | 广州 很胖 人 忍不住 的 要 吃 糖水 甜品 南信 的 店面 很 好找 上下 九 旅游区 ... | 非常好 | 很好 | 非常好 | 518986 | 4.0 | 2018 | 9 | 5 | 22 | 255.0 | 1.0 |
9 | 水芙蓉88 | 2018-09-06 16:06:00 | sml-str40 | 位于 步行街 上 沿着 步行街 一直 走 就 可以 到达 去 的 时候 不用 排队 门口 有... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 3 | 16 | 255.0 | 1.0 |
10 | 滚淡小姐 | 2018-09-12 20:44:00 | sml-str40 | 不 知道 算不算 网红 只是 在 很多 小伙伴 的 朋友圈 都 看到 过 自然 要 来 打卡... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 2 | 20 | 255.0 | 1.0 |
11 | 请叫我伊丽莎丸袁哥 | 2018-08-22 11:30:00 | sml-str50 | 这家 店 可谓 是 人气 爆棚 小贴士 是 座位 先 让 同行 小伙伴 找 好 否则 买好 ... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 8 | 2 | 11 | 255.0 | 1.0 |
12 | Hugewood | 2018-08-09 13:03:00 | sml-str40 | 这次 是 特地 为了 南信 才 去 的 上下 九 真的 是 一家 很 任性 的 店 准点 九... | 好 | 很好 | 好 | 518986 | 4.0 | 2018 | 8 | 3 | 13 | 255.0 | 1.0 |
13 | 360_执着的马 | 2018-08-29 02:02:00 | sml-str50 | 睡 到 自然 醒 又 去 上下 九 步行街 的 南信 要 一份 姜撞奶 一份 莲子 伴 椰汁... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 8 | 2 | 2 | 163.0 | 1.0 |
14 | 小昕子_17 | 2018-08-28 13:02:00 | sml-str40 | 广州 的 老字号 不少 其中 招牌 中有 文字 的 就 有 好几家 每家 都 有 自己 的 ... | 很好 | 好 | 好 | 518986 | 4.0 | 2018 | 8 | 1 | 13 | 255.0 | 1.0 |
15 | lincolnsuper | 2018-09-06 22:14:00 | sml-str40 | 传统 的 广式 甜品店 就 应该 是 这个 样子 店面 不 大 店员 都 是 有点 年纪 的... | 很好 | 好 | 好 | 518986 | 4.0 | 2018 | 9 | 3 | 22 | 255.0 | 1.0 |
16 | 肥牛佳 | 2018-09-05 22:50:00 | sml-str50 | 老广 同事 极力推荐 的 店铺 在 宝华 面馆 吃 完 主食 一路 散步 过来 接着 战斗 ... | 非常好 | 一般 | 一般 | 518986 | 5.0 | 2018 | 9 | 2 | 22 | 255.0 | 1.0 |
17 | 两活勿连 | 2018-09-11 13:18:00 | sml-str40 | 上下 九 步行街 上 的 网红 甜品店 人气 爆棚 门口 有 一面 墙 的 各种 认证 获奖... | 非常好 | 好 | 好 | 518986 | 4.0 | 2018 | 9 | 1 | 13 | 240.0 | 1.0 |
18 | 宝贝longan | 2018-09-05 15:34:00 | sml-str40 | 不是 周末 节假日 在 上下 九 步行街 的 南信 甜品店 也 是 人山人海 就算 肯 一起... | 很好 | 好 | 好 | 518986 | 4.0 | 2018 | 9 | 2 | 15 | 255.0 | 1.0 |
19 | 柚chopyf | 2018-09-13 11:37:00 | sml-str40 | 我 为 代言 地址 荔灣區 第十 甫 路 号 近 宝华 路 人均 元 左右 在 广州 众多 ... | 很好 | 很好 | 很好 | 518986 | 4.0 | 2018 | 9 | 3 | 11 | 255.0 | 1.0 |
20 | suki_gb | 2018-08-30 23:55:00 | sml-str50 | 去 广州 玩 美食 当然 不能 辜负 住 在 上下 九 晚上 点 出来 觅食 上 看 了 别... | 非常好 | 好 | 很好 | 518986 | 5.0 | 2018 | 8 | 3 | 23 | 255.0 | 1.0 |
21 | 几哩是块里脊_ | 2018-09-24 09:32:00 | sml-str40 | 来 了 广州 可以 说出 一系列 小吃 早茶 肠粉 烧腊 甜品 糖水 汤品 等 从 饮食文化... | 非常好 | 好 | 好 | 518986 | 4.0 | 2018 | 9 | 0 | 9 | 255.0 | 1.0 |
23 | 树懒丹 | 2018-09-12 21:36:00 | sml-str50 | 打卡 广州 上下 九 步行街 那条 类似 于 上海南京路 步行街 的 街 到处 琳琅满目 的... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 9 | 2 | 21 | 255.0 | 1.0 |
24 | 忽忽_3307 | 2018-09-26 09:13:00 | sml-str40 | 抱 着 很大 期望 去 的 人 真的 超级 多 买 的 门口 的 外带 双皮奶 和 杨枝 甘... | 很好 | 一般 | 非常好 | 518986 | 4.0 | 2018 | 9 | 2 | 9 | 72.0 | 1.0 |
25 | BerlinettaNNN | 2018-09-25 23:37:00 | sml-str10 | 超级 恶心 打包 了 三份 回家 吃 到 第二份 的 时候 直接 吃 出 不 知道 是 什么... | 差 | 差 | 差 | 518986 | 1.0 | 2018 | 9 | 1 | 23 | 114.0 | 0.0 |
27 | ShinyNikki | 2018-09-25 22:44:00 | sml-str50 | 周二 两天 打三卡 点评 都 不 推送 我 让 点评 了 哈哈 今天 去 了 北京路 晚上 ... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 9 | 1 | 22 | 255.0 | 1.0 |
28 | 爱吃甜食得小吃兔 | 2018-09-25 22:06:00 | sml-str50 | 依旧 那么 好吃 这次 去 竟然 可以 叫外卖 了 真 好 啊 坐在 酒店 里 就 能 吃 ... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 9 | 1 | 22 | 146.0 | 1.0 |
29 | C-zm_6372 | 2018-09-25 20:48:00 | sml-str50 | 逛街 正好 经过 就 进去 了 椰汁 香芋 西米露 和 鲜虾 云吞面 也 很 好吃 推荐 推荐 | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 9 | 1 | 20 | 47.0 | 1.0 |
30 | ceciler | 2018-09-25 16:30:00 | sml-str50 | 朋友 强烈推荐 我来 的 吃 过 以后 也 就 这样 吧 一般 甜品店 都 做 得 出来 而... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 9 | 1 | 16 | 255.0 | 1.0 |
31 | 张菜菜8 | 2018-09-25 15:49:00 | sml-str50 | 这家 真的 是 很棒 了 是 在 广州 吃 到 最 喜欢 的 店 了 强推 酸辣 牛 三星 ... | 非常好 | 非常好 | 非常好 | 518986 | 5.0 | 2018 | 9 | 1 | 15 | 176.0 | 1.0 |
32 | 兔子need肉 | 2018-09-25 12:17:00 | sml-str50 | 旅游 必吃 的 一家 非常 好找 看 了 菜谱 感觉 啥 都 好吃 点 了 几个 大众 点评... | 非常好 | 非常好 | 很好 | 518986 | 5.0 | 2018 | 9 | 1 | 12 | 255.0 | 1.0 |
33 | C小姐觅食迹 | 2018-09-25 10:53:00 | sml-str40 | 来 广州 必要 吃 南信 啦 一进 店面 人山人海 的 场景 真实 有 被 吓 到 位子 自... | 非常好 | 一般 | 一般 | 518986 | 4.0 | 2018 | 9 | 1 | 10 | 255.0 | 1.0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
32445 | lihuamama | 2018-04-08 15:41:00 | sml-str10 | 芋头 椰汁 西米露 芋头 是 酸 的 不 新鲜 | 差 | 好 | 差 | 521698 | 1.0 | 2018 | 4 | 6 | 15 | 23.0 | 0.0 |
32446 | JJMiss~Z | 2017-12-25 12:31:00 | sml-str40 | 慕名而来 的 在 西华路 第一 津 里面 一问 好多 人 都 不 知道 有些 年 的 老铺 ... | 很好 | 很好 | 很好 | 521698 | 4.0 | 2017 | 12 | 0 | 12 | 255.0 | 1.0 |
32447 | Kary_BB_7754 | 2017-11-01 19:30:00 | sml-str20 | 收银 阿姨 服务 超级 差多 问 一句 就 反 白眼 这么 不耐烦 就 不要 做 服务行业 ... | 非常好 | 好 | 差 | 521698 | 2.0 | 2017 | 11 | 2 | 19 | 121.0 | 0.0 |
32448 | 涴世亦踯躅 | 2017-10-31 07:49:00 | sml-str40 | 沙湾 小镇 以前 的 老 镇子 大都 是 住 在 这里 好多年 的 老 街坊邻居 学校 旁边... | 非常好 | 好 | 好 | 521698 | 4.0 | 2017 | 10 | 1 | 7 | 255.0 | 1.0 |
32450 | vivi2008 | 2017-10-01 16:00:00 | sml-str50 | 龟苓膏 配 炼乳 芒果 双皮 特别 好吃 芒果 又 甜 又 新鲜 椰奶 红 豆沙 淡淡的 甜... | 非常好 | 很好 | 很好 | 521698 | 5.0 | 2017 | 10 | 6 | 16 | 52.0 | 1.0 |
32452 | 不知道起什么名字好 | 2017-07-07 16:27:00 | sml-str40 | 杏仁 炒奶糊 浓浓的 杏仁 味好 食 其他 地方 都 食 唔 道 特地来 食 | 很好 | 很好 | 很好 | 521698 | 4.0 | 2017 | 7 | 4 | 16 | 38.0 | 1.0 |
32453 | mingmin9 | 2017-06-18 22:38:00 | sml-str50 | 从 我 初中 时期 开 到 现在 店内 虽然 环境 不 大 可以 称得上 是 老字号 店 啦... | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2017 | 6 | 6 | 22 | 161.0 | 1.0 |
32454 | henry_gzw | 2016-11-14 15:13:00 | sml-str40 | 位于 西华路 广州 有名 的 食街 这家 店 做 的 时间 应该 算是 数一数二 的 已 出... | 非常好 | 好 | 好 | 521698 | 4.0 | 2016 | 11 | 0 | 15 | 204.0 | 1.0 |
32455 | bre比 | 2016-07-02 01:46:00 | sml-str50 | 从家 下楼 走 分钟 就 可以 吃 甜品 好 方便 这家 店 起码 在 我 初中 懂事 的 ... | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2016 | 7 | 5 | 1 | 255.0 | 1.0 |
32456 | eaterp | 2016-05-13 21:12:00 | sml-str40 | 慕名而来 感觉 还是 挺不错 的 地方 虽然 不 大 但是 环境 不错 服务 一般 吧 不过... | 很好 | 好 | 好 | 521698 | 4.0 | 2016 | 5 | 4 | 21 | 151.0 | 1.0 |
32457 | 丫琪_6831 | 2016-01-07 13:50:00 | sml-str10 | 口味 好 一般 店员 态度 真的 好差 做生意 做成 这样 不会 再 去 了 | 差 | 差 | 差 | 521698 | 1.0 | 2016 | 1 | 3 | 13 | 38.0 | 0.0 |
32458 | QI_285010384 | 2015-10-31 22:41:00 | sml-str10 | 服务 太度 差 出品 慢 味道 比开 记差 | 差 | 差 | 差 | 521698 | 1.0 | 2015 | 10 | 5 | 22 | 21.0 | 0.0 |
32459 | iiiookkk | 2015-10-06 19:09:00 | sml-str50 | 千里迢迢 跑过来 不 枉 此行 好吃 | 非常好 | 很好 | 非常好 | 521698 | 5.0 | 2015 | 10 | 1 | 19 | 18.0 | 1.0 |
32460 | C+CL | 2015-06-28 22:14:00 | sml-str40 | 赞 味道 很 不错 双皮奶 很 好吃 就是 比较 贵 而且 分量 有点 少 | 非常好 | 很好 | 好 | 521698 | 4.0 | 2015 | 6 | 6 | 22 | 37.0 | 1.0 |
32461 | dpuser_0178821948 | 2015-02-02 20:41:00 | sml-str40 | 回 湖南 前 特别 想 吃 广州 的 甜品 为了 让 他 送外 卖点 了 五份 吃 的 好 ... | 很好 | 很好 | 非常好 | 521698 | 4.0 | 2015 | 2 | 0 | 20 | 69.0 | 1.0 |
32462 | Eblank造梦 | 2014-07-16 21:20:00 | sml-str40 | 凤凰 炒奶 吃 到 最后 还有 一个 未熟 的 蛋黄 味道 很 好吃 过 都 说好 店面 有... | 很好 | 好 | 好 | 521698 | 4.0 | 2014 | 7 | 2 | 21 | 59.0 | 1.0 |
32463 | 识事务者 | 2014-05-19 22:03:00 | sml-str40 | 水准 还 可 不过 正如 网支 所 讲 有用 塑料产品 代替 有 些许 倒胃口 | 非常好 | 好 | 好 | 521698 | 4.0 | 2014 | 5 | 0 | 22 | 39.0 | 1.0 |
32464 | 睇我唔岛 | 2013-09-20 20:21:00 | sml-str10 | 升价后 太少 人 去 食 食物 唔 新鲜 今晚 打包 个 芝麻 胡翻 屋企 食一食 落口 一... | 差 | 一般 | 差 | 521698 | 1.0 | 2013 | 9 | 4 | 20 | 68.0 | 0.0 |
32465 | CarolLokyee | 2013-08-01 21:11:00 | sml-str20 | 外卖 好像 要 买 五碗 才 送 有时候 多人 连 电话 也 不 听 态度 极差 到 店面 ... | 好 | 一般 | 差 | 521698 | 2.0 | 2013 | 8 | 3 | 21 | 70.0 | 0.0 |
32466 | 小琼豆豆 | 2013-08-01 12:23:00 | sml-str40 | 店面 很 不起眼 在 西华路 里面 以前 价钱 很 划算 现在 升价 了 就 比较 少 吃 了 | 很好 | 很好 | 很好 | 521698 | 4.0 | 2013 | 8 | 3 | 12 | 47.0 | 1.0 |
32467 | withdraw | 2013-05-09 18:33:00 | sml-str40 | 甜品 老店 每次 来 这里 就 要点 一碗 红豆 双皮奶 奶香 红豆 料足 吃 起来 很 舒... | 很好 | 很好 | 很好 | 521698 | 4.0 | 2013 | 5 | 3 | 18 | 97.0 | 1.0 |
32468 | 台狼棒会 | 2013-05-02 18:40:00 | sml-str40 | 今天 专门 去 西华路 美食 之旅 所以 也 来 了 这家 店 早上 点多 去 的 还 没 ... | 很好 | 好 | 很好 | 521698 | 4.0 | 2013 | 5 | 3 | 18 | 108.0 | 1.0 |
32469 | 我就是一只蛙 | 2013-04-24 23:20:00 | sml-str50 | 好 好吃 真的 不错 一级 推介 苏 上门 吃 过 不过 就系 服务态度 有点 差 接受 到... | 很好 | 好 | 好 | 521698 | 5.0 | 2013 | 4 | 2 | 23 | 62.0 | 1.0 |
32470 | 与猫看日落 | 2013-01-25 17:53:00 | sml-str50 | 甜品 的话 这家 已经 很 好 了 老城区 好 有 广州 格调 街坊 生意 做 得 非常 好... | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2013 | 1 | 4 | 17 | 79.0 | 1.0 |
32471 | lilycat10 | 2013-01-25 17:42:00 | sml-str50 | 真的 是 起沙 的 红 豆沙 非常 好 价钱 便宜 附近 的 邻居 有福 了 推荐 | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2013 | 1 | 4 | 17 | 41.0 | 1.0 |
32472 | 木頭woodwood | 2012-02-22 04:27:00 | sml-str10 | 年前 啱 搬 嚟 呢 頭 嘅 時 候 呢 間 嘢 喺 我 逢 星期五 嘅 宵夜 朋友 嚟 都... | 差 | 一般 | 一般 | 521698 | 1.0 | 2012 | 2 | 2 | 4 | 190.0 | 0.0 |
32473 | mj19910916 | 2011-12-30 18:44:00 | sml-str50 | 这里 好吃 得 太 离谱 了 吧 简直 就是 惊艳 曾经 冒名 去过 北京路 和 东 山口 ... | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2011 | 12 | 4 | 18 | 216.0 | 1.0 |
32480 | winny311111 | 2018-05-14 03:09:00 | sml-str50 | 第二次 来 好吃 第二次 来 好吃 第二次 来 好吃 | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2018 | 5 | 0 | 3 | 26.0 | 1.0 |
32481 | Polykat_年嫿 | 2018-04-28 02:33:00 | sml-str50 | 兒時 的 味道 兒時 的 味道 兒時 的 味道 | 非常好 | 很好 | 好 | 521698 | 5.0 | 2018 | 4 | 5 | 2 | 23.0 | 1.0 |
32482 | 不瘦到120斤不换ID | 2018-04-09 01:22:00 | sml-str50 | 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好喝 好... | 非常好 | 非常好 | 非常好 | 521698 | 5.0 | 2018 | 4 | 0 | 1 | 56.0 | 1.0 |
21691 rows × 15 columns
中文文本特征处理,需要进行中文分词,jieba分词库简单好用。接下来需要过滤停用词,网上能够搜到现成的。最后就要进行文本转向量,有词库表示法、TF-IDF、word2vec等,这篇文章作了详细介绍,推荐一波 https://zhuanlan.zhihu.com/p/44917421
这里我们使用sklearn库的TF-IDF工具进行文本特征提取。
#切分测试集、训练集
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(data_model['cus_comment'], data_model['target'], random_state=3, test_size=0.25)
#引入停用词
infile = open("stopwords.txt",encoding='utf-8')
stopwords_lst = infile.readlines()
stopwords = [x.strip() for x in stopwords_lst]
#中文分词
def fenci(train_data):
words_df = train_data.apply(lambda x:' '.join(jieba.cut(x)))
return words_df
x_train[:5]
26328 冲着 老字号 去 的 但 真的 不 咋 地 所有 的 东西 都 不是 先 做 的 点 了 煎...
3457 名过其实 味道 一般 全是 人 价格 也 贵 感觉 碗碟 都 洗 不 干净
17834 香芋 西米 以前 系 北京路 个边 上班 落 左班 都 会同 同事 去 吃糖 上个星期 去 ...
7904 南信 的 双皮奶 非常 滑 不是 很甜 可是 很嫩 非常 美味 还有 鲜虾 肠有 好多好多 ...
3258 环境 真的 是 一般 可能 是 老店 的 关系 但 很 传统 双皮奶 奶味重 甜度 适中 粥...
Name: cus_comment, dtype: object
#使用TF-IDF进行文本转向量处理
from sklearn.feature_extraction.text import TfidfVectorizer
tv = TfidfVectorizer(stop_words=stopwords, max_features=3000, ngram_range=(1,2))
tv.fit(x_train)
C:\Users\Administrator\Anaconda3\lib\site-packages\sklearn\feature_extraction\text.py:300: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['ain', 'aren', 'couldn', 'didn', 'doesn', 'don', 'hadn', 'hasn', 'haven', 'isn', 'lex', 'll', 'mon', 'null', 'shouldn', 've', 'wasn', 'weren', 'won', 'wouldn', '12', 'li', 'zxfitl'] not in stop_words.
'stop_words.' % sorted(inconsistent))
TfidfVectorizer(analyzer='word', binary=False, decode_error='strict',
dtype=, encoding='utf-8', input='content',
lowercase=True, max_df=1.0, max_features=3000, min_df=1,
ngram_range=(1, 2), norm='l2', preprocessor=None, smooth_idf=True,
stop_words=['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', '-', '--', '.', '..', '...', '......', '...................', './', '.一', '记者', '数', '年', '月', '日', '时', '分', '秒', '/', '//', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':', '://', '::', ';', '<', '=', '>', '>>', '?', '@'...3', '94', '95', '96', '97', '98', '99', '100', '01', '02', '03', '04', '05', '06', '07', '08', '09'],
strip_accents=None, sublinear_tf=False,
token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, use_idf=True,
vocabulary=None)
特征和标签已经准备好了,接下来就是建模了。这里我们使用文本分类的经典算法朴素贝叶斯算法,而且朴素贝叶斯算法的计算量较少。特征值是评论文本经过TF-IDF处理的向量,标签值评论的分类共两类,好评是1,差评是0。情感评分为分类器预测分类1的概率值。
#计算分类效果的准确率
from sklearn.naive_bayes import MultinomialNB
from sklearn.metrics import roc_auc_score, f1_score
classifier = MultinomialNB()
classifier.fit(tv.transform(x_train), y_train)
classifier.score(tv.transform(x_test), y_test)
0.9275308869629356
#计算分类器的AUC值
y_pred = classifier.predict_proba(tv.transform(x_test))[:,1]
roc_auc_score(y_test,y_pred)
0.889712635344161
#计算一条评论文本的情感评分
def ceshi(model,strings):
strings_fenci = fenci(pd.Series([strings]))
return float(model.predict_proba(tv.transform(strings_fenci))[:,1])
#从大众点评网找两条评论来测试一下
test1 = '很好吃,环境好,所有员工的态度都很好,上菜快,服务也很好,味道好吃,都是用蒸馏水煮的,推荐,超好吃' #5星好评
test2 = '糯米外皮不绵滑,豆沙馅粗躁,没有香甜味。12元一碗不值。' #1星差评
print('好评实例的模型预测情感得分为{}\n差评实例的模型预测情感得分为{}'.format(ceshi(classifier,test1),ceshi(classifier,test2)))
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\ADMINI~1\AppData\Local\Temp\jieba.cache
Loading model cost 1.330 seconds.
Prefix dict has been built succesfully.
好评实例的模型预测情感得分为0.824812345120737
差评实例的模型预测情感得分为0.7751377818748739
可以看出,准确率和AUC值都非常不错的样子,但点评网上的实际测试中,5星好评模型预测出来了,1星差评缺预测错误。为什么呢?我们查看一下混淆矩阵
from sklearn.metrics import confusion_matrix
y_predict = classifier.predict(tv.transform(x_test))
cm = confusion_matrix(y_test, y_predict)
cm
array([[ 44, 387],
[ 6, 4986]], dtype=int64)
可以看出,负类的预测非常不准,433单准确预测为负类的只有15.7%,应该是由于数据不平衡导致的,模型的默认阈值为输出值的中位数。比如逻辑回归的输出范围为[0,1],当某个样本的输出大于0.5就会被划分为正例,反之为反例。在数据的类别不平衡时,采用默认的分类阈值可能会导致输出全部为正例,产生虚假的高准确度,导致分类失败。
处理样本不均衡问题的方法,首先可以选择调整阈值,使得模型对于较少的类别更为敏感,或者选择合适的评估标准,比如ROC或者F1,而不是准确度(accuracy)。另外一种方法就是通过采样(sampling)来调整数据的不平衡。其中欠采样抛弃了大部分正例数据,从而弱化了其影响,可能会造成偏差很大的模型,同时,数据总是宝贵的,抛弃数据是很奢侈的。另外一种是过采样,下面我们就使用过采样方法来调整。
单纯的重复了反例,因此会过分强调已有的反例。如果其中部分点标记错误或者是噪音,那么错误也容易被成倍的放大。因此最大的风险就是对反例过拟合。
data['target'].value_counts()
1.0 19916
0.0 1779
Name: target, dtype: int64
#把0类样本复制10次,构造训练集
index_tmp = y_train==0
y_tmp = y_train[index_tmp]
x_tmp = x_train[index_tmp]
x_train2 = pd.concat([x_train,x_tmp,x_tmp,x_tmp,x_tmp,x_tmp,x_tmp,x_tmp,x_tmp,x_tmp,x_tmp])
y_train2 = pd.concat([y_train,y_tmp,y_tmp,y_tmp,y_tmp,y_tmp,y_tmp,y_tmp,y_tmp,y_tmp,y_tmp])
#使用过采样样本(简单复制)进行模型训练,并查看准确率
clf2 = MultinomialNB()
clf2.fit(tv.transform(x_train2), y_train2)
y_pred2 = clf2.predict_proba(tv.transform(x_test))[:,1]
roc_auc_score(y_test,y_pred2)
0.899220190820394
#查看此时的混淆矩阵
y_predict2 = clf2.predict(tv.transform(x_test))
cm = confusion_matrix(y_test, y_predict2)
cm
array([[ 326, 105],
[ 654, 4338]], dtype=int64)
可以看出,即使是简单粗暴的复制样本来处理样本不平衡问题,负样本的识别率大幅上升了,变为77%,满满的幸福感呀~我们自己写两句评语来看看
ceshi(clf2,'排队人太多,环境不好,口味一般')
0.352913902404629
可以看出把0类别的识别出来了,太棒了~
SMOTE(Synthetic minoritye over-sampling technique,SMOTE),是在局部区域通过K-近邻生成了新的反例。相较于简单的过采样,SMOTE降低了过拟合风险,但同时运算开销加大
对SMOTE感兴趣的同学可以看下这篇文章https://www.jianshu.com/p/ecbc924860af
#使用SMOTE进行样本过采样处理
from imblearn.over_sampling import SMOTE
oversampler=SMOTE(random_state=0)
x_train_vec = tv.transform(x_train)
x_resampled, y_resampled = oversampler.fit_sample(x_train_vec, y_train)
#原始的样本分布
y_train.value_counts()
1.0 14920
0.0 1348
Name: target, dtype: int64
#经过SMOTE算法过采样后的样本分布情况
pd.Series(y_resampled).value_counts()
1.0 14920
0.0 14920
dtype: int64
我们经过插值,把0类数据也丰富为14923个数据了,这时候正负样本的比例为1:1,接下来我们用平衡后的数据进行训练,效果如何呢,好期待啊~
#使用过采样样本(SMOTE)进行模型训练,并查看准确率
clf3 = MultinomialNB()
clf3.fit(x_resampled, y_resampled)
y_pred3 = clf3.predict_proba(tv.transform(x_test))[:,1]
roc_auc_score(y_test,y_pred3)
0.9010351597358558
#查看此时的准确率
y_predict3 = clf3.predict(tv.transform(x_test))
cm = confusion_matrix(y_test, y_predict3)
cm
array([[ 326, 105],
[ 613, 4379]], dtype=int64)
#到网上找一条差评来测试一下情感评分的预测效果
test3 = '糯米外皮不绵滑,豆沙馅粗躁,没有香甜味。12元一碗不值。'
ceshi(clf3,test3)
0.22919320383366565
可以看出,使用SMOTE插值与简单的数据复制比起来,AUC率略有提高,实际预测效果也挺好
接下来我们把3W条数据都拿来训练,数据量变多了,模型效果应该会更好
#词向量训练
tv2 = TfidfVectorizer(stop_words=stopwords, max_features=3000, ngram_range=(1,2))
tv2.fit(data_model['cus_comment'])
#SMOTE插值
X_tmp = tv2.transform(data_model['cus_comment'])
y_tmp = data_model['target']
sm = SMOTE(random_state=0)
X,y = sm.fit_sample(X_tmp, y_tmp)
clf = MultinomialNB()
clf.fit(X, y)
def fenxi(strings):
strings_fenci = fenci(pd.Series([strings]))
return float(clf.predict_proba(tv2.transform(strings_fenci))[:,1])
C:\Users\Administrator\Anaconda3\lib\site-packages\sklearn\feature_extraction\text.py:300: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['ain', 'aren', 'couldn', 'didn', 'doesn', 'don', 'hadn', 'hasn', 'haven', 'isn', 'lex', 'll', 'mon', 'null', 'shouldn', 've', 'wasn', 'weren', 'won', 'wouldn', '12', 'li', 'zxfitl'] not in stop_words.
'stop_words.' % sorted(inconsistent))
#到网上找一条差评来测试一下
fenxi('糯米外皮不绵滑,豆沙馅粗躁,没有香甜味。12元一碗不值。')
0.2723496698366991
只用到了简单的机器学习,就做出了不错的情感分析效果,知识的力量真是强大呀,666~