朴素贝叶斯(Naïve Bayes)
- 属性独立性是Naïve Bayes的前提也是关键
- 思想:通俗地说,就是根据已有的数据集,得到先验概率和各种属性对于各种决策的条件概率(可以理解为每种属性对每种决策的影响的大小);面对新的场景,对于每一种决策结果,进行一串连乘,推选出概率最高者为最终决策。
- 贝叶斯方法的特点是结合先验概率和后验概率,即避免了只使用先验概率的主观偏见,也避免了单独使用样本信息的过拟合现象
最大熵(Maximum Entropy)
- 信息量与信息熵(Shannon entropy)
- 熵表示混乱程度。符号集={A,A,A,A,A,B,B,B},熵= − ( 5 / 8 ∗ l o g 2 ( 5 / 8 ) + 3 / 8 ∗ l o g 2 ( 3 / 8 ) ) = 0.9544 -(5/8*log2(5/8)+3/8*log2(3/8))=0.9544 −(5/8∗log2(5/8)+3/8∗log2(3/8))=0.9544
- 思想:对于未知的推测应该选取熵值最大的概率分布,即最随机的分布,从而使未知事件的分布尽可能均匀。
决策树(Decision Tree)
- 决策树是基于概率的,或者说就是基于熵的
- 思想:我们会事先给出一个熵值,当子集的熵大于该值时,会被进一步分解出树枝,直到熵值沉寂到事先给出的预期
- 另外,树的深度也作为参数被控制,这与训练时间成正比,与精度成反比——这很好理解
- 决策树是极其直观的预测模型
基于nltk实现三种分类器(实现对影评的情感倾向预测)
▶ 文本处理
from nltk.corpus import movie_reviews
# ([...], pos)
# ([...], neg)
documents = [(list(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]
# 将documents「随机化」,为组成训练集和测试集作准备
import random
random.shuffle(documents)
# 挑出词频最高的2000个词,作为「特征词」 (去掉停词,去掉标点符号,其实还剩大概1800个词)
import nltk
from nltk.corpus import stopwords
import string
word_fd = nltk.FreqDist(w.lower() for w in movie_reviews.words()).most_common(2000) # 词频最高的前2000个(词+频度)
feature_words = [w for (w, _) in word_fd if w not in stopwords.words("english") and w not in string.punctuation] # 处理后最终的特征词列表
# 对于每一个document词列表,检查每一个「特征词」的有无(true/false),以此作为「特征」并返回
# 格式: {}
def get_document_feature(document):
document_words = set(document)
feature = {}
for word in feature_words:
feature['contains({})'.format(word)] = (word in document_words)
return feature
# 划分「训练集」和「测试集」
feature_set =[(get_document_feature(d), c) for (d, c) in documents]
train_set = feature_set[100:]
test_set = feature_set[:100]
▶ 训练与测试
classifier = nltk.NaiveBayesClassifier.train(train_set)
# classifier = nltk.MaxentClassifier.train(train_set)
# classifier = nltk.DecisionTreeClassifier.train(train_set)
print('朴素贝叶斯(NaiveBayesClassifier)的测试集正确率: ', nltk.classify.accuracy(classifier, test_set))
text = input('请输入影评文本(一句话也行>_<): ')
print('情感分析结果为(pos/neg): ', classifier.classify(get_document_feature(text.split(' '))))
# 注意get_document_feature的参数需要是个词列表哦!因此需要提前分词,这里使用了最偷工减料的text.split(' ')
笔者注
- 文本处理是最难理解的部分,一定要转变过来思维——不是将每个document(文本)中的词列表本身作为特征,而是事先规定一些特征词,用这些特征词去试探它们在document中是否存在,将存在与否作为特征——也就是说,事先规定了多少特征词,这个文本的特征就有多少个
- 第二点,就是彻底理解上面第一点 !
- 在使用朴素贝叶斯或决策树时,对每个文本用了1800多个特征词进行分析;而使用最大熵时,emmm用180个最好,否则会因为计算量过大而超时报错