Spam Or Ham讀書筆記
《Machine Learning Projects for .NET Developers》書中的第二章,用了樸素貝葉斯的方法來識別簡訊是垃圾資訊還是正常資訊。
章節從零開始講,所以在最開始考慮如何入手這個問題。分析了測試資料,發現垃圾簡訊有一些在正常簡訊中不太會用到的單詞,用了FREE
(全大寫)做測試。最後發現結果感人,有85%的正確率。將此作為baseline,接下來用更科學的方式,再怎麼差也不能比baseline差。
通過決策樹,分析通過垃圾簡訊中有FREE的概率能不能反推得到簡訊中有FREE這個詞,這條簡訊是垃圾簡訊的概率是多少。開始引入(樸素)貝葉斯定理。
公式比較簡單易懂:
P(A|B) = P(B|A) x P(A) / P(B)
又只用FREE一個單詞似乎不科學,那可以使用多個單詞,多個單詞出現的概率獨立。那就可以使用公式
P(A and B) = P(A) x P(B)
(A B相互獨立 也就是交集是空)
在想到處理一些稀有單詞,可能單詞不在測試資料中,可以引入拉普拉斯平滑,這裡我直接上程式碼好了:
let laplace count total = float (count+1) / float (total+1)
也就是對分子分母各加1,這個函式本身不會改變原先結果的大小關係,所以使用也沒什麼問題。
直接使用公式計算不是很方便所以要對公式進行化簡。具體化簡的過程可以參考書本,我這裡只給出最後的結果:
制定的工作流:
上面free、txt是通過實現分類器,給定一些用來做分類的token(這裡就是free和txt),統計訓練集得到每個token的Laplace(SMS contains token|spam)
和Laplace(SMS contains token|ham)
然後對實際資料進行上面score函式的運算就可以了
第一個實現,分詞器用了最簡單的取每個單詞並且小寫化,用了一個單詞txt做分類用的token(也就是流程圖裡只有txt),得到的結果是86%(小數點後面我不記得了...86.5%好像...)
可以發現實現比baseline好了一點,但還是不夠。接下去考慮優化。
使用測試資料裡所有的token作為分類用token,結果效果更差了,所以token的選擇要更有針對性。
把分詞器變為取每個單詞,不區分大小寫,考慮到垃圾簡訊常常使用全大寫的單詞,效果所有提升。
在第一個優化中,想到free主要出現在垃圾簡訊中,所以可以考慮取垃圾簡訊和正常簡訊的出現次數top N的token,得到的結果達到90%。
分析top N的token,發現會有一大堆you、the、in之類的詞,考慮用停用詞。最後簡化將垃圾簡訊和正常簡訊的top N的結果取交集得到都出現的詞,然後取並集,再去除之間的交集。
程式碼如下:
let topHam = ham |> top (hamCount / 10) casedTokenizer
let topSpam = spam |> top (spamCount / 10) casedTokenizer
let topTokens = Set.union topHam topSpam
let commonTokens = Set.intersect topHam topSpam
let specificTokens = Set.difference topTokens commonTokens
結果就更好了。
接下去的優化分析了出現最少的topN token,分析到垃圾資訊中會有大量的電話號碼,而正常簡訊中更多的是一些數字。針對電話號碼做單獨的處理,修改分詞器,讓分詞器再檢查到電話號碼時變為一個統一的token__PHONE__
,取這個名字是不想讓普通的token和他衝突。得到了更好的結果。
後來的優化涉及到考慮簡訊的長度,因為簡訊的長度是一個連續的值,所以對其用區間的方式變為幾個分離的值。接著套用貝葉斯的方法。
P(長度的分類/Spam) -> P(Spam/長度的分類)
,加入到上面的公式當中。效果我忘了,因為看書的時候這部分好像被我跳過自己沒敲程式碼。
最後是關於錯誤率帶來的影響的問題,是識別垃圾更重要還是識別正確資訊更重要。後來得到正確簡訊的識別率更重要。於是可以將正確簡訊的topN token的N變大一些(除以的百分比變小),垃圾的N小一些。
最後是總結。
相關文章
- 讀書筆記筆記
- 《讀書與做人》讀書筆記筆記
- webpackDemo讀書筆記Web筆記
- Vue讀書筆記Vue筆記
- 散文讀書筆記筆記
- Cucumber讀書筆記筆記
- HTTP 讀書筆記HTTP筆記
- postgres 讀書筆記筆記
- 讀書筆記2筆記
- 讀書筆記3筆記
- js高程讀書筆記JS筆記
- 《論語》讀書筆記筆記
- 《重構》讀書筆記筆記
- PMBook讀書筆記(一)筆記
- 《如何有效閱讀一本書》讀書筆記筆記
- 《將心注入》讀書筆記筆記
- Raft論文讀書筆記Raft筆記
- 讀書筆記-沒有空白筆記
- JVM讀書筆記之OOMJVM筆記OOM
- swift語法-讀書筆記Swift筆記
- 【GO】《GO HANDBOOK》讀書筆記Go筆記
- 讀書筆記(2)《微精通》筆記
- 《Effective C++》讀書筆記C++筆記
- 編譯原理讀書筆記編譯原理筆記
- 類載入讀書筆記筆記
- 《Effective-Ruby》讀書筆記筆記
- 《CSS揭祕》讀書筆記CSS筆記
- 《圖解 HTTP》 讀書筆記圖解HTTP筆記
- 產品讀書筆記-需求筆記
- C++讀書筆記:字串C++筆記字串
- 今日隨筆-構建之法讀書筆記筆記
- 《高效能JavaScript》讀書筆記JavaScript筆記
- 《Google File System》讀書筆記(1)Go筆記
- 讀書筆記-資訊收集1筆記
- 黑客與畫家讀書筆記黑客筆記
- 深入淺出node讀書筆記筆記
- 五月的讀書筆記筆記
- 《Head First Java》20201017讀書筆記Java筆記
- 《Head First Java》20200927讀書筆記Java筆記