熱線電話:13121318867

登錄
首頁精彩閱讀機器學習實戰之樸素貝葉斯
機器學習實戰之樸素貝葉斯
2016-12-11
收藏

機器學習實戰之樸素貝葉斯

一、概述
樸素貝葉斯分類算法是基于概率論中的貝葉斯公式得到的,也是比較常用的一種算法,而樸素代表的是屬性之間的獨立性,這樣聯合概率可以轉換成各概率分量的乘積。
二、算法思想
其實這個算法的思想就是貝葉斯公式,如果不是很了解也沒什么關系,只要看點例子就明白了,但由于這里只想給大家提供一些實用代碼,因此就不仔細說例子了,《機器學習實戰》中的那個灰石頭的例子就不錯,另外,如果還感覺不是很清楚,推薦看一下《數據挖掘導論》中貝葉斯分類器部分。

三、實例算法
不說廢話了,現在開始介紹樸素貝葉斯的matlab代碼編寫,這里我們的目標是利用樸素貝葉斯進行文檔分類,即確定該文檔是侮辱類還是非侮辱類,分別以1和0表示。
1. 創建測試數據
%% 建立測試數據
postingList = [{‘my dog has flea problems help please’};
               {‘maybe not take him to dog park stupid’};
               {‘my dalmation is so cute I love him’};
               {‘stop posting stupid worthless garbage’};
               {‘mr licks ate my steak how to stop him’};
               {‘quit buying worthless dog food stupid’}];
classVec = [0, 1, 0, 1, 0, 1];
意義應該還是比較明確的,就是說2,4,6是帶有侮辱性語句的文檔
2. 創建無重復單詞的列表
%% 創建無重復單詞的列表
[m, n] = size(postingList);
VocabList = [];
 
for  i = 1: m
    tempstr = postingList{i};
    str_split = regexp(tempstr, ‘W*s+’, ‘split’);
    VocabList = [VocabList, str_split];
end
 
VocabList_unique = unique(VocabList);
可以看一下單詞列表
>> VocabList_unique
 
VocabList_unique =
 
  Columns 1 through 8
 
    ‘I’    ‘ate’    ‘buying’    ‘cute’    ‘dalmation’    ‘dog’    ‘flea’    ‘food’
 
  Columns 9 through 16
 
    ‘garbage’    ‘has’    ‘help’    ‘him’    ‘how’    ‘is’    ‘licks’   ‘love’
 
  Columns 17 through 24
 
    ‘maybe’    ‘mr’    ‘my’    ‘not’    ‘park’    ‘please’    ‘posting’   ‘problems’
 
  Columns 25 through 32
 
    ‘quit’    ‘so’    ‘steak’    ‘stop’    ‘stupid’    ‘take’    ‘to’   ‘worthless’
 
 
3. 創建列表向量
由于單詞不好進行表述,我們需要根據單詞列表創建一個向量表示列表中的單詞是否出現,出現用1表示,未出現用0表示。
setOfWords2Vec.m文件如下
function wordsVec = setOfWords2Vec(vocabList, inputSet)
 
vocabList = unique(vocabList);
inputSet = unique(inputSet);
 
Listnum = length(vocabList);
inputnum = length(inputSet);
 
wordsVec = zeros(1, Listnum);
for  i = 1: inputnum
    for j = 1: Listnum
        if (strcmp(vocabList{j}, inputSet{i}))
            wordsVec(j) = 1;
        end        
    end
end
列表向量測試代碼如下
%% 創建列表向量測試
tempstr = postingList{1};
str_split = regexp(tempstr, ‘W*s+’, ‘split’);
 
wordsVec = setOfWords2Vec(VocabList_unique, str_split);
測試結果如下
wordsVec =
 
  Columns 1 through 14
 
     0     0     0     0     0     1     1     0     0    1     1     0     0     0
 
  Columns 15 through 28
 
     0     0     0     0     1     0     0     1     0    1     0     0     0     0
 
  Columns 29 through 32
 
     0     0     0     0
上面的意思是測試postingList第一句’my dog has flea problems help please’
在單詞表中的描述,對照上面的單詞列表可以看到結果是正確的,比如wordsVec中的第六第七項為1,在單詞表中表示的是dog 和 flea,這連個此時在上面那句話中出現的。
 
4. 貝葉斯分類函數編寫
trainNB0.m文件
function [p0Vect, p1Vect, pAbusive] = trainNB0(trainMatrix, trainCategory)
 
[m, n] = size(trainMatrix);
pAbusive = sum(trainCategory) / m;
 
p1words = trainMatrix(find(trainCategory), :);
p0words = trainMatrix(find(1 – trainCategory), :);
 
p0wordscount = sum(p0words, 1) + 1; % 加1是為了防止出現0概率
p1wordscount = sum(p1words, 1) + 1;
 
p0Vect = log(p0wordscount ./ sum(p0wordscount));
p1Vect = log(p1wordscount ./ sum(p1wordscount));
 
這段代碼還是要說明一下的
(1)注釋位置那句對每個單詞的出現初始化為1,就是說就算單詞沒出現,也將其計算為1,這是防止出現0概率,導致乘積為0。當然避免這個的方法有很多,每本書都不太一樣,這里的+1采用的是Laplace平滑方法。
(2)最后算概率加了個log是減少其動態范圍。
這兩個都是為了實際應用對代碼進行的修改,也就是說,就基本原理而言,不需要+1和增加log。
 
下面,我們對這個代碼進行測試
%% 測試trainNB0
trainMatrix = [];
for  i = 1: m
    tempstr = postingList{i};
    str_split = regexp(tempstr, ‘W*s+’, ‘split’);
    wordsVec = setOfWords2Vec(VocabList_unique, str_split);
    trainMatrix = [trainMatrix;wordsVec];
end
 
[p0V, p1V, pAb] = trainNB0(trainMatrix, classVec);
 
p0V代表0分類下,每個單詞的出現概率,也就是先驗概率(由于用了log,所以是負數,并且由于+1,故沒有無窮大項目)
p0V =
 
  Columns 1 through 8
 
   -3.3322   -3.3322   -4.0254   -3.3322   -3.3322   -3.3322   -3.3322   -4.0254
 
  Columns 9 through 16
 
   -4.0254   -3.3322   -3.3322   -2.9267   -3.3322   -3.3322   -3.3322   -3.3322
 
  Columns 17 through 24
 
   -4.0254   -3.3322   -2.6391   -4.0254   -4.0254   -3.3322   -4.0254   -3.3322
 
  Columns 25 through 32
 
   -4.0254   -3.3322   -3.3322   -3.3322   -4.0254   -4.0254   -3.3322   -4.0254
p1V意義類似
p1V =
 
  Columns 1 through 8
 
   -3.9318   -3.9318   -3.2387   -3.9318   -3.9318   -2.8332   -3.9318   -3.2387
 
  Columns 9 through 16
 
   -3.2387   -3.9318   -3.9318   -3.2387   -3.9318   -3.9318   -3.9318   -3.9318
 
  Columns 17 through 24
 
   -3.2387   -3.9318   -3.9318   -3.2387   -3.2387   -3.9318   -3.2387   -3.9318
 
  Columns 25 through 32
 
   -3.2387   -3.9318   -3.9318   -3.2387   -2.5455   -3.2387   -3.2387   -2.8332
pAb代表的是分類為1的文件占所有文件的比例
pAb = 0.5
這個很明顯,因為測試數據中有三個分類為1,并且一個有6項。
 
5. 分類測試
訓練部分的代碼已經寫完了,下面我們的分類器就可以使用了,利用貝葉斯公式計算p(c | w)并比較大小可以確定分類c。
對于本例來說
p(w|0) = 待分類語句中每個單詞在0類出現的概率的乘積
p(w|1) = 待分類語句中每個單詞在1類出現的概率的乘積
 
p(0|w) = p(w|0)*p(0) / p(w)
p(1|w) = p(w|1)*p(1) / p(w)
 
如果p(0|w) > p(1|w)分類就是0,反之就是1
 
代碼如下
classifyNB.m
function classRes = classifyNB(vec2Classify, p0Vec, p1Vec, pClass1)
p1 = sum(vec2Classify .* p1Vec) + log(pClass1);
p0 = sum(vec2Classify .* p0Vec) + log(1 – pClass1);
if  p1 > p0
    classRes = 1;
else
    classRes = 0;
end
說明:
由于前面的概率是以log形式表示的,所以乘積就變成了加法,還有就是p(w)不影響比較結果,因此未予計算。
測試代碼如下
%% 進行分類測試
testEntry = ‘love my dalmation’;
str_split = regexp(testEntry, ‘W*s+’, ‘split’);
wordsVec1 = setOfWords2Vec(VocabList_unique, str_split);
classRes1 = classifyNB(wordsVec1, p0V, p1V, pAb);
 
testEntry = ‘stupid garbage’;
str_split = regexp(testEntry, ‘W*s+’, ‘split’);
wordsVec2 = setOfWords2Vec(VocabList_unique, str_split);
classRes2 = classifyNB(wordsVec2, p0V, p1V, pAb);
結果就是
classRes1 = 0
classRes2 = 1
也就是說,分類確定第二句帶有侮辱性,其實從其中的stupid就可以看出
四、算法應用
前面就說過,這個算法應用很廣,《實戰》中給出了兩個實例,一個是垃圾郵件分類,這個和我們這里做的文本分類非常類似,另外一個就是從個人廣告中獲取區域傾向。都是平時我們經常使用的功能,如果有興趣可以自己編著試一下,很多還是挺有意思的。

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢