利用樸素貝葉斯算法實現垃圾郵件的過濾,並結合Adaboost改進該算法

NaiveBayesSpamFilter V1.0

利用樸素貝葉斯算法實現垃圾郵件的過濾,並結合Adaboost改進該算法。

1 Naive Bayes spam filtering

  假設郵件的內容中包含的詞彙爲Wi,垃圾郵件Spam,正常郵件ham。
判斷一份郵件,內容包含的詞彙爲Wi,判斷該郵件是否是垃圾郵件,即計算P(S|Wi)這個條件概率。根據Bayes’ theorem:

  Bayes' theorem

  其中:

  • Pr(S|Wi) 出現詞彙Wi的郵件是垃圾郵件的條件概率(即後驗概率);
  • Pr(S) 訓練階段郵件數據集中垃圾郵件的概率,或實際調查的垃圾郵件的概率(即先驗概率);
  • Pr(Wi|S) 垃圾郵件中詞彙Wi出現的概率;
  • Pr(H) 訓練階段郵件數據集中正常郵件的概率,或實際調查的正常郵件的概率;
  • Pr(Wi|H) 正常郵件中詞彙Wi出現的概率;

  對於郵件中出現的所有詞彙,考慮每個詞彙出現事件的獨立性,計算Pr(S|Wi)的聯合概率Pr(S|W),W={W1,W2,…Wn}:

  Bayes' theorem

  其中:
- P 即Pr(S|W),出現詞彙W={W1,W2……Wn}的郵件是垃圾郵件的條件概率;
- Pi 即Pr(S|Wi),出現詞彙Wi的郵件是垃圾郵件的條件概率;

  注:程序中,通過計算出Pr(S|W)和Pr(H|W),比較Pr(S|W)和Pr(H|W)的大小,判斷是垃圾郵件還是正常郵件。我們發現Pr(S|W)和Pr(H|W)計算的分母相同,所以我們只需要比較分子即可。

  但存在兩個問題:

  1. 當詞彙不存在時,即ni=0,此時Pr(S|Wi) = 0,會造成P=0,無法比較
  2. 當Pr(S|Wi)較小時,連乘操作會造成下溢出問題

  解決方案:
- 計算P(Wi|S)和P(Wi|H)時,將所有詞彙初始化出現的次數爲1,並將分母初始化爲2。

    # 統計語料庫中詞彙在S和H中出現的次數
    wordsInSpamNum = np.ones(numWords)
    wordsInHealthNum = np.ones(numWords)
    spamWordsNum = 2.0
    healthWordsNum = 2.0
  • 計算P(Wi|S)和P(Wi|H)時,對概率取對數
    pWordsSpamicity = np.log(wordsInSpamNum / spamWordsNum)
    pWordsHealthy = np.log(wordsInHealthNum / healthWordsNum)

  所以最終比較的是,P(W1|S)P(W2|S)….P(Wn|S)P(S)和P(W1|H)P(W2|H)….P(Wn|H)P(H)的大小。

    ps = sum(testWordsMarkedArray * pWordsSpamicity) + np.log(pSpam)
    ph = sum(testWordsMarkedArray * pWordsHealthy) + np.log(1 - pSpam)

  **測試效果:**5574個樣本,採用交叉驗證,隨機選取4574個作爲訓練樣本,產生詞彙列表(語料庫),對1000個測試樣本,分類的平均錯誤率約爲:2.5%。

2 Running Adaboost on Naive Bayes

  我們在計算ps和ph聯合後驗概率時,可引入一個調整因子DS,其作用是調整詞彙表中某一詞彙的“垃圾程度”(spamicity),

    ps = sum(testWordsMarkedArray * pWordsSpamicity * DS) + np.log(pSpam)

  其中DS通過Adaboost算法迭代獲取最佳值。原理如下:

設定adaboost循環的次數count
交叉驗證隨機選擇1000個樣本
DS初始化爲和詞彙列表大小相等的全一向量
迭代循環count次:
    設定最小分類錯誤率爲inf
    對於每一個樣本:
        在當前DS下對樣本分類
        如果分類出錯:
            計算出錯的程度,即比較ps和ph的相差alpha
            如果樣本原本是spam,錯分成ham:
                DS[樣本包含的詞彙] = np.abs(DS[樣本包含的詞彙] - np.exp(alpha) / DS[樣本包含的詞彙])
            如果樣本原本是ham,錯分成spam:
                DS[樣本包含的詞彙] = DS[樣本包含的詞彙] + np.exp(alpha) / DS[樣本包含的詞彙]
    計算錯誤率
    保存最小的錯誤率和此時的詞彙列表、P(Wi|S)和P(Wi|H)、DS等信息,即保存訓練好的最佳模型的信息

  **測試效果:**5574個樣本,獲取Adaboost算法訓練的最佳模型信息(包括詞彙列表、P(Wi|S)和P(Wi|H)、DS等),對1000個測試樣本,分類的平均錯誤率約爲:0.5%。

References

Running Adaboost on Naive Bayes
Boosting and naive bayesian learning
Naive Bayes spam filtering

Code

NaiveBayesSpamFilter 完整源代碼見 Github

發佈了72 篇原創文章 · 獲贊 26 · 訪問量 31萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章