機器學習演算法-樸素貝葉斯Python實現
引文:前面提到的K最近鄰演算法和決策樹演算法,資料例項最終被明確的劃分到某個分類中,下面介紹一種不能完全確定資料例項應該劃分到哪個類別,或者說只能給資料例項屬於給定分類的概率。
基於貝葉斯決策理論的分類方法之樸素貝葉斯
- 優點:在資料較少的情況下仍然有效,可以處理多類別問題
- 缺點:對於輸入資料的準備方式較為敏感
- 適用資料型別:標稱型資料。
樸素貝葉斯的一般過程
- 收集資料:可以使用任何方式
- 準備資料:需要資料型或是布林型資料
- 分類資料:有大量特徵時,繪製特徵作用不大,此時使用直方圖效果更好
- 訓練演算法:計算不同的獨立特徵的條件概率
- 測試演算法:計算錯誤率
- 使用演算法:文件分類
原理
主要是運用貝葉斯定理
演算法實現
下面做一個簡單的留言板分類,自動判別留言類別:侮辱類和非侮辱類,分別使用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表示條件概率
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表示的是
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 》機器學習實戰