# 朴素贝叶斯—豆瓣Top250影评的情感分析与预测
### 前言
[原文](https://juejin.cn/post/6844903941226921991)
本文使用朴素贝叶斯算法实现 豆瓣Top250电影评价的情感分析与预测。
最近在学习自然语言正负面情感的处理问题,但是绝大部分能搜索到的实践都是Kggle上IMDB影评的情感分析。
所以在这里我就用最基础的朴素贝叶斯算法来对豆瓣的影评进行情感分析与预测。
在这里我参考了 [github.com/aeternae/IM…](https://github.com/aeternae/IMDb_Review),万分感谢。
## 朴素贝叶斯分类器
贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。
这种算法常用来做文章分类,垃圾邮、件垃圾评论分类,朴素贝叶斯的效果不错并且成本很低。
已知某条件概率,如何得到两个事件交换后的概率,也就是在已知P(A|B)的情况下如何求得P(B|A)。
P(B|A)表示事件A已经发生的前提下,事件B发生的概率,叫做事件A发生下事件B的条件概率。
**朴素贝叶斯的公式**
$$
P(B|A) = \frac{P(A|B)P(B)}{P(A)}
$$
一个通俗易懂的视频教程
Youtube [www.youtube.com/watch?v=Aqo…](https://www.youtube.com/watch?v=AqonCeZUcC4)
**举个不太恰当的例子**
我们想知道做程序员与秃头之间的关系,我们就可以用朴素贝叶斯公式来进行计算。
我们现在想求 **P(秃头|做程序员)** 的概率, 也就是**做程序员就会秃头的概率**
我这辈子都不会秃头 (((o(*▽*)o))) !!!
代入朴素贝叶斯公式
$$
P(秃头|做程序员) = \frac{P(做程序员|秃头)P(秃头)}{P(做程序员)}
$$
已知数据如下表
| 姓名 | 职业 | 是否秃头 |
| ------------- | ---------- | -------- |
| 奎托斯 | 战神 | 是 |
| 杀手47号 | 杀手 | 是 |
| 埼玉 | 超人 | 是 |
| 灭霸 | 计生办主任 | 是 |
| 杰森 斯坦森 | 硬汉 | 是 |
| 某某996程序员 | 程序员 | 是 |
| 我 | 程序员 | 否 |
基于朴素贝叶斯公式,由以上这张表我们可以求出:
$$
P(秃头|做程序员) = \frac{\frac16 * \frac67}{\frac27} = \frac{21}{42} = \frac{1}{2}
$$
上面这个例子就简单的描述了朴素贝叶斯公式的基本用法。
接下来我就使用豆瓣Top250排行榜的影评来使用朴素贝叶斯进行好评与差评的训练与预测。
## 豆瓣Top250影评情感分析
首先需要豆瓣Top250影评的语料,我用Scrapy抓取了5w份语料,用于训练与验证。
豆瓣影评爬虫 [github.com/3inchtime/d…](https://github.com/3inchtime/douban_movie_review)
有了语料之后我们就可以开始实际开发了。
这里建议使用jupyter来开发操作。
**首先加载语料**
```python
# -*- coding: utf-8 -*-
import random
import numpy as np
import csv
import jieba
file_path = './data/review.csv'
jieba.load_userdict('./data/userdict.txt')
# 读取保存为csv格式的语料
def load_corpus(corpus_path):
with open(corpus_path, 'r') as f:
reader = csv.reader(f)
rows = [row for row in reader]
review_data = np.array(rows).tolist()
random.shuffle(review_data)
review_list = []
sentiment_list = []
for words in review_data:
review_list.append(words[1])
sentiment_list.append(words[0])
return review_list, sentiment_list
```
在训练之前,一般均会对数据集做shuffle,打乱数据之间的顺序,让数据随机化,这样可以避免过拟合。所以使用`random.shuffle()`方法打乱数据。
`jieba.load_userdict('./data/userdict.txt')`这里我自己做了一个词典,防止部分结巴分词的不准确,可以提高约1%左右的准确率。
比如**不是很喜欢**这句,jieba会分成’不是‘,’很喜欢‘两个词,这样导致这句话很大概率会被预测为好评。
所以这里我在自定义的词典中分好了很多类似这样的词,提高了一点点准确率。
然后将全部的语料按1:4分为测试集与训练集
```python
n = len(review_list) // 5
train_review_list, train_sentiment_list = review_list[n:], sentiment_list[n:]
test_review_list, test_sentiment_list = review_list[:n], sentiment_list[:n]
```
**分词**
使用jieba分词,将语料进行分词,并且去除stopwords。
```python
import re
import jieba
stopword_path = './data/stopwords.txt'
def load_stopwords(file_path):
stop_words = []
with open(file_path, encoding='UTF-8') as words:
stop_words.extend([i.strip() for i in words.readlines()])
return stop_words
def review_to_text(review):
stop_words = load_stopwords(stopword_path)
# 去除英文
review = re.sub("[^\u4e00-\u9fa5^a-z^A-Z]", '', review)
review = jieba.cut(review)
# 去掉停用词
if stop_words:
all_stop_words = set(stop_words)
words = [w for w in review if w not in all_stop_words]
return words
# 用于训练的评论
review_train = [' '.join(review_to_text(review)) for review in train_review_list]
# 对于训练评论对应的好评/差评
sentiment_train = train_sentiment_list
# 用于测试的评论
review_test = [' '.join(review_to_text(review)) for review in test_review_list]
# 对于测试评论对应的好评/差评
sentiment_test = test_sentiment_list
```
**TF\*IDF与词频向量化**
TF-IDF(是一种常用于信息处理和数据挖掘的加权技术。根据词语的在文本中出现的次数和在整个语料中出现的文档频率来计算一个词语在整个语料中的重要程度。
它的优点是能过滤掉一些常见的却无关紧要本的词语,同时保留影响整个文本的重要字词。
使用`Countvectorizer()`将一个文档转换为向量,计算词汇在文本中出现的频率。
`CountVectorizer`类会将文本中的词语转换为词频矩阵,例如矩阵中包含一个元素a[i] [j],它表示j词在i类文本下的词频。它通过fit_transform函数计算各个词语出现的次数。
TfidfTransformer用于统计vectorizer中每个词语的TF-IDF值。
```python
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.pipeline import Pipeline
from sklearn.naive_bayes import MultinomialNB
count_vec = CountVectorizer(max_df=0.8, min_df=3)
tfidf_vec = TfidfVectorizer()
# 定义Pipeline对全部步骤的流式化封装和管理,可以很方便地使参数集在新数据集(比如测试集)上被重复使用。
def MNB_Classifier():
return Pipeline([
('count_vec', CountVectorizer()),
('mnb', MultinomialNB())
])
```
`max_df` 这个参数的作用是作为一个阈值,当构造语料库的关键词集的时候,如果某个词的词频大于`max_df`,这个词不会被当作关键词。
如果这个参数是float,则表示词出现的次数与语料库文档数的百分比,如果是int,则表示词出现的次数。
`min_df`类似于`max_df`,不同之处在于如果某个词的词频小于`min_df`,则这个词不会被当作关键词
这样我们就成功的构造出了用于训练以及测试的Pipeline
然后用 **Pipeline.fit**()对训练集进行训练
再直接用 **Pipeline.score()** 对测试集进行预测并评分
```python
mnbc_clf = MNB_Classifier()
# 进行训练
mnbc_clf.fit(review_train, sentiment_train)
# 测试集准确率
print('测试集准确率: {}'.format(mnbc_clf.score(review_test, sentiment_test)))
```
这样我们就完成了整个从训练到测试的全部流程。
基本上测试集的正确率在79%-80%左右。
因为电影评论中有很大一部分好评中会有负面情感的词语,例如在纪录片《海豚湾》中
> 我觉得大部分看本片会有感的人,都不知道,中国的白暨豚已经灭绝8年了,也不会知道,长江里的江豚也
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
基于朴素贝叶斯的豆瓣Top250影评的情感分析与预测 附完整源码和数据.zip 首先需要豆瓣Top250影评的语料,我用Scrapy抓取了5w份语料,用于训练与验证。 豆瓣影评爬虫 github.com/3inchtime/d… 有了语料之后我们就可以开始实际开发了。 这里建议使用jupyter来开发操作。 首先加载语料 # -*- coding: utf-8 -*- import random import numpy as np import csv import jieba file_path = './data/review.csv' jieba.load_userdict('./data/userdict.txt') # 读取保存为csv格式的语料 def load_corpus(corpus_path): with open(corpus_path, 'r') as f: reader = csv.reader(f) rows = [row for row in reader] review
资源推荐
资源详情
资源评论
收起资源包目录
基于朴素贝叶斯的豆瓣Top250影评的情感分析与预测 附完整源码和数据.zip (11个子文件)
doubansentimentanalysis
native_bayes.ipynb 5KB
native_bayes_test.py 3KB
data
review.csv 7.07MB
userdict.txt 703B
stopwords.txt 9KB
LICENSE 1KB
native_bayes_train.py 2KB
run_test.py 661B
.gitignore 1KB
README.md 12KB
native_bayes_sentiment_analyzer.py 2KB
共 11 条
- 1
甜辣uu
- 粉丝: 8383
- 资源: 1103
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
- 1
- 2
- 3
前往页