天天看點

《Arduino家居安全系統建構實戰》——2.1 挑戰:建構一個垃圾郵件檢測引擎

本節書摘來異步社群《機器學習項目開發實戰》一書中的第2章,第2.1節,作者:【美】mathias brandewinder(馬蒂亞斯·布蘭德溫德爾),更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

我們将要處理的文檔不是電子郵件,而是文本消息。我們的目标是使用來自英國的真實sms(短消息服務)資料集發現垃圾短信,這些消息是我們從加州大學歐文分校機器學習知識庫中找到的。

■ 附注:

uci機器學習知識庫由加州大學歐文分校的機器學習與智能系統中心于1987年啟動。你可以在<code>http://archive.ics.uci.edu/ml/</code>中找到這個知識庫,它包含将近300個幹淨、文檔齊備的資料集,可以按照大小、特征類型等條件搜尋群組織。這是一個很有趣的機器學習資源,包含了許多常常用作算法性能評估基準的“經典”資料集。

在讨論使用哪個模型之前,首先來觀察一下資料。資料集可以從<code>http://1drv.ms/1uzmpll</code>下載下傳(這就是uci知識庫中原始檔案的複制品,原始檔案可以在<code>http://archive.ics.uci.edu/ml/ datasets/sms+spam+collection</code>上找到)。它作為單個文本檔案儲存,名為smsspamcollection(沒有檔案擴充名),包含5574條真實的文本消息。每行是一個sms,标記為“ham”(非垃圾短信)或者“spam”(垃圾短信)。下面是前面幾行:

true ok lar... joking wif u oni... ,<code>`</code>

你怎麼可能猜出這裡的“true”代表什麼?另一個潛在的問題是,如果我們需要增加更多的類别(如非垃圾短信、垃圾短信和有歧義的資訊),布爾值無法擴充。

機器學習的難點在于不能增加額外、不必要的複雜性。是以,我們将用f#的可區分聯合(有時我也将它稱作du)表示标簽。如果你之前從未見過可區分聯合,可以近似地将其看作c#枚舉類型。可區分聯合和枚舉一樣,都定義一組獨特的情況,但是功能強大得多。這種類比對du不公平,但是足以幫助我們起步。

我們先使用可以在fsi中運作的例子,簡單地說明du的工作方式。定義du和定義其他類型一樣簡單:

type doctype =

上述語句定義了一個簡單類型doctype,它隻能取兩個值:spam或者ham。我喜歡可區分聯合的主要原因之一是它們和模式比對配合得很好,可編寫以非常清晰的風格描述業務領域的代碼。例如,在我們的例子中,訓練集中的每個示例都是非垃圾短信或者垃圾短信,并包含真實消息的内容。我們可以将其表示為一個元組,每個示例是一個doctype和一個字元串,按照這一路線處理消息示例,可以在f# interactive視窗中嘗試:

identify (ham,"good message");;<code>`</code>

你應該看到如下結果:

open system.io

let parsedoctype (label:string) =

let parseline (line:string) =

let filename = "smsspamcollection"

let path = source_directory + @"....data" + filename

let dataset =

此時,你應該可以選擇腳本中剛剛編寫的所有代碼,在f# interactive視窗中執行,産生如下結果:

繼續閱讀