1. 程式人生 > >樸素貝葉斯分類器(Python實現)

樸素貝葉斯分類器(Python實現)

基本思想:

樸素貝葉斯分類器,在當給出了特徵向量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()