原理请参考:
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的内容。