機器學習經典算法之朴素貝葉斯分類


很多人都聽說過貝葉斯原理,在哪聽說過?基本上是在學概率統計的時候知道的。有些人可能會說,我記不住這些概率論的公式,沒關系,我盡量用通俗易懂的語言進行講解。

/*請尊重作者勞動成果,轉載請標明原文鏈接:*/

/* https://www.cnblogs.com/jpcflyer/p/11069659.html  * /

貝葉斯原理是英國數學家托馬斯·貝葉斯提出的。貝葉斯是個很神奇的人,他的經歷類似梵高。生前沒有得到重視,死后,他寫的一篇關於歸納推理的論文被朋友翻了出來,並發表了。這一發表不要緊,結果這篇論文的思想直接影響了接下來兩個多世紀的統計學,是科學史上著名的論文之一。
貝葉斯原理跟我們的生活聯系非常緊密。舉個例子,如果你看到一個人總是花錢,那么會推斷這個人多半是個有錢人。當然這也不是絕對,也就是說,當你不能准確預知一個事物本質的時候,你可以依靠和事物本質相關的事件來進行判斷,如果事情發生的頻次多,則證明這個屬性更有可能存在。    
 
一、 貝葉斯原理
貝葉斯原理是怎么來的呢?貝葉斯為了解決一個叫“逆向概率”問題寫了一篇文章,嘗試解答在沒有太多可靠證據的情況下,怎樣做出更符合數學邏輯的推測。
 
什么是“逆向概率”呢?
所謂“逆向概率”是相對“正向概率”而言。正向概率的問題很容易理解,比如我們已經知道袋子里面有 N 個球,不是黑球就是白球,其中 M 個是黑球,那么把手伸進去摸一個球,就能知道摸出黑球的概率是多少。但這種情況往往是上帝視角,即了解了事情的全貌再做判斷。
在現實生活中,我們很難知道事情的全貌。貝葉斯則從實際場景出發,提了一個問題:如果我們事先不知道袋子里面黑球和白球的比例,而是通過我們摸出來的球的顏色,能判斷出袋子里面黑白球的比例么?
正是這樣的一個問題,影響了接下來近 200 年的統計學理論。這是因為,貝葉斯原理與其他統計學推斷方法截然不同,它是建立在主觀判斷的基礎上:在我們不了解所有客觀事實的情況下,同樣可以先估計一個值,然后根據實際結果不斷進行修正。
我們用一個題目來體會下:假設有一種病叫做“貝葉死”,它的發病率是萬分之一,即 10000 人中會有 1 個人得病。現有一種測試可以檢驗一個人是否得病的准確率是 99.9%,它的誤報率是 0.1%,那么現在的問題是,如果一個人被查出來患有“葉貝死”,實際上患有的可能性有多大?
你可能會想說,既然查出患有“貝葉死”的准確率是 99.9%,那是不是實際上患“貝葉死”的概率也是 99.9% 呢?實際上不是的。你自己想想,在 10000 個人中,還存在 0.1% 的誤查的情況,也就是 10 個人沒有患病但是被診斷成陽性。當然 10000 個人中,也確實存在一個患有貝葉死的人,他有 99.9% 的概率被檢查出來。所以你可以粗算下,患病的這個人實際上是這 11 個人里面的一員,即實際患病比例是 1/11≈9%。
上面這個例子中,實際上涉及到了貝葉斯原理中的幾個概念:
 
先驗概率
通過經驗來判斷事情發生的概率,比如說“貝葉死”的發病率是萬分之一,就是先驗概率。再比如南方的梅雨季是 6-7 月,就是通過往年的氣候總結出來的經驗,這個時候下雨的概率就比其他時間高出很多。
 
后驗概率
后驗概率就是發生結果之后,推測原因的概率。比如說某人查出來了患有“貝葉死”,那么患病的原因可能是 A、B 或 C。患有“貝葉死”是因為原因 A 的概率就是后驗概率。它是屬於條件概率的一種。
 
條件概率
事件 A 在另外一個事件 B 已經發生條件下的發生概率,表示為 P(A|B),讀作“在 B 發生的條件下 A 發生的概率”。比如原因 A 的條件下,患有“貝葉死”的概率,就是條件概率。
 
似然函數(likelihood function)
你可以把概率模型的訓練過程理解為求參數估計的過程。舉個例子,如果一個硬幣在 10 次拋落中正面均朝上。那么你肯定在想,這個硬幣是均勻的可能性是多少?這里硬幣均勻就是個參數,似然函數就是用來衡量這個模型的參數。似然在這里就是可能性的意思,它是關於統計參數的函數。
介紹完貝葉斯原理中的這幾個概念,我們再來看下貝葉斯原理,實際上貝葉斯原理就是求解后驗概率,我們假設:A 表示事件 “測出為陽性”, 用 B1 表示“患有貝葉死”, B2 表示“沒有患貝葉死”。根據上面那道題,我們可以得到下面的信息。
患有貝葉死的情況下,測出為陽性的概率為 P(A|B1)=99.9%,沒有患貝葉死,但測出為陽性的概率為 P(A|B2)=0.1%。另外患有貝葉死的概率為 P(B1)=0.01%,沒有患貝葉死的概率 P(B2)=99.99%。
那么我們檢測出來為陽性,而且是貝葉死的概率 P(B1,A)=P(B1)*P(A|B1)=0.01%*99.9%=0.00999%。
這里 P(B1,A) 代表的是聯合概率,同樣我們可以求得 P(B2,A)=P(B2)*P(A|B2)=99.99%*0.1%=0.09999%。
然后我們想求得是檢查為陽性的情況下,患有貝葉死的概率,也即是 P(B1|A)。
所以檢查出陽性,且患有貝葉死的概率為:
檢查出是陽性,但沒有患有貝葉死的概率為:
這里我們能看出來 0.01%+0.1% 均出現在了 P(B1|A) 和 P(B2|A) 的計算中作為分母。我們把它稱之為論據因子,也相當於一個權值因子。
其中 P(B1)、P(B2) 就是先驗概率,我們現在知道了觀測值,就是被檢測出來是陽性,來求患貝葉死的概率,也就是求后驗概率。求后驗概率就是貝葉斯原理要求的,基於剛才求得的 P(B1|A),P(B2|A),我們可以總結出貝葉斯公式為:
由此,我們可以得出通用的貝葉斯公式:
 
 
 
朴素貝葉斯
講完貝葉斯原理之后,我們再來看下今天重點要講的算法,朴素貝葉斯。 它是一種簡單但極為強大的預測建模算法 。之所以稱為朴素貝葉斯,是因為它假設每個輸入變量是獨立的。這是一個強硬的假設,實際情況並不一定,但是這項技術對於絕大部分的復雜問題仍然非常有效。
 
朴素貝葉斯模型由兩種類型的概率組成:
每個 類別的概率 P(Cj);
每個屬性的 條件概率 P(Ai|Cj)。
 
我來舉個例子說明下什么是類別概率和條件概率。假設我有 7 個棋子,其中 3 個是白色的,4 個是黑色的。那么棋子是白色的概率就是 3/7,黑色的概率就是 4/7,這個就是類別概率。
假設我把這 7 個棋子放到了兩個盒子里,其中盒子 A 里面有 2 個白棋,2 個黑棋;盒子 B 里面有 1 個白棋,2 個黑棋。那么在盒子 A 中抓到白棋的概率就是 1/2,抓到黑棋的概率也是 1/2,這個就是條件概率,也就是在某個條件(比如在盒子 A 中)下的概率。
在朴素貝葉斯中,我們要統計的是屬性的條件概率,也就是假設取出來的是白色的棋子,那么它屬於盒子 A 的概率是 2/3。
為了訓練朴素貝葉斯模型,我們需要先給出訓練數據,以及這些數據對應的分類。那么上面這兩個概率,也就是類別概率和條件概率。他們都可以從給出的訓練數據中計算出來。一旦計算出來,概率模型就可以使用貝葉斯原理對新數據進行預測。
 
另外我想告訴你的是,貝葉斯原理、貝葉斯分類和朴素貝葉斯這三者之間是有區別的。
貝葉斯原理是最大的概念,它解決了概率論中“逆向概率”的問題,在這個理論基礎上,人們設計出了貝葉斯分類器,朴素貝葉斯分類是貝葉斯分類器中的一種,也是最簡單,最常用的分類器。朴素貝葉斯之所以朴素是因為它假設屬性是相互獨立的,因此對實際情況有所約束,如果屬性之間存在關聯,分類准確率會降低。不過好在對於大部分情況下,朴素貝葉斯的分類效果都不錯。
 
 
二、 朴素貝葉斯分類工作原理
朴素貝葉斯分類是常用的貝葉斯分類方法。我們日常生活中看到一個陌生人,要做的第一件事情就是判斷 TA 的性別,判斷性別的過程就是一個分類的過程。根據以往的經驗,我們通常會從身高、體重、鞋碼、頭發長短、服飾、聲音等角度進行判斷。這里的“經驗”就是一個訓練好的關於性別判斷的模型,其訓練數據是日常中遇到的各式各樣的人,以及這些人實際的性別數據。
 
離散數據案例
我們遇到的數據可以分為兩種,一種是離散數據,另一種是連續數據。那什么是離散數據呢?離散就是不連續的意思,有明確的邊界,比如整數 1,2,3 就是離散數據,而 1 到 3 之間的任何數,就是連續數據,它可以取在這個區間里的任何數值。
我以下面的數據為例,這些是根據你之前的經驗所獲得的數據。然后給你一個新的數據:身高“高”、體重“中”,鞋碼“中”,請問這個人是男還是女?
針對這個問題,我們先確定一共有 3 個屬性,假設我們用 A 代表屬性,用 A1, A2, A3 分別為身高 = 高、體重 = 中、鞋碼 = 中。一共有兩個類別,假設用 C 代表類別,那么 C1,C2 分別是:男、女,在未知的情況下我們用 Cj 表示。
那么我們想求在 A1、A2、A3 屬性下,Cj 的概率,用條件概率表示就是 P(Cj|A1A2A3)。根據上面講的貝葉斯的公式,我們可以得出:
因為一共有 2 個類別,所以我們只需要求得 P(C1|A1A2A3) 和 P(C2|A1A2A3) 的概率即可,然后比較下哪個分類的可能性大,就是哪個分類結果。
在這個公式里,因為 P(A1A2A3) 都是固定的,我們想要尋找使得 P(Cj|A1A2A3) 的最大值,就等價於求 P(A1A2A3|Cj)P(Cj) 最大值。
我們假定 Ai 之間是相互獨立的,那么: P(A1A2A3|Cj)=P(A1|Cj)P(A2|Cj)P(A3|Cj)
然后我們需要從 Ai 和 Cj 中計算出 P(Ai|Cj) 的概率,帶入到上面的公式得出 P(A1A2A3|Cj),最后找到使得 P(A1A2A3|Cj) 最大的類別 Cj。
我分別求下這些條件下的概率:
P(A1|C1)=1/2, P(A2|C1)=1/2, P(A3|C1)=1/4,P(A1|C2)=0, P(A2|C2)=1/2, P(A3|C2)=1/2,所以 P(A1A2A3|C1)=1/16, P(A1A2A3|C2)=0。
因為 P(A1A2A3|C1)P(C1)>P(A1A2A3|C2)P(C2),所以應該是 C1 類別,即男性。
 
連續數據案例
實際生活中我們得到的是連續的數值,比如下面這組數據:
那么如果給你一個新的數據,身高 180、體重 120,鞋碼 41,請問該人是男是女呢?
公式還是上面的公式,這里的困難在於,由於身高、體重、鞋碼都是連續變量,不能采用離散變量的方法計算概率。而且由於樣本太少,所以也無法分成區間計算。怎么辦呢?
這時,可以假設男性和女性的身高、體重、鞋碼都是正態分布,通過樣本計算出均值和方差,也就是得到正態分布的密度函數。有了密度函數,就可以把值代入,算出某一點的密度函數的值。比如,男性的身高是均值 179.5、標准差為 3.697 的正態分布。所以男性的身高為 180 的概率為 0.1069。怎么計算得出的呢? 你可以使用 EXCEL 的 NORMDIST(x,mean,standard_dev,cumulative) 函數,一共有 4 個參數:
x:正態分布中,需要計算的數值;
Mean:正態分布的平均值;
Standard_dev:正態分布的標准差;
Cumulative:取值為邏輯值,即 False 或 True。它決定了函數的形式。當為 TRUE 時,函數結果為累積分布;為 False 時,函數結果為概率密度。
這里我們使用的是 NORMDIST(180,179.5,3.697,0)=0.1069。
同理我們可以計算得出男性體重為 120 的概率為 0.000382324,男性鞋碼為 41 號的概率為 0.120304111。
所以我們可以計算得出:
P(A1A2A3|C1)=P(A1|C1)P(A2|C1)P(A3|C1)=0.1069*0.000382324* 0.120304111=4.9169e-6
同理我們也可以計算出來該人為女的可能性:
P(A1A2A3|C2)=P(A1|C2)P(A2|C2)P(A3|C2)=0.00000147489* 0.015354144* 0.120306074=2.7244e-9
很明顯這組數據分類為男的概率大於分類為女的概率。
當然在 Python 中,有第三方庫可以直接幫我們進行上面的操作,這個我們會在下文中介紹。這里主要是給你講解下具體的運算原理。
 
三、朴素貝葉斯分類器工作流程
朴素貝葉斯分類常用於文本分類,尤其是對於英文等語言來說,分類效果很好。它常用於垃圾文本過濾、情感預測、推薦系統等。
朴素貝葉斯分類器需要三個流程,我來給你一一講解下這幾個流程。
第一階段:准備階段
在這個階段我們需要確定特征屬性,比如上面案例中的“身高”、“體重”、“鞋碼”等,並對每個特征屬性進行適當划分,然后由人工對一部分數據進行分類,形成訓練樣本。
這一階段是整個朴素貝葉斯分類中唯一需要人工完成的階段,其質量對整個過程將有重要影響,分類器的質量很大程度上由特征屬性、特征屬性划分及訓練樣本質量決定。
第二階段:訓練階段
這個階段就是生成分類器,主要工作是計算每個類別在訓練樣本中的出現頻率及每個特征屬性划分對每個類別的條件概率。
輸入是特征屬性和訓練樣本,輸出是分類器。
第三階段:應用階段
這個階段是使用分類器對新數據進行分類。輸入是分類器和新數據,輸出是新數據的分類結果。
好了,在這次課中你了解了概率論中的貝葉斯原理,朴素貝葉斯的工作原理和工作流程,也對朴素貝葉斯的強大和限制有了認識。下一節中,我將帶你實戰,親自掌握 Python 中關於朴素貝葉斯分類器工具的使用。
 
四、 sklearn 機器學習包
接下來帶你一起使用朴素貝葉斯做下文檔分類的項目,最重要的工具就是 sklearn 這個機器學習神器。
sklearn 的全稱叫 Scikit-learn,它給我們提供了 3 個朴素貝葉斯分類算法,分別是高斯朴素貝葉斯(GaussianNB)、多項式朴素貝葉斯(MultinomialNB)和伯努利朴素貝葉斯(BernoulliNB)。
 
這三種算法適合應用在不同的場景下,我們應該根據特征變量的不同選擇不同的算法:
高斯朴素貝葉斯 :特征變量是連續變量,符合高斯分布,比如說人的身高,物體的長度。
多項式朴素貝葉斯 :特征變量是離散變量,符合多項分布,在文檔分類中特征變量體現在一個單詞出現的次數,或者是單詞的 TF-IDF 值等。
伯努利朴素貝葉斯 :特征變量是布爾變量,符合 0/1 分布,在文檔分類中特征是單詞是否出現。
伯努利朴素貝葉斯是以文件為粒度,如果該單詞在某文件中出現了即為 1,否則為 0。而多項式朴素貝葉斯是以單詞為粒度,會計算在某個文件中的具體次數。而高斯朴素貝葉斯適合處理特征變量是連續變量,且符合正態分布(高斯分布)的情況。比如身高、體重這種自然界的現象就比較適合用高斯朴素貝葉斯來處理。而文本分類是使用多項式朴素貝葉斯或者伯努利朴素貝葉斯。
 
什么是 TF-IDF 值呢?
我在多項式朴素貝葉斯中提到了“詞的 TF-IDF 值”,如何理解這個概念呢?
TF-IDF 是一個統計方法,用來評估某個詞語對於一個文件集或文檔庫中的其中一份文件的重要程度。
TF-IDF 實際上是兩個詞組 Term Frequency 和 Inverse Document Frequency 的總稱,兩者縮寫為 TF 和 IDF,分別代表了詞頻和逆向文檔頻率
詞頻 TF 計算了一個單詞在文檔中出現的次數,它認為一個單詞的重要性和它在文檔中出現的次數呈正比。
逆向文檔頻率 IDF ,是指一個單詞在文檔中的區分度。它認為一個單詞出現在的文檔數越少,就越能通過這個單詞把該文檔和其他文檔區分開。IDF 越大就代表該單詞的區分度越大。
所以 TF-IDF 實際上是詞頻 TF 和逆向文檔頻率 IDF 的乘積 。這樣我們傾向於找到 TF 和 IDF 取值都高的單詞作為區分,即這個單詞在一個文檔中出現的次數多,同時又很少出現在其他文檔中。這樣的單詞適合用於分類。
TF-IDF 如何計算
首先我們看下詞頻 TF 和逆向文檔概率 IDF 的公式。
為什么 IDF 的分母中,單詞出現的文檔數要加 1 呢?因為有些單詞可能不會存在文檔中,為了避免分母為 0,統一給單詞出現的文檔數都加 1。
TF-IDF=TF*IDF。
你可以看到,TF-IDF 值就是 TF 與 IDF 的乘積, 這樣可以更准確地對文檔進行分類。比如“我”這樣的高頻單詞,雖然 TF 詞頻高,但是 IDF 值很低,整體的 TF-IDF 也不高。
我在這里舉個例子。假設一個文件夾里一共有 10 篇文檔,其中一篇文檔有 1000 個單詞,“this”這個單詞出現 20 次,“bayes”出現了 5 次。“this”在所有文檔中均出現過,而“bayes”只在 2 篇文檔中出現過。我們來計算一下這兩個詞語的 TF-IDF 值。
針對“this”,計算 TF-IDF 值:
所以 TF-IDF=0.02*(-0.0414)=-8.28e-4。
針對“bayes”,計算 TF-IDF 值:
 
很明顯“bayes”的 TF-IDF 值要大於“this”的 TF-IDF 值。這就說明用“bayes”這個單詞做區分比單詞“this”要好。
如何求 TF-IDF
在 sklearn 中我們直接使用 TfidfVectorizer 類,它可以幫我們計算單詞 TF-IDF 向量的值。在這個類中,取 sklearn 計算的對數 log 時,底數是 e,不是 10。
下面我來講下如何創建 TfidfVectorizer 類。
TfidfVectorizer 類的創建:
創建 TfidfVectorizer 的方法是:
1 TfidfVectorizer(stop_words=stop_words, token_pattern=token_pattern)
我們在創建的時候,有兩個構造參數,可以自定義停用詞 stop_words 和規律規則 token_pattern。需要注意的是傳遞的數據結構,停用詞 stop_words 是一個列表 List 類型,而過濾規則 token_pattern 是正則表達式。
什么是停用詞?停用詞就是在分類中沒有用的詞,這些詞一般詞頻 TF 高,但是 IDF 很低,起不到分類的作用。為了節省空間和計算時間,我們把這些詞作為停用詞 stop words,告訴機器這些詞不需要幫我計算。
當我們創建好 TF-IDF 向量類型時,可以用 fit_transform 幫我們計算,返回給我們文本矩陣,該矩陣表示了每個單詞在每個文檔中的 TF-IDF 值。
在我們進行 fit_transform 擬合模型后,我們可以得到更多的 TF-IDF 向量屬性,比如,我們可以得到詞匯的對應關系(字典類型)和向量的 IDF 值,當然也可以獲取設置的停用詞 stop_words。
舉個例子,假設我們有 4 個文檔:
文檔 1:this is the bayes document;
文檔 2:this is the second second document;
文檔 3:and the third one;
文檔 4:is this the document。
現在想要計算文檔里都有哪些單詞,這些單詞在不同文檔中的 TF-IDF 值是多少呢?
首先我們創建 TfidfVectorizer 類:
1 from sklearn.feature_extraction.text import TfidfVectorizer
2 tfidf_vec = TfidfVectorizer()
然后我們創建 4 個文檔的列表 documents,並讓創建好的 tfidf_vec 對 documents 進行擬合,得到 TF-IDF 矩陣:
1 documents = [
2     'this is the bayes document',
3     'this is the second second document',
4     'and the third one',
5     'is this the document'
6 ]
7 tfidf_matrix = tfidf_vec.fit_transform(documents)
輸出文檔中所有不重復的詞:
1 print('不重復的詞:', tfidf_vec.get_feature_names())

運行結果

1 不重復的詞: ['and', 'bayes', 'document', 'is', 'one', 'second', 'the', 'third', 'this']
輸出每個單詞對應的 id 值:
1 print('每個單詞的 ID:', tfidf_vec.vocabulary_)
運行結果
1 每個單詞的 ID: {'this': 8, 'is': 3, 'the': 6, 'bayes': 1, 'document': 2, 'second': 5, 'and': 0, 'third': 7, 'one': 4}
輸出每個單詞在每個文檔中的 TF-IDF 值,向量里的順序是按照詞語的 id 順序來的:
1 print('每個單詞的 tfidf 值:', tfidf_matrix.toarray())
運行結果:
1 每個單詞的 tfidf 值: [[0.         0.63314609 0.40412895 0.40412895 0.         0.
2   0.33040189 0.         0.40412895]
3 [0.         0.         0.27230147 0.27230147 0.         0.85322574
4   0.22262429 0.         0.27230147]
5 [0.55280532 0.         0.         0.         0.55280532 0.
6   0.28847675 0.55280532 0.        ]
7 [0.         0.         0.52210862 0.52210862 0.         0.
8   0.42685801 0.         0.52210862]]
 
五、 如何對文檔進行分類
如果我們要對文檔進行分類,有兩個重要的階段:
1.基於分詞的數據准備 ,包括分詞、單詞權重計算、去掉停用詞;
2.應用朴素貝葉斯分類進行分類 ,首先通過訓練集得到朴素貝葉斯分類器,然后將分類器應用於測試集,並與實際結果做對比,最終得到測試集的分類准確率。
下面,我分別對這些模塊進行介紹。
 
模塊 1:對文檔進行分詞
在准備階段里,最重要的就是分詞。那么如果給文檔進行分詞呢?英文文檔和中文文檔所使用的分詞工具不同。
在英文文檔中,最常用的是 NTLK 包。NTLK 包中包含了英文的停用詞 stop words、分詞和標注方法。
1 import nltk
2 word_list = nltk.word_tokenize(text) # 分詞
3 nltk.pos_tag(word_list) # 標注單詞的詞性
在中文文檔中,最常用的是 jieba 包。jieba 包中包含了中文的停用詞 stop words 和分詞方法。
import jieba
word_list = jieba.cut (text) # 中文分詞
 
模塊 2:加載停用詞表
我們需要自己讀取停用詞表文件,從網上可以找到中文常用的停用詞保存在 stop_words.txt,然后利用 Python 的文件讀取函數讀取文件,保存在 stop_words 數組中。
1 stop_words = [line.strip().decode('utf-8') for line in io.open('stop_words.txt').readlines()]
 
模塊 3:計算單詞的權重
這里我們用到 sklearn 里的 TfidfVectorizer 類,上面我們介紹過它使用的方法。
直接創建 TfidfVectorizer 類,然后使用 fit_transform 方法進行擬合,得到 TF-IDF 特征空間 features,你可以理解為選出來的分詞就是特征。我們計算這些特征在文檔上的特征向量,得到特征空間 features。
1 tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5)
2 features = tf.fit_transform(train_contents)
這里 max_df 參數用來描述單詞在文檔中的最高出現率。假設 max_df=0.5,代表一個單詞在 50% 的文檔中都出現過了,那么它只攜帶了非常少的信息,因此就不作為分詞統計。
一般很少設置 min_df,因為 min_df 通常都會很小。
 
模塊 4:生成朴素貝葉斯分類器
我們將特征訓練集的特征空間 train_features,以及訓練集對應的分類 train_labels 傳遞給貝葉斯分類器 clf,它會自動生成一個符合特征空間和對應分類的分類器。
這里我們采用的是多項式貝葉斯分類器,其中 alpha 為平滑參數。為什么要使用平滑呢?因為如果一個單詞在訓練樣本中沒有出現,這個單詞的概率就會被計算為 0。但訓練集樣本只是整體的抽樣情況,我們不能因為一個事件沒有觀察到,就認為整個事件的概率為 0。為了解決這個問題,我們需要做平滑處理。
當 alpha=1 時,使用的是 Laplace 平滑。Laplace 平滑就是采用加 1 的方式,來統計沒有出現過的單詞的概率。這樣當訓練樣本很大的時候,加 1 得到的概率變化可以忽略不計,也同時避免了零概率的問題。
當 0<alpha<1 時,使用的是 Lidstone 平滑。對於 Lidstone 平滑來說,alpha 越小,迭代次數越多,精度越高。我們可以設置 alpha 為 0.001。
# 多項式貝葉斯分類器
1 from sklearn.naive_bayes import MultinomialNB  
2 clf = MultinomialNB(alpha=0.001).fit(train_features, train_labels)
 
模塊 5:使用生成的分類器做預測
首先我們需要得到測試集的特征矩陣。
方法是用訓練集的分詞創建一個 TfidfVectorizer 類,使用同樣的 stop_words 和 max_df,然后用這個 TfidfVectorizer 類對測試集的內容進行 fit_transform 擬合,得到測試集的特征矩陣 test_features。
1 test_tf = TfidfVectorizer(stop_words=stop_words, max_df=0.5, vocabulary=train_vocabulary)
2 test_features=test_tf.fit_transform(test_contents)
 
然后我們用訓練好的分類器對新數據做預測。
方法是使用 predict 函數,傳入測試集的特征矩陣 test_features,得到分類結果 predicted_labels。predict 函數做的工作就是求解所有后驗概率並找出最大的那個。
1 predicted_labels=clf.predict(test_features)
 
模塊 6:計算准確率
計算准確率實際上是對分類模型的評估。我們可以調用 sklearn 中的 metrics 包,在 metrics 中提供了 accuracy_score 函數,方便我們對實際結果和預測的結果做對比,給出模型的准確率。
使用方法如下:
1 from sklearn import metrics
2 print metrics.accuracy_score(test_labels, predicted_labels)
 
搜索關注微信公眾號“程序員姜小白”,獲取更新精彩內容哦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM