机器学习——基于概率论的分类方法:朴素贝叶斯

朴素贝叶斯(naive Bayes)算法是基于贝叶斯定理与特征条件独立假设的分类方法,对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布,然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y,朴素贝叶斯法实现简单,学习与预测的效率都很高,是一种常见的方法。

朴素贝叶斯(naive Bayes)算法是有监督的学习算法,解决的是分类问题,如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但由于该算法以自变量之间的独立(条件特征独立)性和连续变量的正态性假设为前提,就会导致算法精度在某种程度上受影响。

1.基于贝叶斯决策理论的分类方法
用p1(x,y)表示数据点(x,y)属于类别1的概率
p1(x,y表示数据点(x,y)属于类别0的概率
如果p1(x,y)> p0(x,y) ,那么为类别1
如果p1(x,y)< p0(x,y) ,那么为类别0
即选择高概率类别,这就是贝叶斯决策理论的核心思想
利用贝叶斯准则:
如果p(c1|x,y) > p(c0|x,y) ,那么属于类别1
如果p(c1|x,y) < p(c0|x,y) ,那么属于类别0

  • 优点:在数据较少的情况下仍然有效,可以处理多类别问题
  • 缺点:对于输入数据的准备方式较为敏感
  • 适用数据类型:标称型数据

2.2.1条件概率
条件概率:
P(gray|bucketB) = P(gray and bucketB)/P(bucketB)
贝叶斯准则(交换条件概率中的条件与结果):
p(a|x) = p(x|a) p(a) / p(x)
2.2.2全概率公式
除了条件概率以外,在计算p1和p2的时候,还要用到全概率公式,因此,这里继续推导全概率公式。
P(B)=P(B⋂A)+P(B⋂A′)P(B)=P(B⋂A)+P(B⋂A′)

已知:
P(B⋂A)=+P(B|A)P(A)P(B⋂A)=+P(B|A)P(A)

故全概率公式为:
P(B)=P(B|A)P(A)+P(B|A′)P(A′)P(B)=P(B|A)P(A)+P(B|A′)P(A′)
其含义为:如果AA和A′A′构成一个样本空间的一个划分,那么事件BB的概率就等于AA和A′A′的概率分别乘以BB对这两个事件的条件概率之和。

于是条件概率就有了另一种写法:
P(A|B)=P(B|A)P(A)P(B|A)P(A)+P(B|A′)P(A′)

3.使用python进行文本分类

要从文本中获取特征:(1)拆分文本;(2)一个文本片段——>一个词条向量,1表示词条出现在文档中,0表示未出现。
例:社区留言板屏蔽侮辱性言论
构建快速过滤器:留言使用了负面或者侮辱性语言——>标识为内容不当。
类别:侮辱类和非侮辱类(用1和0分别表示)
准备数据:从文本中构建词向量
将句子转换为向量:(1)考虑所有文档中出现的所有单词;(2)决定将哪些词纳入词汇表;(3)将每一篇文档转换为词汇表上的向量。

##词表到向量的转换函数
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 代表侮辱性文字,0代表正常言论
    return postingList, classVec #返回词条集合和类别标签集合

#创建一个包含在所有文档中出现的不重复词的列表
def createVocabList(dataSet):
    vocabSet = set([]) #创建一个空集,set()会返回一个不重复词表
    for document in dataSet:
        vocabSet = vocabSet | set(document) #创建两个集合的并集
    return list(vocabSet)

def setOfWords2Vec(vocabList, inputSet): #输入参数(词汇表,某文档)
    returnVec = [0]*len(vocabList)  #创建一个其中所含元素都为0的向量
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
        else:
            print("the word: %s is not in my Vocabulary!" % word)
    return returnVec #0和1分别表示词汇表的单词在文档中未出现和出现
 
def main():
    listOPosts, listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    print(myVocabList)
    print(setOfWords2Vec(myVocabList, listOPosts[0]))
    print(setOfWords2Vec(myVocabList, listOPosts[2]))

if __name__ == "__main__":
    main()

运行结果

>>>['is', 'please', 'problems', 'maybe', 'garbage', 'quit', 'mr', 'dalmation', 'posting', 'my', 'him', 'worthless', 'not', 'buying', 'to', 'help', 'steak', 'stop', 'has', 'take', 'ate', 'dog', 'love', 'how', 'I', 'flea', 'so', 'licks', 'stupid', 'food', 'cute', 'park']
[0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
[1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0]

检查上述词表,确认没有重复出现的单词(注:目前该词表还没有排序)。
标签序列分别代表了单词表中的词在第一句话和第三句话中是否出现。
训练算法:从词向量计算概率
现在已经知道一个词是否出现在一篇文档中,也知道该文档所属的类别。
现在我们重写贝叶斯准则,将之前的x、y替换为w,粗体w表示这是一个向量,即它由多个数值组成:
p(ai | w) = p(w | ai) p(ai)/p(w)
函数的伪代码如下:

计算每个类别中的文档数目
对每篇训练文档:
    对每个类别:
    	如果词条出现文档中——>增加该词条的计数值
    	增加所有词条的计数值
    对每个类别:
    	对每个词条:
    		将该词条的数目除以总词条数目得到条件概率
    返回每个类别的条件概率

测试算法:根据现实情况修改分类器
利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算p(w0|1)p(w1|1)p(w2|1)。如果其中一个概率值为0,那么最后乘积也为0。为降低这种影响,可以将所有词的出现次数初始化为1,并将分母初始化为2。
准备数据:文档词袋模型
词集模型:将每个词的出现与否作为一个特征。
词袋模型:如果一个词在文档中出现不止一次,这可能意味着包含该词是否出现在文档中所不能表达的某种信息。
在词袋中,每个单词可以出现多次,而在词集中,每个词只能出现一次。
为适应词袋模型,需要对函数setOfWords2Vec()稍加修改,将修改后的函数称为bagOfWords2Vec(),唯一的不同就是每当遇到一个单词时,它会增加词向量中的对应值,而不只是将对应的数值设为1。

def bagOfWords2VecMN(vocabList, inputSet): #输入参数(词汇表,某文档)
    returnVec = [0]*len(vocabList)  #创建一个其中所含元素都为0的向量
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] += 1
    return returnVec #统计每个单词出现的次数

总结:贝叶斯概率及贝叶斯准则提供了一种利用已知值来估计未知概率的有效方法,可以通过特征之间的条件独立性假设,降低对数据量的需求。朴素贝叶斯是一种有效的分类器。

你可能感兴趣的:(机器学习,分类,概率论)