1. 程式人生 > >機器學習實戰——基於概率論的分類方法:樸素貝葉斯(二)

機器學習實戰——基於概率論的分類方法:樸素貝葉斯(二)

                                      使用貝葉斯過濾垃圾郵件

1.準備資料:切分文字

將字串切分為詞列表時,倘若沒有split引數,則標點符號也會被當成詞的一部分,可以使用正則表示式來切分句子,其中分隔符是除了單詞,數字之外的任意字串。

>>>import re

>>> regEx = re.compile('\\W*')

>>>listOfTokens = regEx.split(mySent)

>>>[tok.lower()  for tok in listOftokens if len(tok)>0]

在實際的解析過程中,比如要用更高階的過濾器對HTML和URL物件進行處理

2.測試演算法:使用樸素貝葉斯進行交叉驗證

使用本地的資料,將郵件內容存放在txt檔案中,只對郵件的第一行進行驗證。spam和ham的資料夾下分別儲存了兩類郵件。

#本地檔案解析以及完整的垃圾郵件測試函式
def textParse(bigString):
    import re
    #利用正則表示式去除標點,防止其作為分割符
    listOfTokens = re.split(r"\W*",bigString)
    #長度>2且全部轉為小寫
    return [tok.lower() for tok in listOfTokens if len(tok)>2]
def spamTest():
    docList = []
    classList = []
    fullText = []
    for i in range(1,26):
        wordList = textParse(open('email/spam/%d.txt' % i).read())
        #append方法是將引數整體作為元素進行新增
        #extend方法是將引數拆解作為元素新增,可能有重複元素
        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)
    vocablList = createVocabList(docList)
    trainingSet = [i for i in range(50)]
    testSet = []
    #隨機挑取10個隨機數作為要測試的樣本索引
    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:
        trainMat.append(setOfWord2Vec(vocablList,docList[docIndex]))
        trainClasses.append(classList[docIndex])
    #訓練得到各個詞對應的概率權重大小
    p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses))
    errorCount = 0
    for docIndex in testSet:
        wordVector = setOfWord2Vec(vocablList,docList[docIndex])
        #將預測值與實際值進行比較
        if classifyNB(array(wordVector),p0V,p1V,pSpam) != classList[docIndex]:
            errorCount += 1
    print('the error rate is :',float(errorCount)/len(testSet))

textParse()函式接受一個大寫字串並將其解析為單詞列表spamTest()對貝葉斯垃圾郵件分類器進行自動化處理,首先構建一個測試集和訓練集,總共50個郵件,然後得到所有詞的詞典,隨機選取10個樣本作為測試集,剩餘的用作訓練集。利用詞典構建各個樣本的詞向量,並將其新增到訓練矩陣中,通過訓練矩陣和標籤列表,得到各個詞對應的概率權重列表。最後得到測試集的預測值,進而求得錯誤率。