樸素貝葉斯分類器(Python實現)
阿新 • • 發佈:2019-01-03
基本思想:
樸素貝葉斯分類器,在當給出了特徵向量w情況下,分類為ci的條件概率p(ci | w)。
利用貝葉斯公式:p(ci | w) = p(w | ci) * p(ci) / p(w),可以完成轉化,觀察公式可以發現分母p(w)都一樣,所以只要比較分子的大小即可。
其中,p(ci)概率很容易求出;而對於條件概率p(w | ci),利用假設各個特徵之間相互獨立,因此,由w = {w1, w2, …, wn),即可以得出p(w | ci) = p(w1 | ci) * p(w2 | ci) * … * p(wn | ci),這也是樸素貝葉斯中“樸素”的意義。
利用python中的NumPy實現起來很簡單,但是要注意的是這裡為了防止下溢位(乘積較小)的情況發生,這裡需要改為求log(p(ci | w))。
程式碼:
# coding=utf-8
# python 2.7
# 樸素貝葉斯分類器實現
from numpy import *
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]
return postingList, classVec
def createVocabList(dataSet):
vacabList = set([])
for doc in dataSet:
vacabList = vacabList | set(doc) # 集合求並集運算
return list(vacabList) # 注意要轉化成列表
# 將文章轉化成詞向量
def wordToVec(list, doc):
vec = [0] * len(list)
for word in doc:
if word in list:
vec[list.index(word)] = 1
else :
print 'thr word: %s is not in my vocabulary!' % word
return vec
# 訓練函式,通過貝葉斯公式計算出特徵概率向量
def trainNB(mat, cate):
docNum = len(mat)
wordNum = len(mat[0])
pAb = sum(cate) * 1.0 / docNum
p1Vec = ones(wordNum); p0Vec = ones(wordNum) # 對數轉化處理
p1Denom = 2.0; p0Denom = 2.0
for i in range(docNum):
if cate[i] == 1:
p1Vec += mat[i]
p1Denom += sum(mat[i])
else :
p0Vec += mat[i]
p0Denom += sum(mat[i])
p1Vec = log(p1Vec / p1Denom) # 對數轉化處理
p0Vec = log(p0Vec / p0Denom)
return p0Vec, p1Vec, pAb # p0Vec是特徵在0分類下的概率向量,p1Vec是特徵在1分類下的概率向量,pAb是取得1分類的概率
# 分類函式
def classfyNB(testVec, p0Vec, p1Vec, pAb):
p0 = sum(testVec * p0Vec) + log(1 - pAb) # 這裡sum(testVec * p0Vec)可以理解為p0Vec中出現的特徵對數求和,也就是取對數之前的求乘積
p1 = sum(testVec * p1Vec) + log(pAb)
if p0 > p1:
return 0
else:
return 1
def testingNB():
postData, listClasses = loadDataSet()
vocabList = createVocabList(postData)
trainMat = []
for doc in postData:
trainMat.append(wordToVec(vocabList, doc))
p0Vec, p1Vec, pAb = trainNB(trainMat, listClasses)
doc = ['love', 'my', 'dalmation']
testVec = array(wordToVec(vocabList, doc))
print doc, 'classfied as: ', classfyNB(testVec, p0Vec, p1Vec, pAb)
doc = ['stupid', 'garbage']
testVec = array(wordToVec(vocabList, doc))
print doc, 'classfied as: ', classfyNB(testVec, p0Vec, p1Vec, pAb)
testingNB()