美文网首页
机器学习_统计模型之(三)朴素贝叶斯

机器学习_统计模型之(三)朴素贝叶斯

作者: xieyan0811 | 来源:发表于2017-11-24 15:03 被阅读162次

    1. 条件独立假设

     条件独立假设简单的说就是特征x1和x2没有关系,比如说兔子的特征中,尾巴短和爱吃萝卜这两个特征它们分别和兔子相关,但两特征彼此之间无关,不是说尾巴短的都爱吃萝卜。所以有p(x2|x1)=p(x2),即无论x1是什么,x2的概率都不变。朴素贝叶斯就是以条件独立假设为基础的。

    2. 概率的乘法

     两个独立事件都发生的联合概率等于两个事件发生概率的乘积。
     当P(A)与P(B)无关时,P(B)=P(B|A),所以P(A,B)=P(A)|P(B|A)=P(A)P(B)
    比如:目标是判断该动物是不是兔子,有三个属性:长耳朵P(A)=70%,短尾巴P(B)=50%,爱吃萝卜P(C)=60%,当三个条件都为真时:
     P(A,B,C)=P(A)P(B)P(C)=70%50%60%=21%,奇怪,三个条件都为真,结果概率却小了?概率小不小主要看跟谁比,再看看三个条件都不成立时:
    (1-P(A))(1-P(B))(1-P(C))=30%50%40%=6%,对比这两个值21:6,就能判断它是一只兔子了。

    3. 朴素贝叶斯

     朴素贝叶斯(Naive Bayesian) 是贝叶斯分类器中应用最为广泛的算法之一, 之所以称为”朴素”是因为它有两个假设:特征之间相互独立,每个特征同等重要。
     完整公式是:

     前文说过它是贝叶斯网络的特殊情况:即网络中无边,各个节点都是独立的。

     它的优点是:对缺失数据不太敏感,算法也比较简单,结果比较直观。而缺点是:基于假设属性之间相互独立,这个假设在实际应用中往往是不成立的,容易产生高度相关特征的双重计数.赋于更高的比重。所以我们尽量在数据降维(去相关性)之后,再使用它。

    4. 例程

    (1) 功能

     通过训练判断句子的感情色彩

    (2) 代码

    # -*- coding: utf-8 -*-
    
    from numpy import *
    
    # 训练数据
    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 createVocabList(dataSet):
        vocabSet = set([])
        for document in dataSet:
            vocabSet = vocabSet | set(document)
        return list(vocabSet)
    
    # 用词汇列表将训练集中的词转换成:句中存在为1,不存在为0
    def setOfWords2Vec(vocabList, inputSet):
        returnVec = [0]*len(vocabList)
        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
    
    # 训练
    def trainNB0(trainMatrix, trainCategory):
        numTrainDocs = len(trainMatrix) # 矩阵的行数
        numWords = len(trainMatrix[0]) # 矩阵的列数
        pAbusive = sum(trainCategory)/float(numTrainDocs) # 正例在总数中占比
        p0Num = ones(numWords); p1Num = ones(numWords) # p0Num是一个数组,大小是所有不重词数
        p0Denom = 2.0; p1Denom = 2.0
        for i in range(numTrainDocs): # 按每句遍历
            if trainCategory[i] == 1:
                p1Num += trainMatrix[i] # 数组按每个值相加
                p1Denom += sum(trainMatrix[i]) # 句子所有词个数相加
            else:
                p0Num += trainMatrix[i]
                p0Denom += sum(trainMatrix[i])
        p1Vect = log(p1Num/p1Denom) # 数组除以数,正例时,每个词出现概率
        p0Vect = log(p0Num/p0Denom)
        return p0Vect, p1Vect, pAbusive # 条件概率
    
    # 分类
    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
    
    if __name__ == '__main__':
        listOPosts,listClasses = loadDataSet()
        myVocabList = createVocabList(listOPosts)
        trainMat=[]
        for postinDoc in listOPosts:
            trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
        p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
        testEntry = ['love', 'my', 'dalmation']
        thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
        print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
        testEntry = ['stupid', 'garbage']
        thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
        print(testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb))
    

    (3) 运行结果

    (['love', 'my', 'dalmation'], 'classified as: ', 0)
    (['stupid', 'garbage'], 'classified as: ', 1)
    

    3. sklearn中的工具

     上例只为说明原理,一般使用朴素贝叶斯的时候都是调库,sklearn中提供以下常用工具:
     GaussianNB:先验为高斯分布的朴素贝叶斯,用于连续型变量。
     MultinomialNB:先验为多项式分布的朴素贝叶斯,多用于文本分类,统计出现次数。partial_fit()方法可以进行多次训练。
     BernoulliNB:先验为伯努利分布(二值分布)的朴素贝叶斯,变量是布尔型的。

    4. 用途

     朴素贝叶斯常用于信息检索,文本分类,识别垃圾邮件等领域。

    5. 一些想法

     说一些自己的想法,也不一定对。
     简单地说朴素贝叶斯就是按概率求合,然后比一下是正例的概率大还是反例的概率大。
     从贝叶斯网络的角度看,条件独立性去掉了网络中所有的依赖连接,把网络结构简化成了单层,是一个非常简单的模型,就像线性拟合似的,所以外理不了一个场景里的多种模式,如需处理,只能用集成模型组合多个简单模型。直觉上,朴素贝叶斯更适合数据多,属性多,分层少的应用。说它经典不是因为它功能强,而是因为其它足够简单和基础,可以作为组合的基本单元。
     它有一种用法是处理稀疏的特征,比如说用它处理文本,需要先去掉停用词(有点像减掉均值),否则有意义的信息会被巨量的无意义信息吞没。
     朴素贝叶斯也并不一定用于分类或回归,也可用于分析导致结果的重要条件,比如分别给正反例中的出现的属性按频率排序。间接地提炼有意义的特征,有点像从常识中把反常的点挑出来。

    相关文章

      网友评论

          本文标题:机器学习_统计模型之(三)朴素贝叶斯

          本文链接:https://www.haomeiwen.com/subject/nuffbxtx.html