基于hadoop的评价预测系统
编写java程序,使其能够实现基于上传至hdfs的“学号_上传文件.txt”数据集训练情感分类器的目的。在训练的过程中,应过滤包含非中文字符或全部由非中文字符构成的词语。保存模型文件至“学号_模型.txt”文件中。格式要求:
类标_词语1\t计数
类标_词语2\t计数
类标_词语3\t计数
……
类标1\t计数
类标2\t计数
基于训练得到的模型参数(即Nc和Ncw,其中,c表示情感标签类别,c∈{好评,差评},w∈V,V是“学号_上传文件.data”数据集包含的中文词典集合),对“test.txt”数据集中的各条记录进行“情感标签”判别。判别结果输出至“学号_预测结果.txt”文件中。“学号_预测结果.txt”文件中的每行是行号及“test.txt”中预测的“情感标签”:格式要求:
1 情感标签
2 情感标签
3 情感标签
……
2000 情感标签
训练和预测用的数据格式如下
好评 几乎 凌晨 才 到 包头 包头 没有 什么 特别 好 酒店 每次 来 就是 住 这家 所以 没有 忒 多 对比 感觉 行 下次 还是 得到 这里 来 住
好评 住 过 几次 东莞 酒店 海悦 地理位置 早餐 最棒 听说 朋友 说 请来 厨师 来头 呵呵 冲 这个 去
好评 酒店设施 比较 不错 就是 携程 价格 酒店 前台 一样 没有 竞争力
好评 房间 不算 大 中规中矩 北方 服务 真的 不敢恭维 CHECK IN 后 没有 服务生 帮 你 拿 行李 到 房间 去 周围 酒店 没 啥 逛 自己 吃 早饭 可以 去 万豪 喜来登 之间 那条 路 永和 豆浆店 很 便宜
好评 通过 朋友 介绍 住 苏州 南林 饭店 一进 酒店 大堂 感觉 很 好 酒店 行李 员 前台 服务员 大堂 经理 很 热情 有种 宾至如归 感觉 房间 很 特色 背景 墙上 金色 字体 诗词 我 住 朝南 景观 房 感觉 真的 很 好 一 出门 就是 娱乐 酒吧 一条街 美食 一条街 出门 很 方便 下次 来 苏州 我 会 选择 南林 我 会 介绍 我 朋友 入住 南林 饭店
好评 西宁 住 过 几个 酒店 此 酒店 虽然 比起 内地 四星级 差 一些 但 西宁 算是 不错 价格 不 高 房间 里 东西 倒 干净 地毯 有点 脏 用 地 暖 感觉 比 空调 舒服 多 没有 噪音 安全 周围环境 尚可
好评 房间 算 整齐 宽敞 我 住 标准间 大床 房 只是 浴室 淋浴 笼头 不太好 出水 不 均匀 洗澡 不 舒服 服务 不错 到 酒店 早上 点 让 我 提前 入住 而且 结账 速度 比较 快 不 耽误时间 酒店 靠近 号 地铁 算 方便
为了实现预测模型使用了两组mapperreducer
类标_词语1\t计数
类标_词语2\t计数
类标_词语3\t计数
好评_好吃\t23
将一行数据先以\t进行分割得到关键字行,再将关键字行以空格分割,分割后以<评价词_关键字,1>写入上下文
读取上下文,对第二个属性值进行累加,等到每个组合关键字的计数,再以<评价词_关键字,计数>写入上下文
mapper时判断是否为好评,如果为好评,写入一条<统计_好评,1>到上下文;如果为差评,写入一条<统计_差评,1>到上下文
注意:reducer时进行了自动排序,要把统计结果放最后就要加一个不同于前面数据的名
1 情感标签
2 情感标签
3 情感标签
4 好评
mapper主要完成预测数据的分词,预测时只需要后面的关键字组,所以以\t先分割出关键字行,再以空格分割出关键字组,将关键字以<行号,关键字>写入上下文
先用一个静态代码块加载训练出的模型到一个hashmap内,方便预测时使用,写一个函数判断一行对应的关键字集合预测是否是好评,然后在上下文写入<行号,评价词>
Integer good = wordMap.get("好评_" + value);
Integer bad = wordMap.get("差评_" + value);
good = good == null ? 1 : good + 1;
bad = bad == null ? 1 : bad + 1;
if (good != bad) {
Double v = (good > bad) ? Math.ceil(good /bad) : -Math.ceil(bad / good);
goodNum += v.intValue();
}
遍历关键字集合,对每个关键字进行拼接后从训练模型集合里面获取个数,如果为空设为1,如果不为空设为n+1
goodNum代表一行词语的好评系数,如果 >= 0 就为好评,反之为差评
如果一个词的好评和差评计数一样,好评系数为0
如果一个词好评数目 > 差评数目,用好评数 / 差评数 向上取整作为好评系数
如果一个词好评数目 < 差评数目,用差评数 / 好评数 向上取整再去相反数作为好评系数
将每个词的好评系数进行累加就得到一行词的评价
在reducer中添加三个计数器,分别计算好评数,差评数,统计正确数
在一行数据评价完成后,判断是好评就好评计数加一,反正差评计数加一
根据预测文件的格式,可以发现前1000条为好评,后1000条为差评,将预测结果与之判断,如果相同,正确计数加一
最后将三个参数在第2000行上下文写出去之后以<学号,描述_个数(比例)>的格式写入上下文
按照实验要求需要实现一个预测文件上传界面和预测结果和数据展示界面
这里采用了Springboot快速搭建了一个前后端分离的框架,然后实现了两个restful风格的接口进行数据交互,具体实现如下:
文件上传采用了分步上传,首先将文件以MultipartFile上传到系统部署平台(或文件服务器)下的一个文件夹,并获取到文件在部署平台下的路径,然后将文件上传到hdfs
首先编写了json返回对象
private Double goodCount;//好评数
private Double badCount;//差评数
private Double correct;//正确率
private List<PredictResult> predictResults;//评价词组
PredictResult:
private String lineNum;//行号
private String pResult;//预测结果
private String tResult;//实际结果