機器學習|樸素貝葉斯演算法(二)-用sklearn實踐貝葉斯

kissjz發表於2018-01-29

相信上一篇部落格肯定已經讓你瞭解了啥叫樸素貝葉斯演算法,好歹知道貝葉斯公式是咋來的了,夠了!接下來會談一談我在剛接觸機器學習時,通過sklearn這個實驗級的庫感受到的樸素貝葉斯演算法的強大。

tip:文章可能很長,希望看完了能有所收穫

機器學習|樸素貝葉斯演算法(一)-貝葉斯簡介及應用
機器學習|樸素貝葉斯演算法(二)-用sklearn實踐貝葉斯
機器學習|樸素貝葉斯演算法(三)-深入理解樸素貝葉斯原理

初學機器學習,我用的是python中的sklearn庫(scikit-learn)。
這裡簡單的介紹一下這個強大的庫:

簡單高效的資料探勘和資料分析工具
可供所有人使用,並可在各種環境下重複使用
基於NumPy,SciPy和matplotlib(都是python強大的資料處理庫)
開源!!!也就是說每一個具體的function我們都能看到原始碼!

那麼如何用sklearn來做機器學習呢?

資料的預處理(Preprocess),這個其實是最頭痛的過程,按照具體情況而異,因為我也是剛剛入坑機器學期不久,也沒有實戰的經驗(以後會有啦,還會補充),這裡就簡單談一下如何用sklearn做一個樸素貝葉斯演算法(naïve_bayes)的分類器(NextGEN Gallery ),聽說還有半樸素貝葉斯分類器(semi-naïve Byes classficat)。。。

首先再來說一下貝葉斯分類器的分類原理

通過某物件的先驗概率,利用貝葉斯公式計算出其後驗概率,即該物件屬於某一類的概率,選擇具有最大後驗概率的類作為該物件所屬的類。目前研究較多的貝葉斯分類器主要有四種,分別是:Naive Bayes、TAN、BAN和GBN。

先驗概率,後驗概率,似然和概率,我相信很多人是跟我之前是一樣是非常糊(meng)塗(bi),這裡也不深入研究,就簡單說一下目前我的理解,如果覺得說的哪裡不對,歡迎部落格下方留下指教哈( ̄︶ ̄)↗ 

先驗概率:事情還沒有發生,要求這件事情發生的可能性大小。比如說你扔一枚硬幣,求它正面朝上的概率,基於我們之前拋擲一百萬次的事實基礎,我們知道的這個概率就是先驗概率。

下面重點來說說似然(函式)和概率,這個也是整了一會也問了老師才徹(gang)底(gang)明(ru)白(men)的。

什麼叫似然?

似然就是從觀察值來推測引數,換句話說,似然是在未知資料分佈函式的情況下,根據已有的觀察值去推斷該觀察值來源於什麼樣的分佈函式的概率,這裡我觀察值可以理解為分類的結果。更專業的解釋:似然函式也稱作似然,是一個關於統計模型引數的函式。也就是這個函式中自變數是統計模型的引數(一個變數概率分佈函式的自變數就是那個$X$,這裡可以理解成反過來,也就是上文所說的,已知一個觀測到的結果去求一種引數設定對產生這個結果的概率是多少)。對於結果 $x$ ,在引數集合 $θ$ 上的似然,就是在給定這些引數值的基礎上,觀察到的結果的概率 $L(θ|x)=P(x|θ)$ 。也就是說,似然是關於引數的函式,在引數給定的條件下,對於觀察到的 $x$ 的值的條件分佈。最後來舉個例子,同樣的像上文一樣我拋一枚硬幣十次,觀察到的結果十次都是朝上,那麼請問“這個硬幣是正反兩面均勻的可能性是多少”,這裡求的“可能性”就是似然。

什麼叫概率?

概率是有了引數來預測觀察值,話句話講,概率就是已知資料分佈函式去推斷的。

好了,難點終於解釋完了,那麼後驗概率呢?可別想矇混過關。

什麼叫後驗概率?

是在得到觀察值之後在重新加以修正的概率,也就是所謂的條件概率。

再來看一個公式:$Posterior∝Likelihood∗Prior$(後驗概率正比於似然乘以先驗概率),這樣就能更好理解了,其實就是第一篇裡舉例的時候說到的,其實是有貝葉斯公式得來的,只不過我們在解決問題的時候分母是同一個,也就是固定的,所以就可以推匯出這個正比的關係。

不信你再看一遍貝葉斯公式:$P ( H | E ) = frac{P (E | H) * P (H)}{P (E)}$

$P (E | H)$就是似然函式,而$P(H)$就是先驗概率(Prior),$P(E)$起到歸一化作用。啥叫歸一化,簡單來說就是為了使資料之間具有可比較性而進行的標準化處理使其處於同一數量級,所以歸一化也叫標準化,比如1釐米和1米就沒有可比較性,要麼同一到釐米,要麼同一到米唄。

而在scikit-learn中,一共有3個樸素貝葉斯的分類演算法類。分別是GaussianNB,MultinomialNB和BernoulliNB。這三種分類演算法是按照先驗的不同而劃分產生的,其中GaussianNB就是先驗為高斯分佈的樸素貝葉斯,MultinomialNB就是先驗為多項式分佈的樸素貝葉斯,而BernoulliNB就是先驗為伯努利分佈的樸素貝葉斯。

樸素貝葉斯方法是一種基於貝葉斯定理和每對特徵間獨立假設的監督學習演算法。 給定一個類變數和一個從屬特徵向量,貝葉斯定理說明了如下關係:

$$
Pleft ( y|x_{1},…,x_{n}
ight )=frac{Pleft ( y
ight )Pleft ( x_{1},…x_{n}|y
ight )}{Pleft ( x_{1},…x_{n}
ight )}
$$

使用樸素獨立的假設我們可以知道:

$$
Pleft ( x_{i}|y,x_{1},…,x_{i-1},..x_{i+1},…x_{n}
ight )=Pleft ( x_{i}|y
ight )
$$

其實上面的 $Pleft ( x_{i}
ight |y,x_{1},x_{2},….x_{i-1},x_{i},…x_{n})$這個意思就是$x_{i}$在$y,x_{1},x_{2},….x_{i-1},x_{i},…x_{n}$這些變數的聯合條件(自創概念)下的概率,又因為我們所採用的樸素貝葉斯分類進行了“屬性條件獨立性假設”,也就是說每一個$x_{i}$之間互相獨立,所以上等式成立。

既然自創了聯合條件,那麼我還是把什麼叫聯合概率簡單說一下吧!

以二維的舉例:

二位隨機變數(X,Y)的性質不僅與X及Y有關,而且還(可能相互依賴,比如樸素貝葉斯就假設相互獨立)依賴於這兩個隨機變數的相互關係。因此,藉助“分佈函式”來研究二維隨機變數。

設(X,Y)是二維隨機變數,對於任意實數$x,y,$二元函式:

$$
Fleft(x,y
ight )=Pleft { left(Xleqslant x
ight )cap left(Yleqslant y
ight )
ight }Rightarrow
$$

$$
Pleft { Xleqslant x,Yleqslant y
ight }
$$

稱為二維隨機變數(X,Y)的(聯合)分佈函式。

由上面分析,可以得到這個等式:$Pleft(x_{1},…,x_{n}|y
ight )=prod_{i=1}^{n}Pleft(x_{i}|y
ight )$

因此,對所有的 i 這個關係可以被簡化為:

$$
Pleft ( y|x_{1},…,x_{n}
ight )=frac{Pleft ( y
ight )prod_{i=1}^{n}Pleft ( x_{i}|y
ight )}{Pleft ( x_{1},……x_{n}
ight )}
$$

由於輸入的$Pleft(x_{1},…,x_{n}
ight)$是固定不變的,我們可以使用下面的分類規則:

$$
Pleft(y|x_{1},…x_{n}
ight )propto Pleft(y
ight )prod_{i=1}^{n}Pleft(x_{i}|y
ight )
$$

$$
Rightarrow
$$

$$
hat{y}=argunderset{y}{max}Pleft ( y
ight )prod_{i=1}^{n}Pleft ( x_{i}|y
ight )
$$

我們可以用最大後驗估計(Maximum A Posteriori ,MAP)來估計$Pleft(y
ight)$和$Pleft(x_{i}|y
ight )$,其中$Pleft(y
ight)$是訓練集中y的相對頻率(也就是$y$訓練集總數)。

不同的樸素貝葉斯分類器的主要區別在於它們對$Pleft(x_{i}|y
ight )$的分佈的假設。

顯然樸素貝葉斯是在假設條件之間互相獨立(顯然,這樣簡化貌似有點草率),但是樸素貝葉斯分類器已經在許多現實世界的情況下工作得卻很好,尤其是在的文件分類垃圾郵件過濾的應用上。因為他們需要少量的訓練資料來估計必要的引數,比如上文提到的垃圾郵件過濾實踐,只需要一封垃圾郵件,就能估計出很多相似型別的郵件為垃圾郵件。

和其他機器學習演算法相比,sklearn中樸素貝葉斯演算法的可調引數相對較少,而且學習難度也低(要不咋第一篇寫呢),但是分類所需時間卻可以非常的快(我試過和SVM比較過,忘了是fit()時間較少還是predict()時間較少了,這個自己遇到動手試一下就ojbk啦)。類別條件特徵分佈的解耦(啥叫耦合,這裡意思就是條件特徵相互有影響)意味著每個分佈可以被獨立地估計為一維分佈。這就有助於減少維度過多帶來的麻煩。
另一方面,儘管樸素貝葉斯(Naïve Bayes)被認為是一個不錯的分類器,但它被認為是一個不好的估計器,所以一般不用它來獲得測試向量的概率估計。

下面貼一下我用sklearn程式碼吧!(資料預處理省略(我也不會(ノへ ̄、)))

def classify(features_train, labels_train):
    import numpy as np 
    from sklearn.naive_bayes 
    import GaussianNB 
    X = features_train 
    Y = labels_train 
    clf = GaussianNB() 
    clf.fit(X, Y) 
    return clf 
  
 
def NB_Accuracy(features_train, labels_train,features_test, labels_test): 
  """ 計算分類器的準確率""" 
  ### 匯入sklearn模組的GaussianNB 
  from sklearn.naive_bayes import GaussianNB 
  
  ### 建立分類器 
  clf = GaussianNB() 
  
  ### 訓練分類器 
  X=features_train 
  Y=labels_train 
  clf.fit(X,Y) 
  
  ### 用訓練好的分類器去預測測試集的標籤值 
  pred =clf.predict(features_test) 
  
  ### 計算並返回在測試集上的準確率 
  from sklearn.metrics import accuracy_score 
  y_pred =pred 
  y_true =labels_test
  accuracy_score(y_true, y_pred) 
  
  return accuracy_score(y_true, y_pred,normalize=False)

sklearn我覺得應該算是實驗級的機器學期庫,也是開源的,如果初學機器學習,不妨用sklearn上手,可以在不知其所以然的情況下進行預測等一些機器學習實踐,讓你自信心爆棚!下面會從另一個角度再理解一下樸素貝葉斯演算法,加深對演算法的理解,何樂而不為呢


相關文章