當前位置:
首頁 > 知識 > 手把手教你用Python和Scikit-learn 實現垃圾郵件過濾

手把手教你用Python和Scikit-learn 實現垃圾郵件過濾

歡迎大家參與在留言區交流

本周內(截止至7月23日晚24點)

本公眾號本周發布的所有文章,留言獲贊最多者

AI研習社送西瓜書(《機器學習》周志華)一本

文本挖掘(Text Mining,從文字中獲取信息)是一個比較寬泛的概念,這一技術在如今每天都有海量文本數據生成的時代越來越受到關注。目前,在機器學習模型的幫助下,包括情緒分析,文件分類,話題分類,文本總結,機器翻譯等在內的諸多文本挖掘應用都已經實現了自動化。

在這些應用中,垃圾郵件過濾算是初學者實踐文件分類的一個很不錯的開始,例如 Gmail 賬戶里的「垃圾郵箱」就是一個垃圾郵件過濾的現實應用。下面我們將基於一份公開的郵件數據集 Ling-spam,編寫一個垃圾郵件的過濾器。Ling-spam 數據集的下載地址如下:

http://t.cn/RKQBl9c

這裡我們已經從 Ling-spam 中提取了相同數量的垃圾郵件和非垃圾郵件,具體下載地址如下:

http://t.cn/RKQBkRu

下面我們將通過以下幾個步驟,編寫一個現實可用的垃圾郵件過濾器。

1.準備文本數據;

2.創建詞典(word dictionary);

3.特徵提取;

4.訓練分類器。

最後,我們會通過一個測試數據集對過濾器進行驗證。

1. 準備文本數據

這裡我們將數據集分成了訓練集(702封郵件)和測試集(260封郵件)兩部分,其中垃圾和非垃圾郵件各占 50%。這裡因為每個垃圾郵件的數據集都以 spmsg 命名,因此很容易區分。

在大部分的文本挖掘問題中,文本清理都是第一步,即首先要清理掉那些與我們的目標信息無關的詞句,本例中也一樣。通常郵件里一般都會包含很多無用的字元,比如標點符號,停用詞,數字等等,這些字元對檢測垃圾郵件沒什麼幫助,因此我們需要將它們清理掉。這裡 Ling-spam 數據集里的郵件已經經過了以下幾個步驟的處理:

a) 清除停用詞--- 像 "and", "the", "of" 等這些停用詞在英語語句中非常常見。然而,這些停用詞對於判定郵件的真實身份並沒有什麼卵用,所以這些詞已經從郵件中被移除。

b) 詞形還原--- 這是一種把同一個詞的不同形式組合在一起,以便被當做一個單獨項目來分析的過程。舉個栗子,"include", "includes" 和 "included" 就可以全部用 "include" 來代表。與此同時,語句的上下文含義也會通過詞形還原的方法保留下來,這一點不同於詞幹提取 (stemming) 的方法(註:詞幹提取是另一種文本挖掘的方法,此法不考慮語句的含義)。

此外,我們還需要移除一些非文字類的符號(non-words),比如標點符號或者特殊字元之類的。要實現這一步有很多方法,這裡,我們將首先創建一個詞典(creating a dictionary),之後再移除這些非文字類的符號。需要指出的是,這種做法其實非常方便,因為當你手上有了一個詞典之後,對於每一種非文字類符號,只需要移除一次就 ok 了。

2. 創建詞典(Creating word dictionary)

一個數據集里的樣本郵件一般長這樣:

Subject: posting

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

你會發現郵件的第一行是標題,從第三行開始才是正文。這裡我們只在郵件正文內容的基礎上做文本分析,來判定該郵件是否為垃圾郵件。第一步,我們需要創建一個文字的詞典和文字出現的頻率。為了創建這樣一個「詞典」,這裡我們利用了訓練集里的 700 封郵件。具體實現詳見下面這個 Python 函數:

def make_Dictionary(train_dir):

all_words = []

for mail in emails:

with open(mail) as m:

for i,line in enumerate(m):

if i == 2: #Body of email is only 3rd line of text file

words = line.split()

all_words += words

dictionary = Counter(all_words)

# Paste code for non-word removal here(code snippet is given below)

return dictionary

詞典創建好之後,我們只要在上面函數的基礎上再加幾行代碼,就可以移除之前提到的那些非文字類符號了。這裡我還順手刪掉了一些與垃圾郵件的判定無關的單字元,具體參見如下的代碼,注意這些代碼要附在 def make_Dictionary(train_dir) 函數的末尾。

list_to_remove = dictionary.keys()

for item in list_to_remove:

if item.isalpha() == False:

del dictionary[item]

elif len(item) == 1:

del dictionary[item]

dictionary = dictionary.most_common(3000)

這裡通過輸入 print dictionary 指令就可以輸出詞典。需要注意的是,你在列印輸出的詞典里可能會看到許多無關緊要的詞,這一點無需擔心,因為我們在後續的步驟中總是有機會對其進行調整的。另外,如果你是嚴格按照上文提到的數據集操作的話,那麼你的詞典里應該會有以下這些高頻詞(本例中我們選取了頻率最高的 3000 個詞):

[( 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. 特徵提取

詞典準備好之後,我們就可以對訓練集里的每一封郵件提取維度是 3000 的詞數向量 word count vector(這個向量就是我們的特徵),每一個詞數向量都包含之前選定的 3000 個高頻詞具體的出現頻率。當然,你可能猜到了,大部分出現的頻率應該會是 0。舉個栗子:比如我們字典里有 500 個詞,每個詞數向量包含了訓練集里這 500 個詞的出現頻率。假設訓練集有一組文本:「Get the work done, work done」。那麼,這句話對應的詞數向量應該是這樣的:[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]。在這裡,句中的每個詞出現的頻率都能顯示出來:這些詞分別對應長度為 500 的詞數向量中的第 296,359,415 和 495 的位置,其他位置顯示為 0。

下面這個 python 函數會幫助我們生成一個特徵向量矩陣,該矩陣有 700 行 3000 列。其中每一行代表訓練集中 700 封郵件的的每一封郵件,每一列代表詞典中的 3000 個關鍵詞。在 「ij」 位置上的值代表了詞典中第 j 個詞在該郵件(第 i 封)中出現的次數。

def extract_features(mail_dir):

features_matrix = np.zeros((len(files),3000))

docID = 0;

for fil in files:

with open(fil) as fi:

for i,line in enumerate(fi):

if i == 2:

words = line.split()

for word in words:

wordID = 0

for i,d in enumerate(dictionary):

if d[0] == word:

wordID = i

features_matrix[docID,wordID] = words.count(word)

docID = docID + 1

return features_matrix

4.訓練分類器

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

Python 為何能坐穩 AI 時代頭牌語言
如果十年前擁有這些技術,你可能比馬雲還要富:python3開發網路爬蟲(一)
2017開發者生態報告:Python 是最多人想嘗試的語言
從零開始教你用 Python 做詞雲

TAG:Python |

您可能感興趣

垃圾郵件活動濫用SettingContent-ms傳播FlawedAmmyy RAT
如何用 Python 讀取 Outlook 中的電子郵件
如何開啟Gmail的Smart Compose並讓Google AI編寫您的郵件
第一封電子郵件從太空發出,用的是蘋果電腦Macintosh Portable
Prime Day已開始備戰!你收到提醒Lightning Deal促銷郵件了嗎?
我的個人電子郵件系統設置:notmuch、mbsync、Postfix和 dovecot
Salmon:一個基於Python語言的郵件伺服器
Essential 收購郵件服務初創公司 CloudMagic
Essential收購電子郵件初創企業CloudMagic
Localhost環境下使用Django send_mail發送郵件-以QQ和163郵箱為例
PHP 使用 phpmailer 發送電子郵件
郵件處理工具 Spark 登陸 Android 平台
Bertin IT發布用於交換敏感數據的高安全性電子郵件網關:Crypto Crossing(R)
Google使用TensorFlow來阻止每天1億多封Gmail垃圾郵件
針對同時通過惡意郵件傳播的Emotet和Trickbot的分析
微軟內部郵件曝光,Surface Phone或真存在
玩家郵件請求遊戲打折,Devolver Digital就真的照辦了
Microsoft Teams突然下線4小時:企業無奈重新啟用電子郵件
Python之Bilibili自動更新郵件提醒並任務欄圖標
Linux中Postfix反病毒和垃圾郵件工具