1. 程式人生 > >我眼中的樸素貝葉斯

我眼中的樸素貝葉斯

幫助 位置 助理 實戰 span com 9.png 初始 buying

既然要用到貝葉斯公式,首先給出貝葉斯公式

P(A|B)=P(B|A)P(A)/P(B)

數學含義:

P(A)是先驗概率,可以通過計算獲得

P(B|A)是條件概率,意識是在A發生的條件下B發生的概率

P(B)是用於歸一化的“證據”因子,對於給定的樣本B,P(B)與類標記無關

P(A|B)就是後驗概率,也是需要我們根據P(B|A),P(A)求的

這個準則有什麽用呢?接下來給一個例子

使用樸素貝葉斯進行文檔分類

目標是實現自動檢測輸入的文檔是侮辱性詞還是非侮辱性詞

首先用圖來描繪整個過程,和對貝葉斯公式的簡單運用

創建訓練集:

假如你有6個文檔,並且知道他們個屬於什麽類型(侮辱/一般)詞

技術分享圖片

0表示一般詞,1表示侮辱詞,首先把這些詞匯總在一起構建一個無重復的詞庫

技術分享圖片

有了詞庫以後我們要制作訓練集,就要把6六個文檔用詞向量的形式比表示,怎麽做呢?,就用到了無重復的詞庫,把6個文檔分別與詞庫比較,有就標記為1,無則為0,就得到只有01的矩陣,它的列長與詞庫的長度相同

技術分享圖片

這就是訓練集,接下來訓練

訓練過程:

詞矩陣:[Wi]

c1表示辱罵型詞,c0表示一般詞

訓練的過程是要求出每一詞的條件分布P([wi]|c1),P([wi]|c0)

P([wi]|c1):已知詞wi是辱罵性詞的條件下,它的概率是多少,概率越高表示它出現的次數越多,表示它越可能是辱罵性詞

P([wi]|c0):相同可知

要求這兩個條件概率,首先要把訓練樣本根據已知標簽分成兩類c1,c0,然後再求每一詞出現的概率,所以最後得到兩個條件概率矩陣。

技術分享圖片

技術分享圖片

得到兩個矩陣後,相當於訓練好的模型,但怎麽實現分類呢?在回顧一下貝葉斯準則

P(cj|[wi])=p([Wi]|c1)*P(c1)/P([wi])

P(cj|[wi]):含義是已知詞wi,則它是(侮辱性詞/非侮辱性)的概率是多少,這就是我們要求的,求得這個概率就能確定它的分類

[Wi]是詞矩陣,且假設每一個詞都是相互獨立,這樣就簡化了問題,這也是為什麽叫樸素貝葉斯。

p([Wi]|c1) = p(W1|c1)*p(W2|c1)*....p(Wn|c1)

p([Wi]|c0) = p(W1|c0)*p(W2|c0)*....p(Wn|c0)

所以

P(c1|[wi]) = p(W1|c1)*p(W2|c1)*....p(Wn|c1)P(c1)

P(c0|[wi]) = p(W1|c0)*p(W2|c0)*....p(Wn|c0)P(c0)

比較P(c1|[wi]),P(c0|[wi])大小

if P(c1|[wi])>P(c0|[wi])

說明是侮辱性詞的概率大

else

是一般性詞

測試:

假如輸入一個不知道類型的文檔,根據上面的詞庫建立它是詞向量,分別與上面的兩個條件概率向量相乘,計算條件貝葉斯概率即可

代碼:

#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]]
    #1代表侮辱性文字,0代表正常言論
    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)
   
def setOfWords2Vec(vocabList,inputSet):
    #構建一個長度和vocabList一樣的零向量
    returnVec =[0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            #如果這個詞在詞表中有,則詞向量中相應位置值設為1
            #vocabList.index(word) 返回的是詞word在vocabList中的位置下標
            returnVec[vocabList.index(word)] = 1
        else:
            print ("the word :%s is not in my Vocabulary" %word)
    return returnVec
    
    
#樸素貝葉斯分類器訓練trainMaxtrix訓練矩陣,trainCategory標簽
def trainNB0(trainMaxtrix,trainCategory):
    #行數
    numTrainDocs = len(trainMaxtrix)
    #列數
    numWords = len(trainMaxtrix[0])
    #侮辱性文檔所占概率P(c1)
    pAbusive = sum(trainCategory)/float(numTrainDocs)
    #為了防止其中一個概率為零,導致乘積為零,初始化分子為1,分母為2
    p0Num = ones(numWords)
    p1Num = ones(numWords)
    p0Denom = 2.0
    p1Denom = 2.0
    #遍歷文檔,每一行表示一個文檔
    for i in range(numTrainDocs):
        #1表示正常言論文檔,否則辱罵言論文檔
        if trainCategory[i] == 1:
            #統計每個詞出現的次數
            p1Num += trainMaxtrix[i]
            #辱罵詞的總個數
            p1Denom +=sum(trainMaxtrix[i])
        else:
            p0Num += trainMaxtrix[i]
            p0Denom +=sum(trainMaxtrix[i])
    #p([Wi]|c1) = p(W1|c1)*p(W2|c1)*....p(Wn|c1)  因為相互獨立
    #p1Vect = p1Num/p1Denom,為了防止許多小數相乘下溢,於是log一下
    p1Vect = log(p1Num/p1Denom)
    #p([Wi]|c0) = p(W1|c0)*p(W2|c0)*....p(Wn|c0)
    #p0Vect = p0Num/p0Denom
    p0Vect = log(p0Num/p0Denom)
    return p0Vect,p1Vect,pAbusive
    
#樸素貝葉斯分類器函數
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
    #p([Wi]|c1)*P(c1) = P(c1|[wi])*P(w) 根據貝葉斯公式
    #P(c1|[wi])意思是已知詞wi,則它是(侮辱性詞/非侮辱性)的概率是多少
    p1 = sum(vec2Classify * p1Vec) + log(pClass1)
    #p([Wi]|c0)*P(c0) = P(c0|[wi])*P(w)
    p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
    if p1 > p0:
        return 1;
    else:
        return 0;

def testingNB():
    listOPosts,listClasses = loadDataSet()
    myVocabList = createVocabList(listOPosts)
    print("myVocabList",myVocabList)
    trainMat = []
    #把文檔轉換成詞向量,生成一個二維向量矩陣trainMat
    for postinDoc in listOPosts:
        trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
    print("trainMat",trainMat)
    p0V,p1V,pAb = trainNB0(trainMat,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))
    

代碼來至機器學習實戰,我做了詳細的註釋,結合上面的圖過程可以理解

主要還幫助理解的貝葉斯公式到底是怎麽實現分類的。

我眼中的樸素貝葉斯