自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

手把手教你用 Python 和 Scikit-Learn 實(shí)現(xiàn)垃圾郵件過(guò)濾

移動(dòng)開(kāi)發(fā) 后端
文本挖掘(Text Mining,從文字中獲取信息)是一個(gè)比較寬泛的概念,這一技術(shù)在如今每天都有海量文本數(shù)據(jù)生成的時(shí)代越來(lái)越受到關(guān)注。

 [[197427]]

文本挖掘(Text Mining,從文字中獲取信息)是一個(gè)比較寬泛的概念,這一技術(shù)在如今每天都有海量文本數(shù)據(jù)生成的時(shí)代越來(lái)越受到關(guān)注。目前,在機(jī)器學(xué)習(xí)模型的幫助下,包括情緒分析,文件分類,話題分類,文本總結(jié),機(jī)器翻譯等在內(nèi)的諸多文本挖掘應(yīng)用都已經(jīng)實(shí)現(xiàn)了自動(dòng)化。

在這些應(yīng)用中,垃圾郵件過(guò)濾算是初學(xué)者實(shí)踐文件分類的一個(gè)很不錯(cuò)的開(kāi)始,例如 Gmail 賬戶里的“垃圾郵箱”就是一個(gè)垃圾郵件過(guò)濾的現(xiàn)實(shí)應(yīng)用。下面我們將基于一份公開(kāi)的郵件數(shù)據(jù)集 Ling-spam,編寫(xiě)一個(gè)垃圾郵件的過(guò)濾器。Ling-spam 數(shù)據(jù)集的下載地址如下:

http://t.cn/RKQBl9c

這里我們已經(jīng)從 Ling-spam 中提取了相同數(shù)量的垃圾郵件和非垃圾郵件,具體下載地址如下:

http://t.cn/RKQBkRu

下面我們將通過(guò)以下幾個(gè)步驟,編寫(xiě)一個(gè)現(xiàn)實(shí)可用的垃圾郵件過(guò)濾器。

1. 準(zhǔn)備文本數(shù)據(jù);

2. 創(chuàng)建詞典(word dictionary);

3. 特征提??;

4. 訓(xùn)練分類器。

***,我們會(huì)通過(guò)一個(gè)測(cè)試數(shù)據(jù)集對(duì)過(guò)濾器進(jìn)行驗(yàn)證。

  1. 準(zhǔn)備文本數(shù)據(jù)

這里我們將數(shù)據(jù)集分成了訓(xùn)練集(702封郵件)和測(cè)試集(260封郵件)兩部分,其中垃圾和非垃圾郵件各占 50%。這里因?yàn)槊總€(gè)垃圾郵件的數(shù)據(jù)集都以 spmsg 命名,因此很容易區(qū)分。

在大部分的文本挖掘問(wèn)題中,文本清理都是***步,即首先要清理掉那些與我們的目標(biāo)信息無(wú)關(guān)的詞句,本例中也一樣。通常郵件里一般都會(huì)包含很多無(wú)用的字符,比如標(biāo)點(diǎn)符號(hào),停用詞,數(shù)字等等,這些字符對(duì)檢測(cè)垃圾郵件沒(méi)什么幫助,因此我們需要將它們清理掉。這里 Ling-spam 數(shù)據(jù)集里的郵件已經(jīng)經(jīng)過(guò)了以下幾個(gè)步驟的處理:

a) 清除停用詞 --- 像 "and", "the", "of" 等這些停用詞在英語(yǔ)語(yǔ)句中非常常見(jiàn)。然而,這些停用詞對(duì)于判定郵件的真實(shí)身份并沒(méi)有什么卵用,所以這些詞已經(jīng)從郵件中被移除。

b) 詞形還原 --- 這是一種把同一個(gè)詞的不同形式組合在一起,以便被當(dāng)做一個(gè)單獨(dú)項(xiàng)目來(lái)分析的過(guò)程。舉個(gè)栗子,"include", "includes" 和 "included" 就可以全部用 "include" 來(lái)代表。與此同時(shí),語(yǔ)句的上下文含義也會(huì)通過(guò)詞形還原的方法保留下來(lái),這一點(diǎn)不同于詞干提取 (stemming) 的方法(注:詞干提取是另一種文本挖掘的方法,此法不考慮語(yǔ)句的含義)。

此外,我們還需要移除一些非文字類的符號(hào)(non-words),比如標(biāo)點(diǎn)符號(hào)或者特殊字符之類的。要實(shí)現(xiàn)這一步有很多方法,這里,我們將首先創(chuàng)建一個(gè)詞典(creating a dictionary),之后再移除這些非文字類的符號(hào)。需要指出的是,這種做法其實(shí)非常方便,因?yàn)楫?dāng)你手上有了一個(gè)詞典之后,對(duì)于每一種非文字類符號(hào),只需要移除一次就 ok 了。

  2. 創(chuàng)建詞典(Creating word dictionary)

一個(gè)數(shù)據(jù)集里的樣本郵件一般長(zhǎng)這樣:

  1. Subject: posting 
  2.  
  3. hi , ' m work phonetics project modern irish ' m hard source . anyone recommend book article english ? ' , specifically interest palatal ( slender ) consonant , work helpful too . thank ! laurel sutton ( sutton @ garnet . berkeley . edu 

你會(huì)發(fā)現(xiàn)郵件的***行是標(biāo)題,從第三行開(kāi)始才是正文。這里我們只在郵件正文內(nèi)容的基礎(chǔ)上做文本分析,來(lái)判定該郵件是否為垃圾郵件。***步,我們需要?jiǎng)?chuàng)建一個(gè)文字的詞典和文字出現(xiàn)的頻率。為了創(chuàng)建這樣一個(gè)“詞典”,這里我們利用了訓(xùn)練集里的 700 封郵件。具體實(shí)現(xiàn)詳見(jiàn)下面這個(gè) Python 函數(shù):

  1. def make_Dictionary(train_dir): 
  2.     emails = [os.path.join(train_dir,f) for f in os.listdir(train_dir)]     
  3.     all_words = []        
  4.     for mail in emails:     
  5.         with open(mail) as m: 
  6.             for i,line in enumerate(m): 
  7.                 if i == 2:  #Body of email is only 3rd line of text file 
  8.                     words = line.split() 
  9.                     all_words += words 
  10.      
  11.     dictionary = Counter(all_words) 
  12.     # Paste code for non-word removal here(code snippet is given below)  
  13.     return dictionary 

詞典創(chuàng)建好之后,我們只要在上面函數(shù)的基礎(chǔ)上再加幾行代碼,就可以移除之前提到的那些非文字類符號(hào)了。這里我還順手刪掉了一些與垃圾郵件的判定無(wú)關(guān)的單字符,具體參見(jiàn)如下的代碼,注意這些代碼要附在 def make_Dictionary(train_dir) 函數(shù)的末尾。

  1. list_to_remove = dictionary.keys() 
  2. for item in list_to_remove: 
  3.     if item.isalpha() == False:  
  4.         del dictionary[item] 
  5.     elif len(item) == 1
  6.         del dictionary[item] 
  7. dictionary = dictionary.most_common(3000

這里通過(guò)輸入 print dictionary 指令就可以輸出詞典。需要注意的是,你在打印輸出的詞典里可能會(huì)看到許多無(wú)關(guān)緊要的詞,這一點(diǎn)無(wú)需擔(dān)心,因?yàn)槲覀冊(cè)诤罄m(xù)的步驟中總是有機(jī)會(huì)對(duì)其進(jìn)行調(diào)整的。另外,如果你是嚴(yán)格按照上文提到的數(shù)據(jù)集操作的話,那么你的詞典里應(yīng)該會(huì)有以下這些高頻詞(本例中我們選取了頻率***的 3000 個(gè)詞):

[('order', 1414), ('address', 1293), ('report', 1216), ('mail', 1127), ('send', 1079), ('language', 1072), ('email', 1051), ('program', 1001), ('our', 987), ('list', 935), ('one', 917), ('name', 878), ('receive', 826), ('money', 788), ('free', 762)

  3. 特征提取

詞典準(zhǔn)備好之后,我們就可以對(duì)訓(xùn)練集里的每一封郵件提取維度是 3000 的詞數(shù)向量 word count vector(這個(gè)向量就是我們的特征),每一個(gè)詞數(shù)向量都包含之前選定的 3000 個(gè)高頻詞具體的出現(xiàn)頻率。當(dāng)然,你可能猜到了,大部分出現(xiàn)的頻率應(yīng)該會(huì)是 0。舉個(gè)栗子:比如我們字典里有 500 個(gè)詞,每個(gè)詞數(shù)向量包含了訓(xùn)練集里這 500 個(gè)詞的出現(xiàn)頻率。假設(shè)訓(xùn)練集有一組文本:“Get the work done, work done”。那么,這句話對(duì)應(yīng)的詞數(shù)向量應(yīng)該是這樣的:[0,0,0,0,0,…….0,0,2,0,0,0,……,0,0,1,0,0,…0,0,1,0,0,……2,0,0,0,0,0]。在這里,句中的每個(gè)詞出現(xiàn)的頻率都能顯示出來(lái):這些詞分別對(duì)應(yīng)長(zhǎng)度為 500 的詞數(shù)向量中的第 296,359,415 和 495 的位置,其他位置顯示為 0。

下面這個(gè) python 函數(shù)會(huì)幫助我們生成一個(gè)特征向量矩陣,該矩陣有 700 行 3000 列。其中每一行代表訓(xùn)練集中 700 封郵件的的每一封郵件,每一列代表詞典中的 3000 個(gè)關(guān)鍵詞。在 “ij” 位置上的值代表了詞典中第 j 個(gè)詞在該郵件(第 i 封)中出現(xiàn)的次數(shù)。

  1. def extract_features(mail_dir):  
  2.     files = [os.path.join(mail_dir,fi) for fi in os.listdir(mail_dir)] 
  3.     features_matrix = np.zeros((len(files),3000)) 
  4.     docID = 0
  5.     for fil in files: 
  6.       with open(fil) as fi: 
  7.         for i,line in enumerate(fi): 
  8.           if i == 2
  9.             words = line.split() 
  10.             for word in words: 
  11.               wordID = 0 
  12.               for i,d in enumerate(dictionary): 
  13.                 if d[0] == word: 
  14.                   wordID = i 
  15.                   features_matrix[docID,wordID] = words.count(word) 
  16.         docID = docID + 1      
  17.     return features_matrix 

 

4.訓(xùn)練分類器

在這里我們會(huì)使用 scikit-learn 機(jī)器學(xué)習(xí)庫(kù)來(lái)訓(xùn)練分類器,scikit-learn 庫(kù)的相關(guān)鏈接如下:

http://t.cn/SMzAoZ

這是一個(gè)綁定在第三方 python 發(fā)行版 Anaconda 的開(kāi)源機(jī)器學(xué)習(xí)庫(kù),可以跟隨 Anaconda 一同下載安裝,或者也可以按照以下鏈接中的提示獨(dú)立安裝:

http://t.cn/8kkrVlQ

安裝好了之后,我們只需要將其 import 到我們的程序中就可以使用了。

這里我們訓(xùn)練了兩個(gè)模型,分別是樸素貝葉斯分類器和 SVM(支持向量機(jī))。樸素貝葉斯分類器是一個(gè)傳統(tǒng)的監(jiān)督型概率分類器,在文本分類的場(chǎng)景中非常常用,它基于貝葉斯定理,假設(shè)每一對(duì)特征都是相互獨(dú)立的。SVM 是監(jiān)督型的二分類器,面對(duì)特征數(shù)量較多的場(chǎng)景時(shí)非常有效,其最終目標(biāo)是從訓(xùn)練數(shù)據(jù)中分離出一組子集,稱為支持向量(分離超平面的邊界)。判定測(cè)試數(shù)據(jù)最終類別的 SVM 決策函數(shù)正是基于該支持向量和內(nèi)核技巧(kernel trick)的。

分類器訓(xùn)練完成后,我們可以在測(cè)試集上測(cè)試模型的性能。這里我們?yōu)闇y(cè)試集中的每封郵件提取字?jǐn)?shù)向量,然后用訓(xùn)練好的樸素貝葉斯分類器和 SVM 模型,預(yù)測(cè)它的類別(普通郵件或垃圾郵件)。下面是垃圾郵件分類器的完整 python 代碼,另外還需要包含我們?cè)诓襟E 2 和步驟 3 中定義的兩個(gè)函數(shù)。

  1. import os 
  2. import numpy as np 
  3. from collections import Counter 
  4. from sklearn.naive_bayes import MultinomialNB, GaussianNB, BernoulliNB 
  5. from sklearn.svm import SVC, NuSVC, LinearSVC 
  6. from sklearn.metrics import confusion_matrix  
  7. # Create a dictionary of words with its frequency 
  8.  
  9. train_dir = 'train-mails' 
  10. dictionary = make_Dictionary(train_dir) 
  11.  
  12. # Prepare feature vectors per training mail and its labels 
  13.  
  14. train_labels = np.zeros(702
  15. train_labels[351:701] = 1 
  16. train_matrix = extract_features(train_dir) 
  17.  
  18. # Training SVM and Naive bayes classifier 
  19.  
  20. model1 = MultinomialNB() 
  21. model2 = LinearSVC() 
  22. model1.fit(train_matrix,train_labels) 
  23. model2.fit(train_matrix,train_labels) 
  24.  
  25. # Test the unseen mails for Spam 
  26. test_dir = 'test-mails' 
  27. test_matrix = extract_features(test_dir) 
  28. test_labels = np.zeros(260
  29. test_labels[130:260] = 1 
  30. result1 = model1.predict(test_matrix) 
  31. result2 = model2.predict(test_matrix) 
  32. print confusion_matrix(test_labels,result1) 
  33. print confusion_matrix(test_labels,result2) 

 

性能測(cè)試

這里我們的測(cè)試集中包含 130 封垃圾郵件和 130 封非垃圾郵件,如果你已經(jīng)順利完成了之前的所有步驟,那么你將會(huì)得到如下的結(jié)果。這里顯示的是兩個(gè)模型在測(cè)試數(shù)據(jù)中的混淆矩陣,對(duì)角元素代表了正確識(shí)別的郵件數(shù),非對(duì)角元素代表的則是錯(cuò)誤的分類。

 

混淆矩陣

可以看到,兩個(gè)模型在測(cè)試集上有著相近的性能,但 SVM 更傾向垃圾郵件的判定。需要注意的是,這里的測(cè)試數(shù)據(jù)集既沒(méi)有用于創(chuàng)建字典,也沒(méi)有用于模型訓(xùn)練。

  拓展

感興趣的朋友可以按照上文所述的步驟進(jìn)行一些拓展,這里介紹拓展相關(guān)的數(shù)據(jù)庫(kù)和結(jié)果。

拓展使用的是已經(jīng)預(yù)處理好的 Euron-spam 數(shù)據(jù)庫(kù),其中包含了 6 個(gè)目錄,33716 封郵件,每個(gè)目錄中都包含非垃圾郵件和垃圾郵件子目錄,非垃圾郵件和垃圾郵件的總數(shù)分別為 16545 封和 17171 封。Euron-spam 庫(kù)的下載鏈接如下:

http://t.cn/RK84mv6

需要注意的是,由于 Euron-spam 數(shù)據(jù)庫(kù)的組織形式有別于上文提到的 ling-spam 庫(kù),因此上文的一些函數(shù)也需要做少量的修改才能應(yīng)用于 Euron-spam。

這里我們將 Euron-spam 數(shù)據(jù)庫(kù)按照 3:2 的比例分為訓(xùn)練集和測(cè)試集,按照上文的步驟,我們?cè)?13478 封測(cè)試郵件中得到了如下結(jié)果:

 

結(jié)果

可以看到,SVM 的表現(xiàn)略勝于樸素貝葉斯。

  總結(jié)

在本文中我們盡量保持簡(jiǎn)單易懂的敘述,省略了許多技術(shù)性強(qiáng)的講解和名詞。我們希望這是一篇簡(jiǎn)單易懂的教程,希望這篇教程可以對(duì)文本分析感興趣的初學(xué)者們有所裨益。

有些朋友可能會(huì)對(duì)樸素貝葉斯模型和 SVM 模型背后的數(shù)學(xué)原理感到好奇,這里需要指出的是,SVM 在數(shù)學(xué)上屬于比較復(fù)雜的模型,而樸素貝葉斯則相對(duì)更容易理解一些。我們當(dāng)然鼓勵(lì)對(duì)數(shù)學(xué)原理感興趣的朋友們深入探索,關(guān)于這些數(shù)學(xué)模型網(wǎng)上有非常詳細(xì)的教程和實(shí)例。除此之外,采用不同的方式實(shí)現(xiàn)同一個(gè)目標(biāo),也是一種很好的研究方法。例如可以調(diào)節(jié)如下一些參數(shù),觀察它們對(duì)垃圾郵件過(guò)濾的實(shí)際效果的影響:

a) 訓(xùn)練數(shù)據(jù)的大小

b) 詞典的大小

c) 不同的機(jī)器學(xué)習(xí)模型,包括 GaussianNB,BernoulliNB,SVC

d) 不同的 SVM 模型參數(shù)

e) 刪除無(wú)關(guān)緊要的詞來(lái)改進(jìn)詞典 (例如手動(dòng)刪除)

f) 采用其他特征模型 (尋找 td-idf)

***,博客中提到的完整 python 代碼詳見(jiàn)如下鏈接:

http://t.cn/R6ZeuiN

若有問(wèn)題,歡迎在文末留言討論。

本文轉(zhuǎn)自雷鋒網(wǎng),原文來(lái)自一篇國(guó)外大神的博客,由雷鋒網(wǎng)字幕組 彭艷蕾、林立宏 兩位組員共同編譯完成。

責(zé)任編輯:張子龍 來(lái)源: 雷鋒網(wǎng)
相關(guān)推薦

2021-08-09 13:31:25

PythonExcel代碼

2021-12-11 20:20:19

Python算法線性

2021-05-17 21:30:06

Python求均值中值

2022-10-19 14:30:59

2021-05-10 06:48:11

Python騰訊招聘

2021-03-23 09:05:52

PythonExcelVlookup

2021-02-02 13:31:35

Pycharm系統(tǒng)技巧Python

2021-02-10 09:34:40

Python文件的壓縮PyCharm

2011-03-28 16:14:38

jQuery

2021-02-04 09:00:57

SQLDjango原生

2021-02-06 14:55:05

大數(shù)據(jù)pandas數(shù)據(jù)分析

2017-10-27 10:29:35

人臉識(shí)別UbuntuPython

2022-08-04 10:39:23

Jenkins集成CD

2017-10-29 21:43:25

人臉識(shí)別

2021-04-01 09:02:38

Python小說(shuō)下載網(wǎng)絡(luò)爬蟲(chóng)

2018-12-29 09:38:16

Python人臉檢測(cè)

2021-01-27 21:55:13

代碼參數(shù)值ECharts

2009-04-22 09:17:19

LINQSQL基礎(chǔ)

2021-01-21 09:10:29

ECharts柱狀圖大數(shù)據(jù)

2021-01-08 10:32:24

Charts折線圖數(shù)據(jù)可視化
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)