朴素贝叶斯方法(Naive Bayes)原理和实现
生活随笔
收集整理的這篇文章主要介紹了
朴素贝叶斯方法(Naive Bayes)原理和实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
模型概述
樸素貝葉斯方法,是指根據貝葉斯定理,對一個分類問題,給定樣本特征x,樣本屬于類別y的概率是
在這里,x是一個特征向量,將設x維度為M。因為樸素的假設,即特征條件獨立,根據全概率公式展開,公式(1)可以表達為
p(y=ck|x)=∏Mi=1p(xi|y=ck)p(y=ck)∑kp(y=ck)∏Mi=1P(xi|y=ck)。。。。(2)
這里,只要分別估計出,特征 xi在每一類的條件概率就可以了。類別y的先驗概率可以通過訓練集算出,同樣通過訓練集上的統計,可以得出對應每一類上的,條件獨立的特征對應的條件概率向量。
如何統計,就是下一部分——學習——所關心的內容。
學習(參數估計)
下面介紹如何從數據中,學習得到樸素貝葉斯分類模型。概述分類方法,并提出一個值得注意的問題。
學習
訓練集TrainingSet={(x1,y1),(x2,y2),...,(xN,yN)} 包含N條訓練數據,其中 xi=(x(1)i,x(2)i,...,x(M)i)T是M維向量,yi∈{c1,c2,...cK}屬于K類中的一類。學習 1.首先,我們來計算公式(2)中的p(y=ck)
其中I(x)為指示函數,若括號內成立,則計1,否則為0。
學習 2.接下來計算分子中的條件概率,設M維特征的第j維有L個取值,則某維特征的某個取值ajl,在給定某分類ck下的條件概率為:
經過上述步驟,我們就得到了模型的基本概率,也就完成了學習的任務。
分類
通過學到的概率,給定未分類新實例X,就可以通過上述概率進行計算,得到該實例屬于各類的后驗概率p(y=ck|X),因為對所有的類來說,公式(2)中分母的值都相同,所以只計算分子部分即可,具體步驟如下:p(y=ck|X)=p(y=ck)∏j=1np(X(j)=x(j)|y=ck)。。。(5)
分類 2.確定該實例所屬的分類y
y=argmaxckp(y=ck|X)。。。。(6)
于是我們得到了新實例的分類結果
拉普拉斯平滑
到這里好像方法已經介紹完了,實則有一個小問題需要注意,在公式(3)(4)中,如果從樣本中算出的概率值為0該怎么辦呢?下面介紹一種簡單方法,給學習步驟中的兩個概率計算公式,分子和分母都分別加上一個常數,就可以避免這個問題。更新過后的公式如下:K是類的個數
p(xj=ajl|y=ck)=∑Ni=1I(xji=ajl,yi=ck)+λ∑Ni=1I(yi=ck)+Ljλ。。。(8)
Lj是第j維特征的最大取值
可以證明,改進以后的(7)(8)仍然是概率。平滑因子λ=0即為(3)(4)實現的最大似然估計,這時會出現在本節開始時提到的0概率問題;而λ=1則避免了0概率問題,這種方法被稱為拉普拉斯平滑。
實現:樸素貝葉斯下的文本分類
根據上面的算法流程,在這里實現一個句子極性劃分的例子。所謂句子極性是指,句子所表達的情感色彩,例如積極/消極,這里(書里)使用的是侮辱性/非侮辱性。其實是什么類別不重要,只要給定有標簽的訓練數據,就可以得到分類模型。
下面簡述實現思想和流程,給出代碼。
算法思想和流程
給定的訓練集是標定了 侮辱性/非侮辱性 的句子(因為是英語句子,所以基本視分詞為已經解決的問題,如果是漢語,則要先進行分詞),我們認為特征就是句子中的單個詞語。單個詞語有極性表征,整個句子所包含的單詞的極性表征就是句子的極性。由以上的基礎,應用樸素貝葉斯分類,就變成了這樣的問題代碼
初始化:
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,classVecdef createVocabList(dataSet):#創建詞匯表vocabSet = set([])for document in dataSet:vocabSet = vocabSet | set(document) #創建并集return list(vocabSet)def bagOfWord2VecMN(vocabList,inputSet):#根據詞匯表,講句子轉化為向量returnVec = [0]*len(vocabList)for word in inputSet:if word in vocabList:returnVec[vocabList.index(word)] += 1return returnVec訓練:
def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)numWords = len(trainMatrix[0])pAbusive = sum(trainCategory)/float(numTrainDocs)p0Num = ones(numWords);p1Num = ones(numWords)#計算頻數初始化為1p0Denom = 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)#注意p0 = sum(vec2Classify * p0Vec) + log(1-pClass1)#注意if p1 > p0:return 1else:return 0def testingNB():#流程展示listOPosts,listClasses = loadDataSet()#加載數據myVocabList = createVocabList(listOPosts)#建立詞匯表trainMat = []for postinDoc in listOPosts:trainMat.append(bagOfWord2VecMN(myVocabList,postinDoc))p0V,p1V,pAb = trainNB0(trainMat,listClasses)#訓練#測試testEntry = ['love','my','dalmation']thisDoc = bagOfWord2VecMN(myVocabList,testEntry)print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)注意:上述代碼中標有注意的地方,是公式中概率連乘變成了對數概率相加。此舉可以在數學上證明不會影響分類結果,且在實際計算中,避免了因概率因子遠小于1而連乘造成的下溢出。總結
以上是生活随笔為你收集整理的朴素贝叶斯方法(Naive Bayes)原理和实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: scikit-learn学习笔记(六)D
- 下一篇: 理解Promise规范