scikit-learn 樸素貝葉斯類庫使用小結

劉建平Pinard發表於2016-11-17

    之前在樸素貝葉斯演算法原理小結這篇文章中,對樸素貝葉斯分類演算法的原理做了一個總結。這裡我們就從實戰的角度來看樸素貝葉斯類庫。重點講述scikit-learn 樸素貝葉斯類庫的使用要點和引數選擇。

1. scikit-learn 樸素貝葉斯類庫概述

    樸素貝葉斯是一類比較簡單的演算法,scikit-learn中樸素貝葉斯類庫的使用也比較簡單。相對於決策樹,KNN之類的演算法,樸素貝葉斯需要關注的引數是比較少的,這樣也比較容易掌握。在scikit-learn中,一共有3個樸素貝葉斯的分類演算法類。分別是GaussianNB,MultinomialNB和BernoulliNB。其中GaussianNB就是先驗為高斯分佈的樸素貝葉斯,MultinomialNB就是先驗為多項式分佈的樸素貝葉斯,而BernoulliNB就是先驗為伯努利分佈的樸素貝葉斯。

    這三個類適用的分類場景各不相同,一般來說,如果樣本特徵的分佈大部分是連續值,使用GaussianNB會比較好。如果如果樣本特徵的分大部分是多元離散值,使用MultinomialNB比較合適。而如果樣本特徵是二元離散值或者很稀疏的多元離散值,應該使用BernoulliNB。

2. GaussianNB類使用總結

    GaussianNB假設特徵的先驗概率為正態分佈,即如下式:

$$P(X_j=x_j|Y=C_k) = \frac{1}{\sqrt{2\pi\sigma_k^2}}exp\Bigg{(}-\frac{(x_j - \mu_k)^2}{2\sigma_k^2}\Bigg{)}$$

    其中$C_k$為Y的第k類類別。$\mu_k和\sigma_k^2$為需要從訓練集估計的值。

    GaussianNB會根據訓練集求出$\mu_k和\sigma_k^2$。 $\mu_k$為在樣本類別$C_k$中,所有$X_j$的平均值。$\sigma_k^2$為在樣本類別$C_k$中,所有$X_j$的方差。

    GaussianNB類的主要引數僅有一個,即先驗概率priors ,對應Y的各個類別的先驗概率$P(Y=C_k)$。這個值預設不給出,如果不給出此時$P(Y=C_k) = m_k/m$。其中m為訓練集樣本總數量,$m_k$為輸出為第k類別的訓練集樣本數。如果給出的話就以priors 為準。

    在使用GaussianNB的fit方法擬合資料後,我們可以進行預測。此時預測有三種方法,包括predict,predict_log_proba和predict_proba。

    predict方法就是我們最常用的預測方法,直接給出測試集的預測類別輸出。

    predict_proba則不同,它會給出測試集樣本在各個類別上預測的概率。容易理解,predict_proba預測出的各個類別概率裡的最大值對應的類別,也就是predict方法得到類別。

    predict_log_proba和predict_proba類似,它會給出測試集樣本在各個類別上預測的概率的一個對數轉化。轉化後predict_log_proba預測出的各個類別對數概率裡的最大值對應的類別,也就是predict方法得到類別。

    下面給一個具體的例子,程式碼如下,亦可見我的github

import numpy as np
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
Y = np.array([1, 1, 1, 2, 2, 2])
from sklearn.naive_bayes import GaussianNB
clf = GaussianNB()
#擬合資料
clf.fit(X, Y)
print "==Predict result by predict=="
print(clf.predict([[-0.8, -1]]))
print "==Predict result by predict_proba=="
print(clf.predict_proba([[-0.8, -1]]))
print "==Predict result by predict_log_proba=="
print(clf.predict_log_proba([[-0.8, -1]]))

    結果如下:

==Predict result by predict==
[1]
==Predict result by predict_proba==
[[  9.99999949e-01   5.05653254e-08]]
==Predict result by predict_log_proba==
[[ -5.05653266e-08  -1.67999998e+01]]

    從上面的結果可以看出,測試樣本[-0.8,-1]的類別預測為類別1。具體的測試樣本[-0.8,-1]被預測為1的概率為9.99999949e-01 ,遠遠大於預測為2的概率5.05653254e-08。這也是為什麼最終的預測結果為1的原因了。

    此外,GaussianNB一個重要的功能是有 partial_fit方法,這個方法的一般用在如果訓練集資料量非常大,一次不能全部載入記憶體的時候。這時我們可以把訓練集分成若干等分,重複呼叫partial_fit來一步步的學習訓練集,非常方便。後面講到的MultinomialNB和BernoulliNB也有類似的功能。

3. MultinomialNB類使用總結

    MultinomialNB假設特徵的先驗概率為多項式分佈,即如下式:

$$P(X_j=x_{jl}|Y=C_k) = \frac{x_{jl} + \lambda}{m_k + n\lambda}$$

    其中,$P(X_j=x_{jl}|Y=C_k)$是第k個類別的第j維特徵的第l個個取值條件概率。$m_k$是訓練集中輸出為第k類的樣本個數。$\lambda$ 為一個大於0的常數,常常取為1,即拉普拉斯平滑。也可以取其他值。

    MultinomialNB引數比GaussianNB多,但是一共也只有僅僅3個。其中,引數alpha即為上面的常數$\lambda$,如果你沒有特別的需要,用預設的1即可。如果發現擬合的不好,需要調優時,可以選擇稍大於1或者稍小於1的數。布林引數fit_prior表示是否要考慮先驗概率,如果是false,則所有的樣本類別輸出都有相同的類別先驗概率。否則可以自己用第三個引數class_prior輸入先驗概率,或者不輸入第三個引數class_prior讓MultinomialNB自己從訓練集樣本來計算先驗概率,此時的先驗概率為$P(Y=C_k) = m_k/m$。其中m為訓練集樣本總數量,$m_k$為輸出為第k類別的訓練集樣本數。總結如下:

fit_prior class_prior 最終先驗概率
false 填或者不填沒有意義 $P(Y=C_k) = 1/k$
true 不填 $P(Y=C_k) = m_k/m$
true $P(Y=C_k) = $class_prior

 

    在使用MultinomialNB的fit方法或者partial_fit方法擬合資料後,我們可以進行預測。此時預測有三種方法,包括predict,predict_log_proba和predict_proba。由於方法和GaussianNB完全一樣,這裡就不累述了。 

4. BernoulliNB類使用總結

    BernoulliNB假設特徵的先驗概率為二元伯努利分佈,即如下式:

$$P(X_j=x_{jl}|Y=C_k) = P(j|Y=C_k)x_{jl} + (1 - P(j|Y=C_k)(1-x_{jl}) $$

    此時$l$只有兩種取值。$x_{jl}$只能取值0或者1。

    BernoulliNB一共有4個引數,其中3個引數的名字和意義和MultinomialNB完全相同。唯一增加的一個引數是binarize。這個引數主要是用來幫BernoulliNB處理二項分佈的,可以是數值或者不輸入。如果不輸入,則BernoulliNB認為每個資料特徵都已經是二元的。否則的話,小於binarize的會歸為一類,大於binarize的會歸為另外一類。

    在使用BernoulliNB的fit或者partial_fit方法擬合資料後,我們可以進行預測。此時預測有三種方法,包括predict,predict_log_proba和predict_proba。由於方法和GaussianNB完全一樣,這裡就不累述了。

    以上就是scikit-learn 樸素貝葉斯類庫的使用的經驗總結。希望可以幫到朋友們。

 

(歡迎轉載,轉載請註明出處。歡迎溝通交流: liujianping-ok@163.com) 

相關文章