機器學習筆記:樸素貝葉斯方法(Naive Bayes)原理和實現
本文主要描述了樸素貝葉斯分類方法,包括模型匯出和學習描述。例項部分總結了《machine learning in action》一書中展示的一個該方法用於句子感情色彩分類的程式。1
- 方法概述
- 學習(引數估計)
- 實現:樸素貝葉斯下的文字分類
模型概述
- 樸素貝葉斯方法,是指
- 樸素:特徵條件獨立
- 貝葉斯:基於貝葉斯定理
根據貝葉斯定理,對一個分類問題,給定樣本特徵x,樣本屬於類別y的概率是
p(y|x) = \dfrac{p(x|y)p(y)}{p(x)} 。。。。。。(1)
在這裡,x是一個特徵向量,將設x維度為M。因為樸素的假設,即特徵條件獨立,根據全概率公式展開,公式(1)可以表達為
p(y=c_k|x)=\dfrac{\prod_{i=1}^{M}p(x^i|y=c_k)p(y=c_k)}{\sum_kp(y=c_k)\prod_{i=1}^{M}P(x^i|y=c_k)}。。。。(2)
這裡,只要分別估計出,特徵
x^i
在每一類的條件概率就可以了。類別y的先驗概率可以通過訓練集算出,同樣通過訓練集上的統計,可以得出對應每一類上的,條件獨立的特徵對應的條件概率向量。 如何統計,就是下一部分——學習——所關心的內容。
學習(引數估計)
下面介紹如何從資料中,學習得到樸素貝葉斯分類模型。概述分類方法,並提出一個值得注意的問題。
學習
- 訓練集TrainingSet=
{(x1,y1),(x2,y2),...,(xN,yN)} \{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}包含N條訓練資料,其中xi=(x(1)i,x(2)i,...,x(M)i)T x_i=(x_{i}^{(1)},x_{i}^{(2)},...,x_{i}^{(M)})^T是M維向量,yi∈{c1,c2,...cK} y_i\in\{c_1,c_2,...c_K\}屬於K類中的一類。 -
學習 1.首先,我們來計算公式(2)中的
p(y=ck) p(y=c_k)
p(y=ck)=∑Ni=1I(yi=ck)N。。。。(3) p(y=c_k)=\dfrac{\sum_{i=1}^{N}I(y_i=c_k)}{N}。。。。(3)
其中I(x) I(x)為指示函式,若括號內成立,則計1,否則為0。 -
學習 2.接下來計算分子中的條件概率,設
M M維特徵的第j j維有L L個取值,則某維特徵的某個取值ajl a_{jl},在給定某分類ck c_k下的條件概率為:
p(xj=ajl|y=ck)=∑Ni=1I(xji=ajl,yi=ck)∑Ni=1I(yi=ck)。。。(4) p(x^j=a_{jl}|y=c_k)=\dfrac{\sum_{i=1}^{N}I(x_i^{j}=a_{jl},y_i=c_k)}{\sum_{i=1}^{N}I(y_i=c_k)}。。。(4)
經過上述步驟,我們就得到了模型的基本概率,也就完成了學習的任務。
分類
- 通過學到的概率,給定未分類新例項
X X,就可以通過上述概率進行計算,得到該例項屬於各類的後驗概率p(y=ck|X) p(y=c_k|X),因為對所有的類來說,公式(2)中分母的值都相同,所以只計算分子部分即可,具體步驟如下: 分類 1.計算該例項屬於
y=ck y=c_k類的概率
p(y=ck|X)=p(y=ck)∏j=1np(X(j)=x(j)|y=ck)。。。(5) p(y=c_k|X)=p(y=c_k)\prod_{j=1}^{n}p(X^{(j)}=x^{(j)}|y=c_k)。。。(5)
分類 2.確定該例項所屬的分類y y
y=argmaxckp(y=ck|X)。。。。(6) y=arg\max_{ c_k}p(y=c_k|X)。。。。(6)
於是我們得到了新例項的分類結果
拉普拉斯平滑
- 到這裡好像方法已經介紹完了,實則有一個小問題需要注意,在公式(3)(4)中,如果從樣本中算出的概率值為0該怎麼辦呢?
- 下面介紹一種簡單方法,給學習步驟中的兩個概率計算公式,分子和分母都分別加上一個常數,就可以避免這個問題。更新過後的公式如下:
p(y=ck)=∑Ni=1I(yi=ck)+λN+Kλ。。。。(7) p(y=c_k)=\dfrac{\sum_{i=1}^{N}I(y_i=c_k)+ \lambda}{N+K\lambda}。。。。(7)
K K是類的個數
p(xj=ajl|y=ck)=∑Ni=1I(xji=ajl,yi=ck)+λ∑Ni=1I(yi=ck)+Ljλ。。。(8) p(x^j=a_{jl}|y=c_k)=\dfrac{\sum_{i=1}^{N}I(x_i^{j}=a_{jl},y_i=c_k)+ \lambda}{\sum_{i=1}^{N}I(y_i=c_k)+L_j\lambda}。。。(8)
Lj L_j是第j j維特徵的最大取值
可以證明,改進以後的(7)(8)仍然是概率。平滑因子
\lambda=0
即為(3)(4)實現的最大似然估計,這時會出現在本節開始時提到的0概率問題;而\lambda=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,classVec
def 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)] += 1
return returnVec
訓練:
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = ones(numWords);p1Num = ones(numWords)#計算頻數初始化為1
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)#注意
p0 = sum(vec2Classify * p0Vec) + log(1-pClass1)#注意
if p1 > p0:
return 1
else:
return 0
def 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而連乘造成的下溢位。
- 參考:
李航. (2012). 統計學習方法.
Harrington, P. (2013). 機器學習實戰. 人民郵電出版社, 北京 ↩
相關文章
- 機器學習演算法(二): 樸素貝葉斯(Naive Bayes)機器學習演算法AI
- Python機器學習 — 樸素貝葉斯演算法(Naive Bayes)Python機器學習演算法AI
- 機器學習實戰(三)--樸素貝葉斯機器學習
- 樸素貝葉斯和半樸素貝葉斯(AODE)分類器Python實現Python
- Python機器學習筆記:樸素貝葉斯演算法Python機器學習筆記演算法
- chapter6:概率及樸素貝葉斯--樸素貝葉斯APT
- [機器學習&資料探勘]樸素貝葉斯數學原理機器學習
- 機器學習之樸素貝葉斯分類機器學習
- 機器學習Sklearn系列:(四)樸素貝葉斯機器學習
- 機器學習筆記之樸素貝葉斯分類演算法機器學習筆記演算法
- 機器學習|樸素貝葉斯演算法(二)-用sklearn實踐貝葉斯機器學習演算法
- 樸素貝葉斯模型模型
- 樸素貝葉斯實現文件分類
- 樸素貝葉斯分類演算法(Naive Bayesian classification)演算法AI
- 樸素貝葉斯法初探
- 樸素貝葉斯演算法的python實現 -- 機器學習實戰演算法Python機器學習
- 《統計學習方法》——樸素貝葉斯程式碼實現
- 機器學習|樸素貝葉斯演算法(一)-貝葉斯簡介及應用機器學習演算法
- 樸素貝葉斯演算法原理小結演算法
- 樸素貝葉斯演算法演算法
- 樸素貝葉斯分類和預測演算法的原理及實現演算法
- 樸素貝葉斯演算法的實現與推理演算法
- 樸素貝葉斯演算法的python實現演算法Python
- 《機器學習實戰》4.4使用樸素貝葉斯進行文件分類機器學習
- 樸素貝葉斯/SVM文字分類文字分類
- 抽象的藝術-樸素貝葉斯抽象
- 100天搞定機器學習|Day15 樸素貝葉斯機器學習
- 機器學習經典演算法之樸素貝葉斯分類機器學習演算法
- 監督學習之樸素貝葉斯
- 分類演算法-樸素貝葉斯演算法
- 04_樸素貝葉斯演算法演算法
- 使用樸素貝葉斯過濾垃圾郵件
- 樸素貝葉斯分類流程圖介紹流程圖
- 樸素貝葉斯分類器的應用
- 詳解樸素貝葉斯的來源,原理以及例項解析
- 資料探勘(8):樸素貝葉斯分類演算法原理與實踐演算法
- [譯] Sklearn 中的樸素貝葉斯分類器
- Machine Learning-樸素貝葉斯演算法Mac演算法