機器學習實戰——基於概率論的分類方法:樸素貝葉斯(二)
阿新 • • 發佈:2018-12-19
使用貝葉斯過濾垃圾郵件
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個樣本作為測試集,剩餘的用作訓練集。利用詞典構建各個樣本的詞向量,並將其新增到訓練矩陣中,通過訓練矩陣和標籤列表,得到各個詞對應的概率權重列表。最後得到測試集的預測值,進而求得錯誤率。