【snownlp源代码系列】之情感分类朴素贝叶斯原理

聊一聊snownlp源代码中的朴素贝叶斯分类原理

    • 一、情感分析任务
    • 二、分类原理
    • 三、snownlp源码解析
    • 四、致谢:

建议拿出小本本,写写画画便于理解

一、情感分析任务

简单来说,给一句话,运用情感分析,判断这句话是积极态度亦或是消极态度,并给出态度的度。(入门阶段我就不研究太高深的啦~)

那么要怎么完成这个任务呢?可以分为一下几个阶段(措辞不够专业,主要是为了简单易懂):

  1. 训练词典传送门
  2. 样本分词传送门
  3. 结果分类

前面两项另写了文章,本篇主要讲结果分类

二、分类原理

首先理解一下贝叶斯分类原理,下面根据该原理做情感分类。

现假设:
所有的句子可以分类两类:积极态度(c1)、消极态度(c2).
一个句子有特征w1,w2,...,wn,这n个特征相互独立.
对于情感分类任务中特征w1,w2,...,wn分别代表该句子中对应的单词
由朴素贝叶斯分类器原理P(c1|w1,w2,…,wn) = (P(w1,w2,…,wn|ci) × P(ci)) / (P(w1,w2,…,wn))
具有w1,w2,…,wn特征的句子属于ci类的概率 = 【1】 / 【2】
【1】= 如果句子是类ci,那么该句子具有w1,w2,…,wn特征的概率 × 句子是类c1的概率
【2】 = 句子具有w1,w2,…,wn特征的概率
而由全概率公式P(B) = P(B|A)P(A) + P(B|A’)P(A’)
句子具有w1,w2,…,wn特征的概率 = 【3】 + 【4】
【3】 = 如果句子是c1类,那么该句子具有w1,w2,…,wn特征的概率 × 句子是类c1的概率
【4】 = 如果句子是c2类,那么该句子具有w1,w2,…,wn特征的概率 × 句子是类c2的概率
综上
具有w1,w2,…,wn特征的句子属于ci类的概率 = 【1】 / (【3】 + 【4】)
将上述讲解转换成公式
P(c1|w1,w2,…,wn) = [P(w1,w2,…,wn|c1) × P(c1)] / [P(w1,w2,…,wn|c1) × P(c1) + P(w1,w2,…,wn|c2) × P(c2) ]
对公式化简 参考
【snownlp源代码系列】之情感分类朴素贝叶斯原理_第1张图片

三、snownlp源码解析

首先回忆一下Bayes类的各个属性:

  • class Bayes
    • self.d = {}
      • 1.key : pos/neg标签,即只有两个键
      • 2.value : pos/neg标签分别对应的积极/消极单词列表
    • self.total = 0
      • 1.值为所有分类的词的数量之和,即所有单词数
# 该段代码取自snownlp/classification/bayes.py
# 参数x:测试文本去掉停用词之后的单词列表,是一个list类型的数据,每一个元素都是一个单词
def classify(self, x):
	# 下面这些为字典库相关计算
    tmp = {} # 使用字典完成打表 key:pos/neg ; value:该单词出现的次频的log值
    # self.d 取值为pos或者neg
    for k in self.d: 
    	# 分别计算积极类和消极类的词数总数的log值 - 总词数的log值
        tmp[k] = log(self.d[k].getsum()) - log(self.total)
        for word in x: # 对输入文本的每个非停用词
        	# pos/neg出现词频 加上 输入文本中各个单词在积极/消极词典中词频的log值
            tmp[k] += log(self.d[k].freq(word))
    # 以上为字典库相关计算
    
    # 下面是统计相关计算
    ret, prob = 0, 0 # ret:句子的分类pos/neg , pro:句子的情感极性
    # self.d 取值为pos或者neg
    for k in self.d: # 分别计算积极类/消极类 对应的概率
        now = 0 # 表示如果具有输入文本句子中各个单词特征,那么该句子是输入 k 类的概率
        try: # 下面的计算是真正的朴素贝叶斯公式
            for otherk in self.d:
                now += exp(tmp[otherk]-tmp[k]) # 朴素贝叶斯二分类公式中的分母
            now = 1/now # 取倒数
        except OverflowError:
            now = 0 # 词频为0,则取0
        if now > prob: # 若本次计算出的概率 > 原先概率,则词性ret = k, 概率 = now
            ret, prob = k, now
    return (ret, prob)
    # 返回 ret:'neg/pos' prob:句子的情感极性
  • tips : 朴素贝叶斯在平时使用中,会做一些优化,例如:取对数。
  • 以上程序所用公式是朴素贝叶斯公式的化简版

小傲娇脸:

# 以下是运用snownlp源码做的一个情感分类调用的代码
from snownlp1 import sentiment

text = '我喜欢你,你真是我的骄傲,天高水阔,走马观花,遇见你是我一生最大的幸运'

print(sentiment.classifier.handle(text))
print(sentiment.classify(text))

'''
输出如下:
['喜欢', '骄傲', '天高', '水阔', '走马', '观', '花', '遇见', '一生', '最', '大', '幸运']
0.9999626199601812
'''

四、致谢:

snownlp github
情感分析——深入snownlp原理和实践
简单易学的机器学习算法——朴素贝叶斯
NLP系列(3)_用朴素贝叶斯进行文本分类(下)


本人理解源代码能力有限,如有失误,还望提点!
如有侵权,我会在第一时间删掉该文章,还望指出和原谅!

你可能感兴趣的:(自然语言处理)