原理請參考:
http://www.ruanyifeng.com/blog/2011/08/bayesian_inference_part_one.html
http://www.javashuo.com/article/p-anjlwbbz-kd.htmlhtml
即 後驗機率 = 先驗機率 * 調整因子python
在分類中,先驗機率指樣本中該類別佔全部類別的機率,調整因子則是每一個樣本特徵的機率乘積,舉個例子。算法
帥不帥 | 性格 | 上進不 | 值不值得交朋友 | |
---|---|---|---|---|
帥 | 好 | 不上進 | 不值得 | |
不帥 | 很差 | 不上進 | 不值得 | |
帥 | 好 | 上進 | 值得 | |
不帥 | 好 | 上進 | 值得 |
這裏的先驗機率就是指:值得交朋友(1/2) , 不值得交朋友(1/2)api
調整因子是指你要預測的樣本的特徵機率,若是有一個樣本是不帥|好|不上進(例子特徵不分散,由於只有兩個值,咱們先無論這個)數組
那麼值得交的後驗機率= 1/2 * 調整因子 = 0, 調整因子 = 不帥在值得交的數據中佔(1/2) * 好在值得佔(1) * 不上進在值得佔(0)
不值得交的後驗機率 = 1/2* 1/2 * 1/2 * 1 = 1/8微信
因此這我的值不值得交呢,根據數據是1/8>0,那就是不值得交了。不過由於樣本數據較少,出現某個爲0的機率,這就有點問題了,由於實際不可能機率爲0的。app
因此咱們須要引入一個平滑參數,來使這個值不爲0機器學習
那麼咱們計算機率時不是直接使用:符合要求的樣本/總樣本,而是 符合要求的樣本 + alpha/(總樣本+標籤類別數或特徵類別數 * alpha),alpha通常取1.0學習
即先驗機率:值得交朋友(2 + 1/(4+2 * 1))=1/3 , 不值得交朋友(2 + 1/(4+2 * 1)) = 1/3code
而特徵機率的計算須要這樣計算:其餘先不看,咱們直接看值得交中不上進的機率(也就是先前爲0的機率)= 0+1/(2 + 21) = 1/4, 注意這裏的類別數是指len(上進,不上進)
值得交的後驗機率:1/3 1/2 * 3/4 * 1/4 = 1/32
不值得交的後驗機率: 1/3 * 1/2 * 1/2 * 3/4 = 1/16
雖然仍是不值得交,但至少值得交的機率不爲0了。若是你還不懂的話,直接看驗證碼的識別,而後在回來看這個。
sklearn.naive_bayes.MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
參數
固然還有其餘樸素貝葉斯分類或迴歸器,區別以下:
特徵是離散變量時,使用多項式模型(MultinomialNB)
當特徵是連續變量時,使用高斯模型(GaussianNB)
伯努利模型(BernoulliNB)和多項式模型是一致的,但要求特徵是二值化的(1,0)
根據上面的描述可知,像這種簡單驗證碼,可使用多項式模型,也可使用伯努利模型,由於圖片已經被二值化。
已知圖片是18x10的二維數組,數組的每一個元素都是0,1之間的數。咱們能夠組成180個特徵,而驗證碼都是0-9的數字,因此分類是這樣來計算的
假設180個特徵分別爲x1, x2,...,x180,標籤爲0-9,每一個標籤的樣本個數都是120個
某個樣本屬於0的機率:P(0) = P0(x1)P0(x2)....P0(x180)P總(0), P0(x1)表示x1在0類別樣本中所佔的比例(機率),P總(0)表示0佔總樣本的比例(機率)即1/10, 這些值都是能夠從訓練樣本求得。
代碼和KNN的基本同樣,以下:
from sklearn import naive_bayes import os from PIL import Image import numpy as np def func(): x = [] y = [] for label in os.listdir('train'): for file in os.listdir(f'train/{label}'): im = Image.open(f'train/{label}/{file}') pix = np.array(im) pix = (pix > 180) * 1 pix = pix.ravel() x.append(list(pix)) y.append(int(label)) train_x = np.array(x) train_y = np.array(y) model = naive_bayes.MultinomialNB(alpha=1) model.fit(train_x, train_y) x = [] y = [] for label in os.listdir('test'): for file in os.listdir(f'test/{label}'): im = Image.open(f'test/{label}/{file}') pix = np.array(im) pix = (pix > 180) * 1 pix = pix.ravel() x.append(list(pix)) y.append(int(label)) test_x = np.array(x) test_y = np.array(y) score = model.score(test_x, test_y) return score if __name__ == "__main__": score = func() print(score)
在這種簡單驗證碼識別上,樸素貝葉斯也能夠達到100%的正確率。若是將樣本特徵改爲16個的話,你會發現樸素貝葉斯和KNN錯誤的地方都是同樣的,都是同一個驗證碼識別成了同一個錯誤。
最後,我正在學習一些機器學習的算法,對於一些我須要記錄的內容我都會分享到博客和微信公衆號,歡迎關注。平時的話通常分享一些爬蟲或者Python的內容。另外,若是博客有錯誤的話,還請指出。
這是已標註的數據:https://www.lanzous.com/i8epywd
最後,我正在學習一些機器學習的算法,對於一些我須要記錄的內容我都會分享到博客和微信公衆號(python成長路),歡迎關注。平時的話通常分享一些爬蟲或者Python的內容。