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

不少人都據說過貝葉斯原理,在哪據說過?基本上是在學機率統計的時候知道的。有些人可能會說,我記不住這些機率論的公式,不要緊,我儘可能用通俗易懂的語言進行講解。

/*請尊重做者勞動成果,轉載請標明原文連接:*/html

/* http://www.javashuo.com/article/p-wsikcjwu-cs.html  * /程序員

貝葉斯原理是英國數學家托馬斯·貝葉斯提出的。貝葉斯是個很神奇的人,他的經歷相似梵高。生前沒有獲得重視,死後,他寫的一篇關於概括推理的論文被朋友翻了出來,並發表了。這一發表沒關係,結果這篇論文的思想直接影響了接下來兩個多世紀的統計學,是科學史上著名的論文之一。
貝葉斯原理跟咱們的生活聯繫很是緊密。舉個例子,若是你看到一我的老是花錢,那麼會推斷這我的多半是個有錢人。固然這也不是絕對,也就是說,當你不能準確預知一個事物本質的時候,你能夠依靠和事物本質相關的事件來進行判斷,若是事情發生的頻次多,則證實這個屬性更有可能存在。    
 
1、 貝葉斯原理
貝葉斯原理是怎麼來的呢?貝葉斯爲了解決一個叫「逆向機率」問題寫了一篇文章,嘗試解答在沒有太多可靠證據的狀況下,怎樣作出更符合數學邏輯的推測。
 
什麼是「逆向機率」呢?
所謂「逆向機率」是相對「正向機率」而言。正向機率的問題很容易理解,好比咱們已經知道袋子裏面有 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。
爲了訓練樸素貝葉斯模型,咱們須要先給出訓練數據,以及這些數據對應的分類。那麼上面這兩個機率,也就是類別機率和條件機率。他們均可以從給出的訓練數據中計算出來。一旦計算出來,機率模型就可使用貝葉斯原理對新數據進行預測。
 
另外我想告訴你的是,貝葉斯原理、貝葉斯分類和樸素貝葉斯這三者之間是有區別的。
貝葉斯原理是最大的概念,它解決了機率論中「逆向機率」的問題,在這個理論基礎上,人們設計出了貝葉斯分類器,樸素貝葉斯分類是貝葉斯分類器中的一種,也是最簡單,最經常使用的分類器。樸素貝葉斯之因此樸素是由於它假設屬性是相互獨立的,所以對實際狀況有所約束,若是屬性之間存在關聯,分類準確率會下降。不過好在對於大部分狀況下,樸素貝葉斯的分類效果都不錯。
 
 
2、 樸素貝葉斯分類工做原理
樸素貝葉斯分類是經常使用的貝葉斯分類方法。咱們平常生活中看到一個陌生人,要作的第一件事情就是判斷 TA 的性別,判斷性別的過程就是一個分類的過程。根據以往的經驗,咱們一般會從身高、體重、鞋碼、頭髮長短、服飾、聲音等角度進行判斷。這裏的「經驗」就是一個訓練好的關於性別判斷的模型,其訓練數據是平常中遇到的各式各樣的人,以及這些人實際的性別數據。
 
離散數據案例
咱們遇到的數據能夠分爲兩種,一種是離散數據,另外一種是連續數據。那什麼是離散數據呢?離散就是不連續的意思,有明確的邊界,好比整數 1,2,3 就是離散數據,而 1 到 3 之間的任何數,就是連續數據,它能夠取在這個區間裏的任何數值。
我如下面的數據爲例,這些是根據你以前的經驗所得到的數據。而後給你一個新的數據:身高「高」、體重「中」,鞋碼「中」,請問這我的是男仍是女?
針對這個問題,咱們先肯定一共有 3 個屬性,假設咱們用 A 表明屬性,用 A1, A2, A3 分別爲身高 = 高、體重 = 中、鞋碼 = 中。一共有兩個類別,假設用 C 表明類別,那麼 C1,C2 分別是:男、女,在未知的狀況下咱們用 Cj 表示。
那麼咱們想求在 A一、A二、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.五、標準差爲 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 中,有第三方庫能夠直接幫咱們進行上面的操做,這個咱們會在下文中介紹。這裏主要是給你講解下具體的運算原理。
 
3、樸素貝葉斯分類器工做流程
樸素貝葉斯分類經常使用於文本分類,尤爲是對於英文等語言來講,分類效果很好。它經常使用於垃圾文本過濾、情感預測、推薦系統等。
樸素貝葉斯分類器須要三個流程,我來給你一一講解下這幾個流程。
第一階段:準備階段
在這個階段咱們須要肯定特徵屬性,好比上面案例中的「身高」、「體重」、「鞋碼」等,並對每一個特徵屬性進行適當劃分,而後由人工對一部分數據進行分類,造成訓練樣本。
這一階段是整個樸素貝葉斯分類中惟一須要人工完成的階段,其質量對整個過程將有重要影響,分類器的質量很大程度上由特徵屬性、特徵屬性劃分及訓練樣本質量決定。
第二階段:訓練階段
這個階段就是生成分類器,主要工做是計算每一個類別在訓練樣本中的出現頻率及每一個特徵屬性劃分對每一個類別的條件機率。
輸入是特徵屬性和訓練樣本,輸出是分類器。
第三階段:應用階段
這個階段是使用分類器對新數據進行分類。輸入是分類器和新數據,輸出是新數據的分類結果。
好了,在此次課中你瞭解了機率論中的貝葉斯原理,樸素貝葉斯的工做原理和工做流程,也對樸素貝葉斯的強大和限制有了認識。下一節中,我將帶你實戰,親自掌握 Python 中關於樸素貝葉斯分類器工具的使用。
 
4、 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]]
 
5、 如何對文檔進行分類
若是咱們要對文檔進行分類,有兩個重要的階段:
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)
 
搜索關注微信公衆號「程序員姜小白」,獲取更新精彩內容哦。
相關文章
相關標籤/搜索