其他分享
首页 > 其他分享> > 贝叶斯分类详解,从条件概率说起

贝叶斯分类详解,从条件概率说起

作者:互联网

  要想了解贝叶斯分类,我们首先要了解概率论中一个我们在生活中中常用的,却又没有觉察的小知识,条件概率。

  条件概率,顾名思义,是在某种条件下或者某个特征下的概率。我们这里不再讨论先验和后验概率,以防大家迷糊。只讨论条件概率,更利于大家理解。

  举个例子,假设一个学校里有60%男生和40%女生。女生穿裤子的人数和穿裙子的人数相等,所有男生穿裤子。我们定义两个时间A,B。

  其中A={某个学生穿的服装类型},B={某个学生的性别};那么A的样本空间为A={A1:穿裙子,A2:穿裤子};B={B1:男,B2:女}

  P(A=“穿裙子”|B=“女生”)=50%,那么这个就是女生穿裙子的概率,也就是在限定一个女生的前提下,她穿裙子的概率是50%。那么我们可以推导一下,利用公式:p(A+B)=p(A)+p(B)-p(AB),那么P(A=“穿裙子”并且B=“女生”) =P(A=“穿裙子”)+P(B=“女生”) - P(A=“穿裙子”+B=“女生”)=0.5*0.4+0.4-0.4=0.2,(用互斥的话,更简单,但是不容易理解),P(B=“女生”)=0.4,P(A=“穿裙子”|B=“女生”) =P(A=“穿裙子”并且B=“女生”) /P(B=“女生”),那么以此类推,我们可以定义出条件概率:P(A|B) =P(AB) /P(B)。

  有了以上的知识储备,那么我们在理解贝叶斯算法,就有了理论的基石。对于随机变量W,有K个特征。{w1,...,wk},样本空间{C1,...,Cn},每个样本可以称为Ci类别。对随机变量做一次新的实验,等价于<==>在实际生产中,添加了一个具有K个特征的观测值Obeservtion,O1(o1,...,ok)。那么我们要知道O1的类别,就是要求P(C1|O1(o1,...,ok),...,P(Cn|O1(o1,...,ok)的最大值,也就可以说O1(o1,...,ok)属于哪个类别。这个其实是极大释然思想的体现,一次实验中发生的最大概率是,比如说C5,那么他就是属于这个类。

  P(Cn|W(W1,...,Wk))=(P(W(W1,...,Wk)|Cn)*P(Cn))/P(W(W1,...,Wk)),可以简化为求P(Cn)*(P(W1|Cn)...P(Wk|Cn)的最大值。Python实现如下,处理中有些细节,初始值,还有就是计算溢出问题等,用些小技巧处理掉。

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'],
                   ['my', 'licks', 'ate', 'my', 'steak', 'how', \
                    'to', 'stop', 'him'],
                   ['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
    # 由人工标注的每篇文档的类标签
    classVec = [0, 1, 0, 1, 0, 1]
    return postingList, classVec

# 统计所有文档中出现的词条列表
def createVocabList(dataSet):
    vocabSet = set([])
    for document in dataSet:
        vocabSet = vocabSet | set(document)
    return list(vocabSet)

# 根据词条列表中的词条是否在文档中出现(出现1,未出现0),将文档转化为词条向量
def setOfWords2Vec(vocabSet, inputSet):
    returnVec = [0] * len(vocabSet)
    for word in inputSet:
        if word in vocabSet:
            returnVec[vocabSet.index(word)] = 1
        else:
            print('the word: %s is not in my vocabulary! ' % 'word')
    return returnVec

# 训练算法,从词向量计算概率p(w0|ci)...及p(ci)
# @trainMatrix:由每篇文档的词条向量组成的文档矩阵
# @trainCategory:每篇文档的类标签组成的向量
def trainNB0(trainMatrix, trainCategory):
    numTrainDocs = len(trainMatrix)
    numWords = len(trainMatrix[0])
    pAbusive = sum(trainCategory) / float(numTrainDocs)
    p0Num = ones(numWords)
    p1Num = ones(numWords)
    p0Denom = 2.0
    p1Denom = 2.0
    # 初始化,防止有p(w0|ci)=0,导致全部为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 = p1Num / p1Denom
    p0Vect = p0Num / p0Denom
    return p0Vect, p1Vect, pAbusive

# 朴素贝叶斯分类函数,取log
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1
    else:
        return 0

# 分类测试整体函数
def testingNB():
    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))
    testEntry1 = ['stupid', 'garbage']
    thisDoc1 = array(setOfWords2Vec(myVocabList, testEntry1))
    print(testEntry1, 'classified as:', classifyNB(thisDoc1, p0V, p1V, pAb))

# def bagOfWords2VecMN(vocabList, inputSet):
#     returnVec = [0] * len(vocabList)
#     for word in inputSet:
#         if word in vocabList:
#             returnVec[vocabList.index(word)] += 1
#     return returnVec

if __name__ =="__main__":
    testingNB()

 

标签:...,女生,Cn,说起,贝叶斯,详解,word,vocabSet,trainMatrix
来源: https://www.cnblogs.com/zhuangxp2008/p/13890229.html