1. 程式人生 > >郵件分類和過濾-樸素貝葉斯NB經典案例

郵件分類和過濾-樸素貝葉斯NB經典案例

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1

關於樸素貝葉斯的理論,已在機器學習之樸素貝葉斯分類器中進行了詳細說明,但是沒有經歷coding親自見證效果,還是無法真正掌握。

本篇旨在理論的基礎上靈活運用樸素貝葉斯進行分類。

再來回顧下樸素貝葉斯分類器的思想、演算法流程,順道把用到的Python函式羅列出來。

演算法思想

比如我們想判斷一個郵件是不是垃圾郵件,那麼我們知道的是這個郵件中的詞的分佈,那麼我們還要知道:垃圾郵件中某些詞的出現是多少,就可以利用貝葉斯定理得到。

樸素貝葉斯最常見的分類應用是對文件進行分類,因此,最常見的特徵條件是文件中,出現詞彙的情況,通常將詞彙出現的特徵條件用詞向量 0?wx_fmt=png表示,由多個數值組成,數值的個數和訓練樣本集中的詞彙表個數相同。

樸素貝葉斯分類器中的一個假設是:每個特徵同等重要,每個屬性歸屬於此類的概率獨立於其餘所有屬性。

演算法流程

1.資料準備:(收集資料+處理資料+提取資料特徵)將資料預處理為數值型或者布林型,如對文字分類,需要將文字解析為詞向量 。

2.訓練資料:根據訓練樣本集計算詞項出現的概率,訓練資料後得到各類下詞彙出現概率的向量 。
3. 測試資料:評估對於測試資料集的預測精度作為預測正確率。

4.合併程式碼:使用所有程式碼呈現一個完整的、獨立的樸素貝葉斯演算法的實現。

使用樸素貝葉斯過濾垃圾郵件

資料夾spam和ham中各有25封txt文件形式的郵件正文,兩個資料夾分別分類為1和0,如開啟ham中2.txt檔案,其內容為:

Yay to you both doing fine!

I'm working on an MBA in Design Strategy at CCA (top art school.)  It's a new program focusing on more of a right-brained creative and strategic approach to management.  I'm an 1/8 of the way done today!

函式

loadDataSet()

建立資料集,這裡的資料集是已經拆分好的單片語成的句子。

createVocabList(dataSet)

找出這些句子中總共有多少單詞,以確定我們詞向量的大小。

setOfWords2Vec(vocabList, inputSet)

將句子根據其中的單詞轉成向量,這裡用的是伯努利模型,即只考慮這個單詞是否存在。

bagOfWords2VecMN(vocabList, inputSet)

這個是將句子轉成向量的另一種模型,多項式模型,考慮某個詞的出現次數。

trainNB0(trainMatrix,trainCatergory)

計算P(i)和P(w[i]|C[1])和P(w[i]|C[0]),這裡有兩個技巧,一個是開始的分子分母沒有全部初始化為0是為了防止其中一個的概率為0導致整體為0,另一個是後面乘用對數防止因為精度問題結果為0

classifyNB(vec2Classify, p0Vec, p1Vec, pClass1)

根據貝葉斯公式0?wx_fmt=png計算這個向量屬於兩個集合中哪個的概率高。

利用以上文件,進行樸素貝葉斯分類演算法訓練和測試:

1 對郵件的文字劃分成詞彙,長度小於2的預設為不是詞彙,過濾掉即可。返回一串小寫的拆分後的郵件資訊。

def textParse(bigString):    #input is big string, #output is word list
    import re
    listOfTokens = re.split(r'\W*', bigString)    return [tok.lower() for tok in listOfTokens if len(tok) > 2] 

2 文件詞袋模型:使用陣列代替集合資料結構,可以儲存詞彙頻率資訊。

def bagOfWords2VecMN(vocabList, inputSet):

    returnVec = [0]*len(vocabList)

    for word in inputSet:

        if word in vocabList:

            returnVec[vocabList.index(word)] += 1

    return returnVec

3 輸入為25封正常郵件和25封垃圾郵件。50封郵件中隨機選取10封作為測試樣本,剩餘40封作為訓練樣本。

   訓練模型:40封訓練樣本,訓練出先驗概率條件概率

   測試模型:遍歷10個測試樣本,計算垃圾郵件分類的正確率。

def spamTest():

    docList=[]; classList = []; fullText =[]

    for i in range(1,26):

        wordList = textParse(open('email/spam/%d.txt' % i).read())

        # print wordList

        docList.append(wordList)

        fullText.extend(wordList)

        classList.append(1)

        wordList = textParse(open('email/ham/%d.txt' % i).read())

        docList.append(wordList)

        fullText.extend(wordList)

        classList.append(0)

    vocabList = createVocabList(docList)#create vocabulary

    trainingSet = range(50); testSet=[]           #create test set

    for i in range(10):

        randIndex = int(random.uniform(0,len(trainingSet)))

        testSet.append(trainingSet[randIndex])

        del(trainingSet[randIndex])  

    trainMat=[]; trainClasses = []

    for docIndex in trainingSet:#train the classifier (get probs) trainNB0

        trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex]))

        trainClasses.append(classList[docIndex])

    p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))

    errorCount = 0

    for docIndex in testSet:        #classify the remaining items

        wordVector = bagOfWords2VecMN(vocabList, docList[docIndex])

        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:

            errorCount += 1

            print "classification error",docList[docIndex]

    print 'the error rate is: ',float(errorCount)/len(testSet)

    #return vocabList,fullText

 近期熱文

... ...

遲做總比不做好;晚來總比不來強。

0?wx_fmt=jpeg

更多幹貨內容請關注微信公眾號“AI 深入淺出”

長按二維碼關注