首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

基于 Spark 的文本情感分析-3

基于 Spark 的文本情感分析-3

训练分类模型在这一小节中,本文介绍如何用 Spark 训练朴素贝叶斯分类模型,这一流程的输入是文本的特征向量及已经标记好的分类标签。在这里本文得到的是分类模型及文本分类的正确率。
现在,有了文本的特征项及特征值,也有了分类标签,需要用 RDD 的 zip 算子将这两部分数据连接起来,并将其转化为分类模型里的 LabeledPoint 类型。并随机将数据分为训练集和测试集,60%作为训练集,40%作为测试集。
清单 9. 生成训练集和测试集
1
2
3
zipped=rate.zip(tfidf)
data=zipped.map(lambda lineabeledPoint(line[0],line[1]))
training, test = data.randomSplit([0.6, 0.4], seed = 0)




本文用训练数据来训练贝叶斯模型,得到 NBmodel 模型来预测测试集的文本特征向量,并且计算出各个模型的正确率,这个模型的正确率为 74.83%。
清单 10. 训练贝叶斯分类模型
1
2
3
4
NBmodel = NaiveBayes.train(training, 1.0)
predictionAndLabel = test.map(lambda p : (NBmodel.predict(p.features), p.label))
accuracy = 1.0 * predictionAndLabel.filter(lambda x: 1.0 \
if x[0] == x[1] else 0.0).count() / test.count()




可以看出贝叶斯模型最后的预测模型并不高,但是基于本文采集的数据资源有限,特征提取过程比较简单直接。所以还有很大的优化空间,在第四章中,本文将介绍提高正确率的方法。
分类未标记文档现在可以用本文训练好的模型来对未标记文本分类,流程是获取用户输入的评论,然后将输入的评论文本分词并转化成 tf-idf 特征向量,然后用 3.4 节中训练好的分类模型来分类。
清单 11. 分类未分类文本
1
2
3
4
5
yourDocument=input("输入待分类的评论:")
yourwords="/".join(jieba.cut_for_search(yourDocument)).split("/")
yourtf = hashingTF.transform(yourwords)
yourtfidf=idfModel.transform(yourtf)
print('NaiveBayes Model Predict:',NBmodel.predict(yourtfidf),'




当程序输入待分类的评论:“这部电影没有意思,剧情老套,真没劲, 后悔来看了”
程序输出为“NaiveBayes Model Predict: 0.0”。
当程序输入待分类的评论:“太精彩了讲了一个关于梦想的故事剧情很反转制作也很精良”
程序输出为“NaiveBayes Model Predict: 1.0”。
至此,最为简单的文本情感分类系统就构建完整了。
提高正确率的方法在第三章中,本文介绍了构建文本分类系统的方法,但是正确率只有 74.83%,在这一章中,本文将讲述文本分类正确率低的原因及改进方法。
文本分类正确率低的原因主要有:
  • 文本预处理比较粗糙,可以进一步处理,比如去掉停用词,去掉低频词;
  • 特征词抽取信息太少,搜索引擎模式的分词模式不如全分词模式提供的特征项多;
  • 朴素贝叶斯模型比较简单,可以用其他更为先进的模型算法,如 SVM;
  • 数据资源太少,本文只能利用了好评、坏评论各 2238 条。数据量太少,由于爬虫爬取的数据,没有进行人工的进一步的筛选,数据质量也得不到 100%的保证。
下面分别就这四个方面,本文进一步深入的进行处理,对模型进行优化。
数据预处理中去掉停用词停用词是指出现在所有文档中很多次的常用词,比如“的”、“了”、“是”等,可以在提取特征的时候将这些噪声去掉。
首先需要统计一下词频,看哪些词是使用最多的,然后定义一个停用词表,在构建向量前,将这些词去掉。本文先进行词频统计,查看最常用的词是哪些。
清单 12. 统计词频
1
2
3
4
5
text=words.flatMap(lambda w:w)
wordCounts = text.map(lambda word: (word, 1))\
.reduceByKey(lambda a, b: a+b).\
sortBy(lambda x: x[1],ascending=False)
wordCounts.take(10)




通过观察,选择出现次数比较多,但是对于文本情感表达没有意义的词,作为停用词,构建停用词表。然后定义一个过滤函数,如果该词在停用词表中那么需要将这个词过滤掉。
清单 13. 去掉停用词
stopwords = set([" ","的","了","是","就","吧",……])
1
2
3
4
5
6
def filterStopWords(line):
for i in line:
if i in stopwords:
line.remove(i)
return line
words=words.map(lambda w : filterStopWords(w))

返回列表