機器學習演算法-樸素貝葉斯Python實現

引文:前面提到的K最近鄰演算法和決策樹演算法,資料例項最終被明確的劃分到某個分類中,下面介紹一種不能完全確定資料例項應該劃分到哪個類別,或者說只能給資料例項屬於給定分類的概率。

基於貝葉斯決策理論的分類方法之樸素貝葉斯

  • 優點:在資料較少的情況下仍然有效,可以處理多類別問題
  • 缺點:對於輸入資料的準備方式較為敏感
  • 適用資料型別:標稱型資料。

樸素貝葉斯的一般過程

  • 收集資料:可以使用任何方式
  • 準備資料:需要資料型或是布林型資料
  • 分類資料:有大量特徵時,繪製特徵作用不大,此時使用直方圖效果更好
  • 訓練演算法:計算不同的獨立特徵的條件概率
  • 測試演算法:計算錯誤率
  • 使用演算法:文件分類

原理

主要是運用貝葉斯定理

P(H|X)=P(X|H)p(H)P(X)

P(H|X) = \dfrac{P(X|H) p(H)}{P(X)}

演算法實現

下面做一個簡單的留言板分類,自動判別留言類別:侮辱類和非侮辱類,分別使用1和0表示。下面來做一下這個實驗。以下函式全部寫在一個叫bayes.py檔案中,後面的實驗室通過匯入bayes.py,呼叫裡面的函式來做的。

匯入numpy包

from numpy import *

1.載入資料集

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 is abusive, 0 not
return postingList,classVec      

該函式返回的是詞條切分集合類標籤

2.根據樣本建立一個詞庫

下面的函式是根據上面給出來的樣本資料所建立出來的一個詞庫。

def createVocabList(dataSet):
vocabSet = set([])  #create empty set
for document in dataSet:
vocabSet = vocabSet | set(document) #union of the two sets
return list(vocabSet)

3.統計每個樣本在詞庫中的出現情況

下面的函式功能是把單個樣本對映到詞庫中去,統計單個樣本在詞庫中的出現情況,1表示出現過,0表示沒有出現,函式如下:

def setOfWords2Vec(vocabList, inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] = 1
else: print "the word: %s is not in my Vocabulary!" % word
return returnVec

4.計算條件概率和類標籤概率

def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs) #計算某個類發生的概率
p0Num = ones(numWords); p1Num = ones(numWords) #初始樣本個數為1,防止條件概率為0,影響結果       
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)         #計算類標籤為1時的其它屬性發生的條件概率
p0Vect = log(p0Num/p0Denom)         #計算標籤為0時的其它屬性發生的條件概率
return p0Vect,p1Vect,pAbusive       #返回條件概率和類標籤為1的概率

說明:

5.訓練貝葉斯分類演算法

該演算法包含四個輸入,vec2Classify表示待分類的樣本在詞庫中的對映集合,p0Vec表示條件概率P(wi|c=0)P(w_i|c=0),p1Vec表示條件概率P(wi|c=1)P(w_i|c=1),pClass1表示類標籤為1時的概率P(c=1)P(c=1)。

def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec)   log(pClass1)    #element-wise mult
p0 = sum(vec2Classify * p0Vec)   log(1.0 - pClass1)
if p1 > p0:
return 1
else: 
return 0

其中p1和p0表示的是lnp(w1|c=1)p(w2|c=1)…p(wn|c=1)∗p(c=1)lnp(w_1|c=1)p(w_2|c=1)…p(w_n|c=1)*p(c=1)和lnp(w1|c=0)p(w2|c=0)…p(wn|c=0)∗p(c=0)lnp(w_1|c=0)p(w_2|c=0)…p(w_n|c=0)*p(c=0),取對數是因為防止p(w_1|c=1)p(w_2|c=1)p(w_3|c=1)…p(w_n|c=1)多個小於1的數相乘結果值下溢。

6.文件詞袋模型,修改函式setOfWords2Vec

詞袋模型主要修改上面的第三個步驟,因為有的詞可能出現多次,所以在單個樣本對映到詞庫的時候需要多次統計。

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

7.測試函式

下面給出一個測試函式,直接呼叫該測試函式就可以實現簡單的分類,測試結果看下個部分。

def testingNB():
#step1:載入資料集和類標號
listOPosts,listClasses = loadDataSet()
#step2:建立詞庫
myVocabList = createVocabList(listOPosts)
# step3:計算每個樣本在詞庫中的出現情況
trainMat=[]
for postinDoc in listOPosts:
trainMat.append(setOfWords2Vec(myVocabList, postinDoc))
#step4:呼叫第四步函式,計算條件概率
p0V,p1V,pAb = trainNB0(array(trainMat),array(listClasses))
# step5
# 測試1 
testEntry = ['love', 'my', 'dalmation']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)
# 測試2
testEntry = ['stupid', 'garbage']
thisDoc = array(setOfWords2Vec(myVocabList, testEntry))
print testEntry,'classified as: ',classifyNB(thisDoc,p0V,p1V,pAb)

8.實驗

首先匯入庫,然後匯入bayes.py檔案

import os
os.chdir(r"E:\3-CSU\Academic\Machine Leaning\機器學習實戰\src\machinelearninginaction\Ch04")
import bayes

這裡寫圖片描述

可以看出,貝葉斯演算法將[‘love’, ‘my’, ‘dalmation’]分為“無侮辱”一類,將[‘stupid’, ‘garbage’]分為“侮辱”性質的一類。

Reference

[1]《Machine Learning in Action 》機器學習實戰


本欄目Machine Learning 演算法實現持續更新中,歡迎關注:Dream_Angel_Z部落格