1. 程式人生 > >python 貝葉斯演算法

python 貝葉斯演算法

python貝葉斯演算法(sklearn.naive_bayes),會通過了解什麼是貝葉斯、貝葉斯公式推導、實際案例去講解。也同時記錄學習的過程幫組大家一起學習如果實際應該貝葉斯演算法去分析。

貝葉斯解決問題介紹:

貝葉斯演算法是英國數學家貝葉斯(約1701-1761)Thomas Bayes,生前提出為解決“逆概”問題寫的一篇文章。 “逆概”就是逆向概率,有逆向概率就會有正向概率。舉個簡單的例子就能理解什麼是正向概率和逆向概率:

  • 正向概率:假設袋子裡面有兩種球N個白球和M個黑球,你伸手進去摸一個,摸出黑球的概率有多大?正向算概率我們就用黑球的個數除以球的總數就等於摸出黑球的概率。
  • 逆向概率:如果我們事先不知道袋子裡有多少個球,也不知道黑白球的比例。而是閉著眼睛隨便摸一個(或者摸多個)球,觀察這些取出來的球的顏色之後。那麼我們可以就此對袋子裡面的黑白球的比例作出推測。

現實世界本身就是不確定的,人類的觀察能力有限。我們日常所觀察到的只是事物表面上的結果,因此我們需要提供一個猜測。這個就是貝葉斯需要解決的問題。

逆向概率例子:

有一個學校男生女生比例分別為60%和40%,男生100%穿長褲,女生50%會穿長褲剩下的會穿裙子。遠處的校門口走來一個穿長褲的學生,無法判斷性別。求這個學生是女生的概率有多大?

我們先按自己現在方式進行思考一下,要求這個穿長褲的學生是女生的概率。

案例公式推導: 因為不知道學校總人數是多少,我們就假設總人數為U 穿長褲的男生數:P(Boy)男生的概率,P(Pants|Boy)男生穿長褲的概率 UP(Boy)P(PantsBoy)U*P(Boy)*P(Pants|Boy)

穿長褲的女生數:P(Girl)女生的概率,P(Pants|Girl)女生穿長褲的概率 UP(Girl)P(PantsGirl)U*P(Girl)*P(Pants|Girl) 穿長褲的總人數: UP(Boy)P(PantsBoy)+UP(Girl)P(PantsGirl)U*P(Boy)*P(Pants|Boy)+U*P(Girl)*P(Pants|Girl) 那麼女生穿長褲的概率:穿長褲的女生數/穿長褲的總人數U
P(Girl)P(PantsGirl)UP(Boy)P(PantsBoy)+UP(Girl)P(PantsGirl)\frac{U*P(Girl)*P(Pants|Girl)}{U*P(Boy)*P(Pants|Boy)+U*P(Girl)*P(Pants|Girl)}
公式化簡: P(Girl)P(PantsGirl)P(Girl)P(PantsGirl)+P(Boy)P(PantsBoy)\frac{P(Girl)*P(Pants|Girl)}{P(Girl)*P(Pants|Girl)+P(Boy)*P(Pants|Boy)} 所以最終走過了穿長褲可能是女生的概率為: 0.40.50.61+0.40.5=0.20.8=0.25\frac{0.4*0.5}{0.6*1+0.4*0.5}=\frac{0.2}{0.8}=0.25

貝葉斯公式介紹:

P(AB)=P(BA)P(A)P(B)P(A|B)=\frac{P(B|A)P(A)}{P(B)} 結合上面我們講女生穿褲子的概率問題來帶入一下,我們擬定: A1:女生,A2:男生 B1:穿褲子,B2:未穿褲子 P(A1):就是女生的概率,已知條件0.40.4 P(B1):就是穿褲子的概率,男生穿褲子的概率+女生穿褲子的概率及0.61+0.40.50.6*1+0.4*0.5 我們要求的P(A1|B1):穿褲子中是女生的概率 P(B1|A1):就是女生穿褲子的概率,已知條件0.50.5 P(A1B1)=P(B1A1)P(A1)P(B)=0.50.40.61+0.50.4=0.25P(A1|B1)=\frac{P(B1|A1)P(A1)}{P(B)}=\frac{0.5*0.4}{0.6*1+0.5*0.4}=0.25 所以帶入公式就得到上面通推導的結果,穿褲子的女生概率為0.25。這個地方有點繞,需要多多理解一下。

sklearn中的貝葉斯模組

參考博主:https://blog.csdn.net/brucewong0516/article/details/78798359 樸素貝葉斯是一類比較簡單的演算法,scikit-learn中樸素貝葉斯類庫的使用也比較簡單。相對於決策樹,KNN之類的演算法,樸素貝葉斯需要關注的引數是比較少的,這樣也比較容易掌握。在scikit-learn中,常用的有3個樸素貝葉斯的分類演算法類。分別是GaussianNBMultinomialNBBernoulliNB。這三個類適用的分類場景各不相同其中:

  • GaussianNB:就是先驗為高斯分佈的樸素貝葉斯,一般來說如果樣本特徵的分佈大部分是連續值,使用GaussianNB會比較好
  • MultinomialNB:就是先驗為多項式分佈的樸素貝葉斯,如果如果樣本特徵的分大部分是多元離散值,使用MultinomialNB比較合適。
  • BernoulliNB:就是先驗為伯努利分佈的樸素貝葉斯,而如果樣本特徵是二元離散值或者很稀疏的多元離散值,應該使用。

naive_bayes.GaussianNB

GaussianNB類的主要引數僅有一個,即先驗概率priors,對應Y的各個類別的先驗概率P(Y=Ck)。這個值預設不給出,如果不給出此時P(Y=Ck)=mk/m。其中m為訓練集樣本總數量,mk為輸出為第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方法得到類別。
    • 三者區別舉例
    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]]
    
    

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

naive_bayes.MultinomialNB

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

fit_prior class_prior 最終先驗概率
False 填或不填沒有意義 P(Y=Ck)=1/kp(Y=Ck)=1/kP(Y=Ck)=1/kp(Y=Ck)=1/k
True 不填 P(Y=Ck)=mk/mp(Y=ck)=mk/mP(Y=Ck)=mk/mp(Y=ck)=mk/m
True P(Y=Ck)=p(Yck)=classpriorP(Y=Ck)=p(Y-ck)=class_prior

naive_bayes.BernoulliNB

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

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

貝葉斯的主要優缺點

貝葉斯的主要優點

  • 樸素貝葉斯模型發源於古典數學理論,有穩定的分類效率。
  • 對小規模的資料表現很好,能個處理多分類任務,適合增量式訓練,尤其是資料量超出記憶體時,我們可以一批批的去增量訓練。
  • 對缺失資料不太敏感,演算法也比較簡單,常用於文字分類。

貝葉斯的主要缺點

  • 理論上,樸素貝葉斯模型與其他分類方法相比具有最小的誤差率。但是實際上並非總是如此,這是因為樸素貝葉斯模型假設屬性之間相互獨立,這個假設在實際應用中往往是不成立的,在屬性個數比較多或者屬性之間相關性較大時,分類效果不好。而在屬性相關性較小時,樸素貝葉斯效能最為良好。
  • 需要知道先驗概率,且先驗概率很多時候取決於假設,假設的模型可以有很多種,因此在某些時候會由於假設的先驗模型的原因導致預測效果不佳。
  • 由於我們是通過先驗和資料來決定後驗的概率從而決定分類,所以分類決策存在一定的錯誤率。
  • 對輸入資料的表達形式很敏感。