1. 程式人生 > >機器學習演算法-樸素貝葉斯Python實現

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

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

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

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

樸素貝葉斯的一般過程

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

原理

主要是運用貝葉斯定理

P(H|X)=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),p1Vec表示條件概率P(wi|c=1),pClass1表示類標籤為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(w1|c=0)p(w2|c=0)...p(wn|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部落格