目錄:
- 樸素貝葉斯概述
- 參數估計:極大似然估計
- 樸素貝葉斯算法
- Python實現
樸素貝葉斯概述:
基於貝葉斯定理與特徵條件獨立假設的分類方法。
對於給定的訓練數據集,首先基於特徵條件獨立假設學習輸入/輸出 P(X|Y)的聯合概率分佈;然後基於此模型,利用貝葉斯定理求出後驗概率P(X|Y) 最大的輸出Y
- 優點:在數據較少的情況下仍然有效,可以處理所類別問題
- 缺點:對於輸入數據的準備方式較為敏感
- 適用的數據類型:標稱型數據
貝葉斯定理:
其中 P(c) 是先驗概率,P(x|c) 是樣本輸入相對於輸出的條件概率,或者稱“似然”P(X)對於不同情況的類別(C1,C2,。。。。)都是相同的,
估計P(x|c) 就轉化為基於訓練數據D來估計先驗概率 P(c) 和類條件概率P(x|c)
極大似然估計:
P(c)類先驗概率P(c)樣本空間中各類樣本所佔的比例,根據大數定理,:當訓練集包含充足的獨立同分布樣本時,P(c)可以通過各類樣本出現的頻率來估計
P(x|c) 估計:估計類條件概率的一種常見策略是先假定其具有某種確定的概率分佈形式,再基於訓練樣本對概率分佈的參數進行估計。
即假設 P(x|c) 具有確定的形式並且被參數向量0唯一確定,則估計 P(x|c) 就轉化為利用訓練數據估計
0確定其表達形式。
極大似然估計0令Dc表示訓練集D中第c類樣本的集合,假設這些樣本時獨立同分布的,則參數 0對於數據集Dc的類條件概率是
對0進行極大似然估計,就是對
求0的偏導,令其等於0,求使似然
最大化的參數值
其中
為似然函數,一般為
(連乘操作容易造成下溢,通常使用對數似然)
基於樸素貝葉斯算法的文檔分類的Python實現
輸入數據:輸入文本文件,將文本解析成詞條向量
<code>''' 輸出:詞條切片後的文檔列表,對應的類別
'''
def loaddataset():
postingList=[....
]#輸入詞條切片後的文檔集合
classlist=[]#類別列表
return postingList,classlist
#創建詞彙表
def createVocablist(dataset):
vocabSet=set([])#不重複集合
for i in dataset:
vocabSet=vocablist|set(i)
return list(vocabSet)#將vocabSet轉換為列表
'''輸入:詞彙表,輸入文檔
輸出:文檔向量
'''
#創建文檔向量:記錄詞彙表單詞是否在出現在輸入文檔中
def set_words2Vec(vocabSet,inputSet):
returnVec=[0]*len(vocabSet)
for word in inputSet:
if word in vocabSet:#如果單詞出現在詞彙表中,其相應位置的計數置為1
returnVec[vocabSet.index(word)]=1
else:
print ("the word: %s is not in vocabSet" %word)
return returnVec /<code>
訓練數據:利用文檔向量和類別估計p(c)和p(x|c)
<code>#樸素貝葉斯訓練函數
'''輸入為文檔向量矩陣,文檔類別矩陣
輸出為p(word|0),p(word|1),p(侮辱性文檔)
p(正常文檔)=1-p(侮辱性文檔)
'''
def trainNB(trainMatrix,trainCategory):
numberDocu=len(trainMatrix)#計算文檔數目
numberWords=len(trainMatrix[0])#計算每個文檔中單詞數目
PA=sum(trainCategory)/numberDocu#計算文檔是侮辱性文檔概率,正常文檔概率為1-PA
p0Num=ones(numberWords);p1Num=ones(numberWords)
p0Denom=2.0;p1Denom=2.0
for i in range(numberDocu):
if trainCategory[i]==1:#如果文檔是侮辱性文檔
p1Num+=trainCategory[i]#記錄文檔中各個單詞的數量
p1Denom+=sum(trainMatrix[i])
else:
p0Num+=trainMatrix[i]
p0Denom+=trainMatrix[i]
p1Vec=log(p1Num/p1Denom)#計算在侮辱性文檔出現的條件下,各單詞出現的條件概率
p0Vec=log(p0Num/p0Denom)#計算計算在正常文檔出現的條件下,各單詞出現的條件概率
return p0Vec,p1Vec,PA/<code>
測試算法:
<code>#樸素貝葉斯分類函數
'''輸入為要進行分類的文檔向量,p(x|c)和p(c)
輸出為類別:1代表侮辱性文檔,0代表正常文檔
'''
def classifyNB(vec2Class,p0Vec,p1Vec,pClass1):
p1=sum(vec2Class*p1Vec)+log(pClass1)
P0=sum(vec2Class*p0Vec)+log(1.0-pClass1)
if p1>p0:
return 1
else:
return 0/<code>
參考文獻:
《機器學習》周志華著
《統計學習方法》李航著
《Machine Learning In Action》by Peter Harrington
閱讀更多 Python之眼 的文章