本系列來自於我《人工智能》課程複習總結以及機器學習部分的實驗總結
垃圾郵件分類是監督學習分類中一個最經典的案例,本文先複習了基礎的概率論知識、貝葉斯法則以及樸素貝葉斯模型的思想,最後給出了垃圾郵件分類在Matlab中用樸素貝葉斯模型的實現
1.概率
1.1 條件概率
定義:事件B發生的情況下,事件A發生的概率記作條件概率
條件概率也叫後驗概率,無條件概率也叫先驗概率(在沒有任何其它信息存在的情況下關於命題的信度)
可以得到乘法規則:
推廣有鏈式法則:
1.2 概率公理
1.3 聯合分佈和邊緣概率分佈
X是隨機變量x取值集合,Y是隨機變量y取值集合,那麼稱
邊緣概率定義爲聯合分佈中某一個隨機變量發生的概率:
1.4 獨立性
若事件A和B滿足:
稱A和B關於C**條件獨立**,則有:
2.貝葉斯法則
2.1 貝葉斯法則
從乘法規則
經常我們把把未知因素cause造成的結果effect看作證據,去確定未知因素cause發生的概率,那麼有:
舉個例子:
我們預先知道在感冒(cause)的情況下頭痛(effect)發生的概率爲50%,而感冒的概率爲0.025且頭痛的概率爲0.1,那麼某天早上醒來我頭痛了,這時我感冒的概率是0.5*0.025/0.1=0.125而不是感覺上的50%
2.2 樸素貝葉斯模型
給定cause的情況下有n個彼此條件獨立的症狀effect,那麼他們的聯合分佈有:
通常稱這個概率分佈爲樸素貝葉斯模型或貝葉斯分類器
那麼樸素貝葉斯模型怎麼實現分類呢?
我們設有很多種cause(m個),這些cause下分別會表現爲n個effect(effect也有多種)。我們統計訓練集(已做標記)的結果只能統計知道某個cause的情況下這n個effect的取值,也就是
之所以稱之爲樸素,是因爲其對effect條件獨立性的假設,但是往往實際情況中effect並非條件獨立的。
3.樸素貝葉斯模型下的垃圾郵件分類
3.1 模型
假設:
- 設有n個單詞
wordi,i=1,...,n :wordi=0 表示這個單詞在這封email中不出現,wordi=1 表示這個單詞在這封email中出現。 - 設訓練集每封email有label標記郵件是否爲垃圾郵件spam,label=1則該郵件是垃圾郵件
模型:
3.2 訓練
我們需要用訓練集計算出:
- 正常郵件概率
P(norm) - 垃圾郵件概率
P(spam) - 單詞i在正常郵件中不出現概率
P(wordi=0|norm) - 單詞i在正常郵件中出現概率
P(wordi=1|norm) - 單詞i在垃圾郵件中不出現概率
P(wordi=0|spam) - 單詞i在垃圾郵件中出現概率
P(wordi=1|spam)
那麼我們根據樸素貝葉斯模型即可計算出
3.3 Matlab實現
用Matlab實現樸素貝葉斯模型垃圾郵件分類器如下:
function [ypred,accuracy]= nbayesclassifier (traindata, trainlabel, testdata, testlabel, threshold)
trainnum = size(traindata, 1);
wordnum = size(traindata, 2);
p = zeros(wordnum, 2, 2);
count = zeros(2, 1);
for i = 1 : trainnum
count(trainlabel(i) + 1) = count(trainlabel(i) + 1) + 1;
for j = 1 : wordnum
p(j, trainlabel(i) + 1, traindata(i, j) + 1) = p(j, trainlabel(i) + 1, traindata(i, j) + 1) + 1;
end
end
pnorm = count(1) / trainnum;
pspam = count(2) / trainnum;
p(:, 1, :) = (p(:, 1, :)+1) / (count(1)+1);
p(:, 2, :) = (p(:, 2, :)+1) / (count(2)+1);
testnum = size(testdata, 1);
ypred = zeros(testnum, 1);
correct = 0;
for i = 1 : testnum
q = pnorm / pspam;
for j = 1 : wordnum
q = q * p(j, 1, testdata(i, j) + 1) / p(j, 2, testdata(i, j) + 1);
end
q = 1 / (1 + q);
if q > threshold
ypred(i) = 1;
end
if ypred(i) == testlabel(i)
correct = correct + 1;
end
end
accuracy = correct / testnum;
end
其中有幾個要點:
- 我們將已標記數據集劃分爲訓練集和測試集,訓練集用來訓練模型參數,測試集用來測試模型準確率。根據比較模型預測和測試集真實標記,我們可以計算出模型的準確率threshold
p(:, 1, :) = (p(:, 1, :)+1) / (count(1)+1);
是爲了避免某個單詞在某個分類(正常郵件或垃圾郵件)中一直沒有出現而導致p(:, 1, :)=0
的情況降低分類器魯棒性的情況(稱之爲Laplace校準,在數據規模較大時,加1產生的偏差忽略不計)
3.4 分類結果
通過枚舉threshold的可以確定在某個訓練集和測試集劃分下,最優的閾值選取
我簡單測試1000個郵件的數據量,6:4劃分下最優預測準確率只有90%(待優化)