基于朴素贝叶斯的垃圾邮件分类-着重理解拉普拉斯变换
1. 引言
在正式學習樸素貝葉斯之前,需要明確的是機器學習所要實現的是基于有限的訓練樣本集盡可能準確地估計出后驗概率P(c|x),即根據特征得到所屬類別的概率,首先引入兩個概念。
判別式模型(discriminative models):給定x,直接建模P(c|x)來預測c,比如決策樹、BP神經網絡、支持向量機等;
生成式模型(generative models):聯合概率分布P(x,c)進行建模,然后由此獲得p(c|x),典型代表就是下面要講的樸素貝葉斯。
2. 問題描述
本文基于樸素貝葉斯構建一個分類垃圾郵件的模型,研究對象是英文的垃圾郵件,一來英文垃圾郵件數據集比較容易找到比較多,二來難度較中文的稍小,并且很多人都在用英文郵件,可比性較強,適合新手入門。
3. 算法流程
A. 數據準備
a. 數據集使用 UCI Machine Learning Repository,已上傳至GitHub,可進行下載。
b. 訓練集中,positive郵件數量為12500,negative郵件數量為12500;測試集中,positive郵件數量和negative郵件數量同為12500。
c. 數據預處理。去除郵件中的特殊符號以及沒有任何意義的詞語,如一些html標簽或者"the"、"a"等詞語。具體方式為使用現成的停用詞表進行操作。
B. 理論依據
a. 貝葉斯定理
貝葉斯定理是該算法的核心思想。
?
貝葉斯定理
?
其中,P(c)是類先驗概率,p(x|c)是條件概率,p(x)是“證據因子”(在同一問題中p(x)全相同);
p(c)=類別c的數目/總數。
因此,求解p(c|x)的問題變成了求解p(x|c)的問題,接下來引出下面兩種解決方法。
b1. 極大似然估計(源自頻率主義學派)
試錯,此路不通。
假設p(x|c)具有確定的形式并且被參數向量θc唯一確定,則要利用訓練集估計θc的值,即p(x|c)-->p(x|θc)。
Frequentist:參數雖然未知,但是客觀存在的固定值。
Bayesian:參數是未觀察到的隨機變量,其本身也有分布。
若樣本Dc滿足獨立同分布,則參數θc對于數據集Dc的似然是
極大似然估計
注:使用對數似然的原因是避免連乘造成下溢。
這種參數化的方法的弊端是結果的準確性嚴重依賴于所假設的概率分布形式是否符合潛在的真實數據分布。下面就是貝葉斯的優越性了。
?
b2. 樸素貝葉斯分類器
樸素貝葉斯分類器(naive Bayes classifier)采用了屬性條件獨立性假設(attribute conditional independence assumption),即對于已知類別,假設所有的屬性都相互獨立(雖然這是不對的,但至少在垃圾郵件分類這里假設所有的屬性獨立取得了還不賴的結果)。換言之,假設所有屬性獨立地對分類結果發生影響。
樸素貝葉斯分類器
另外,為了避免進行計算時c類樣本的數量和在樣本中第i個屬性的取值為0導致p(c)或者p(x|c)為0,這里使用拉普拉斯修正(Laplacian correction),即
Laplace
?
C. 垃圾郵件實際問題
- a. 建立詞匯表(之后可以創建TF-IDF詞匯表,現在僅僅簡化)
統計郵件中出現的所有詞匯并記作一維向量的形式,即(abandon,ahead,buy,go,...,zero)。
- b. 詞向量表示(之后使用Word2Vec表示詞向量,現在僅僅簡化)
將每封郵件依據詞匯表以向量的形式表示出來,該詞在郵件中出現記為1,反之記為0,即比如(1,1,0,0,...,1)。
無疑這會造成維數災難,Word2Vec會好很多,不過現在的計算量不是很大也不涉及其他算法就用one-hot方式表示了。
- c. 計算先驗概率p(c)
p(正常郵件)=D(正常郵件數)+1/D(總郵件數)+2
p(垃圾郵件)=D(垃圾郵件數)+1/D(總郵件數)+2
- d. 計算每個詞匯的條件概率
p(abandon=1|正常郵件)=D(正常郵件中有abandon的數目)+1/D(正常郵件數)+2
p(abandon=1|垃圾郵件)=D(垃圾郵件中有abandon的數目)+1/D(垃圾郵件數)+2
p(ahead=1|正常郵件)=D(正常郵件中有ahead的數目)+1/D(正常郵件數)+2
p(ahead=1|垃圾郵件)=D(垃圾郵件中有ahead的數目)+1/D(垃圾郵件數)+2
...
p(zero=1|正常郵件)=D(正常郵件中有zer的數目)+1/D(正常郵件數)+2
p(zero=1|垃圾郵件)=D(垃圾郵件中有zero的數目)+1/D(垃圾郵件數)+2
- e. 測試
p(email1=正常郵件)=p(正常郵件)p(zero|正常郵件)p(buy|正常郵件)p(achieve|正常郵件)=...
p(email1=垃圾郵件)=p(垃圾郵件)p(zero|垃圾郵件)p(buy|垃圾郵件)p(achieve|垃圾郵件)=...
若p(email1=正常郵件)>p(email1=垃圾郵件),則為正常郵件;
若p(email1=正常郵件)<p(email1=垃圾郵件),則為垃圾郵件;
若p(email1=正常郵件)=p(email1=垃圾郵件),則用一個隨機數隨機決定。
將測試結果與實際結果進行比較,并記錄下分類正確和分類錯誤的數目,計算出TP、FP、FN和TN,最后得到準確率、精確率和召回率。如果有必要的話,畫出相應的圖進行說明。
看到要計算準確率、精確率和召回率這里我表示很慚愧,只計算了準確率
4.結論
由于諸多因素(設置閾值去除稀有詞匯,使用TF-IDF表示詞匯向量,使用log防止乘數下溢)沒有考慮,所以訓練大量的數據集時會導致內存不足的現象,故只使用了36個訓練數據進行訓練,使用36個測試數據測試準確率。最終準確率只有55.5%多,只比瞎猜的大了一點,個人覺得還是訓練集太少,再放大一點肯定還是會提升很多的。樸素貝葉斯的基本思想在這,這里我就不多改了,其他的問題之后注意,要進入下一個算法的學習了。在這里附上代碼地址,(樸素貝葉斯-spamClassification)[https://github.com/RuiDream/MachineLearning.git]
自己手寫的Bayes結果展示:
手寫Bayes結果
調包的結果展示(人家的很齊全,還有混淆矩陣,服):
庫中Bayes結果
?
庫中Bayes混淆矩陣
?
注:準確率相差這么大很大的一個原因是訓練集的大小不同,大的為25000,我自己寫的為36.。。不過還是要怪自己的代碼不精,革命剛剛起步……
?
總結
以上是生活随笔為你收集整理的基于朴素贝叶斯的垃圾邮件分类-着重理解拉普拉斯变换的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Auto_ml与TPOT的区别
- 下一篇: nlp大赛冠军总结