自然语言处理 - 朴素贝叶斯

https://wizardforcel.gitbooks.io/dm-algo-top10/content/naive-bayes.html

朴素贝叶斯为何朴素:
因为引入条件独立假设,特征的顺序变得无关紧要,所有优点naive。在自然语言处理中,另外一种说法叫做“词袋模型”。

特征预处理:
1. 分词
2. 消除停用词
3. 消除特殊字符

sklearn钟的朴素贝叶斯:
1. MultinomialNB: 多项式朴素贝叶斯 (常用)
2. BernoulliNB: 倍努力朴素贝叶斯(常用)
3. GaussianNB: 高斯朴素贝叶斯(服从正态分布的连续变量)

平滑技术:
在小数据集中,通常会出现某些词汇0频率的现象,这样概率计算值为0,没有意义。
采用平滑方法进行处理:
倍努力模型:分子+1, 分母+2
多项式模型:分子+1,分母+词表大小

原始关键词法 vs 朴素贝叶斯法:
贝叶斯效率高,准确率高。
原始关键词法容易被反攻。

常见的工程优化手段:
1.训练阶段-对数运算-hash方法,提高预测阶段效率
2.二分问题-训练阶段-赋值权重-hash方法,提高预测阶段效率
3.二分为题-训练阶段-赋值权重-topK权重-hash方法-设定阈值,进一步提高效率
4.topK方法下优化
      a.对于长篇幅,进行分段
      b.对于短篇幅,调整关键词数量和阈值高低
5. 位置权重:额外添加位置权重,提高预测精度
6. 蜜罐:设置限制邮箱-手机垃圾邮件-数据收集工作

朴素贝叶斯如何处理不均衡标签的问题?
本质上是样本中的先验概率出现差异:
如果确信在总体中先验概率是均衡的,则依然使用最大似染法
如果使用最大似然法依然会有偏差,则调整系数或者阈值。

贝叶斯实现代码python

import numpy as np 
import math
# 使用词集法进行贝叶斯分类
# 构造数据集,分类是侮辱性 or 非侮辱性
def loadDataset () :
    postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
                 ['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
                 ['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
                 ['stop', 'posting', 'stupid', 'worthless', 'garbage'],
                 ['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
                 ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    classVec = [0,1,0,1,0,1]    #1 is abusive, 0 not
    return postingList, classVec


# 创建一个包涵所有词汇的列表 , 为后面建立词条向量使用
def createlist (dataset) :
    vovabset = set ([])
    for vec in dataset :
        vovabset = vovabset | set (vec)
    return list (vovabset)

# 将词条转化为向量的形式
def changeword2vec (inputdata, wordlist) :
    returnVec = [0] * len (wordlist)
    for word in inputdata :
        if word in wordlist :
            returnVec[wordlist.index(word)] = 1
    return returnVec

# 创建贝叶斯分类器 
def trainNBO (dataset, classlebels) :
    num_of_sample = len (dataset)
    num_of_feature = len (dataset[0])
    pAusuive = sum (classlebels) / num_of_sample # 侮辱性语言的概率
    p0Num = np.ones (num_of_feature)
    p1Num = np.ones (num_of_feature)
    p0tot = num_of_feature
    p1tot = num_of_feature
    for i in range (num_of_sample) :
        if classlebels[i] == 1 :
            p1Num += dataset[i]
            p1tot += sum (dataset[i])
        else :
            p0Num += dataset[i]
            p0tot += sum (dataset[i])   
    p0Vec = p0Num / p0tot
    p1Vec = p1Num / p1tot
    for i in range (num_of_feature) :
        p0Vec[i] = math.log (p0Vec[i])
        p1Vec[i] = math.log (p1Vec[i])
    return p0Vec, p1Vec, pAusuive


#  定义分类器 
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)    #element-wise mult
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else: 
        return 0

# 测试代码 
dataset,classlebels = loadDataset ()
wordlist = createlist (dataset)
print (wordlist)
print (changeword2vec (dataset[0], wordlist))
trainmat = []
for temp in dataset :
    trainmat.append (changeword2vec (temp,wordlist))
p0V, p1V, pAb = trainNBO (trainmat, classlebels)
print (p0V)
print (p1V)
print (pAb)

参考: https://blog.csdn.net/zhelong3205/article/details/78659169

你可能感兴趣的:(NLP)