贝叶斯原理
贝叶斯为了解决一个叫“逆向概率”问题写了一篇文章,尝试解答在没有太多可靠证据的情况下,怎样做出更符合数学逻辑的推测
“逆向概率”是相对“正向概率”而言
正向概率,比较容易理解,比如我们已经知道袋子里面有N 个球,不是黑球就是白球,其中M个是黑球,那么把手伸进去摸一个球,就能知道摸出黑球的概率是多少 => 这种情况往往是上帝视角,即了解了事情的全貌再做判断
逆向概率,贝叶斯则从实际场景出发,提了一个问题:如果我们事先不知道袋子里面黑球和白球的比例,而是通过我们摸出来的球的颜色,能判断出袋子里面黑白球的比例么?
贝叶斯原理:
影响了接下来近200年的统计学理论
建立在主观判断的基础上:在我们不了解所有客观事实的情况下,同样可以先估计一个值
先验概率,通过经验来判断事情发生的概率
后验概率,就是发生结果之后,推测原因的概率
条件概率,事件A 在另外一个事件B已经发生条件下的发生概率,表示为P(A|B)
似然函数,把概率模型的训练过程理解为求参数估计的过程
比如,一个硬币在10次抛落中正面均朝上 => 那么这个硬币是均匀的可能性是多少?这里硬币均匀就是个参数,似然函数就是用来衡量这个模型的参数
经过推导,贝叶斯推理告诉我们后验概率是与先验概率和似然函数成正比得,即
Thinking:假设有一种病叫做“贝叶死”,它的发病率是万分之一,即10000 人中会有1个人得病。现有一种测试可以检验一个人是否得病的准确率是99.9%,误报率(假阳)是0.1%
那么,如果一个人被查出来患有“叶贝死”,实际上患有的可能性有多大?
查出患有“贝叶死”的准确率是99.9%,是不是实际上患“贝叶死”的概率也是99.9%?)
在10000个人中,还存在0.1%的误查的情况,也就是10个人没有患病但是被诊断成阳性。当然10000个人中,也确实存在一个患有贝叶死的人,他有99.9%的概率被检查出来
可以粗算下,患病的这个人实际上是这11个人里面的一员,即实际患病比例是1/11≈9%
贝叶斯原理就是求解后验概率,假设:A 表示事件 “测出为阳性”, B1 表示“患有贝叶死”, B2 表示“没有患贝叶死”
患有贝叶死的情况下,测出为阳性的概率为P(A|B1)=99.9%
没有患贝叶死,但测出为阳性的概率为P(A|B2)=0.1%
患有贝叶死的概率为 P(B1)=0.01%
没有患贝叶死的概率P(B2)=99.99%
那么我们检测出来为阳性,而且是贝叶死的概率P(B1,A)=P(B1)*P(A|B1)=0.01%*99.9%=0.00999% ≈0.01%
P(B1,A)代表的是联合概率,同样我们可以求得P(B2,A)=P(B2)*P(A|B2)=99.99%*0.1%=0.09999% ≈0.1%
检查为阳性的情况下,患有贝叶死的概率,即P(B1|A)
检查出是阳性的条件下,但没有患有贝叶死的概率为
0.01%+0.1%均出现在了P(B1|A)和P(B2|A)的计算中作为分母,称之为论据因子,也相当于一个权值因子
我们可以总结出贝叶斯公式
从而我们可以得到通用的贝叶斯公式
朴素贝叶斯:
一种简单但极为强大的预测建模算法
假设每个输入变量是独立的。这是一个强硬的假设,实际情况并不一定,但是这项技术对于绝大部分的复杂问题仍然非常有效
朴素贝叶斯模型由两种类型的概率组成:
每个类别的概率P(Cj)
每个属性的条件概率P(Ai|Cj)
什么是类别概率:
假设我有7个棋子,其中3个是白色的,4个是黑色的
那么棋子是白色的概率就是3/7,黑色的概率就是4/7 => 这个是类别概率
什么是条件概率:
假设我把这7个棋子放到了两个盒子里,其中盒子A里面有2个白棋,2个黑棋;盒子B里面有1个白棋,2个黑棋
那么在盒子A中抓到白棋的概率就是1/2,抓到黑棋的概率也是1/2,这个就是条件概率,也就是在某个条件(比如在盒子A中)下的概率
训练朴素贝叶斯模型的过程:
在朴素贝叶斯中,我们要统计的是属性的条件概率,也就是假设取出来的是白色的棋子,那么它属于盒子A的概率是2/3
Step1:先给出训练数据,以及这些数据对应的分类
Step2,计算类别概率和条件概率
Step3,使用概率模型(基于贝叶斯原理)对新数据进行预测
朴素贝叶斯分类(离散值):
如何根据身高,体重,鞋码,判断是否为男女,比如一个新的数据:身高“高”、体重“中”,鞋码“中” => 男 or 女?
求在A1、A2、A3属性下,Cj的概率
因为一共有2个类别,所以我们只需要求得P(C1|A1A2A3)和P(C2|A1A2A3)的概率即可,然后比较下哪个分类的可能性大,就是哪个分类结果
分别求下这些条件下的概率:
P(A1|C1)=1/2, P(A2|C1)=1/2, P(A3|C1)=1/4
P(A1|C2)=0, P(A2|C2)=1/2, P(A3|C2)=1/2
所以P(A1A2A3|C1)=1/16, P(A1A2A3|C2)=0
因为P(A1A2A3|C1)P(C1)>P(A1A2A3|C2)P(C2),所以应该是C1类别,即男性
朴素贝叶斯分类(连续值):
身高180、体重120,鞋码41,请问该人是男是女呢
可以假设男性和女性的身高、体重、鞋码都是正态分布,通过样本计算出均值和方差,也就是得到正态分布的密度函数。有了密度函数,就可以把值代入,算出某一点的值
比如,男性的身高是均值179.5、标准差为3.697的正态分布。所以男性的身高为180的概率为0.1069
同理可以计算得出男性体重为120的概率为0.000382324,男性鞋码为41号的概率为0.120304111
P(A1A2A3|C1)=P(A1|C1)P(A2|C1)P(A3|C1)=0.1069*0.000382324*0.120304111=4.9169e-6
P(A1A2A3|C2)=P(A1|C2)P(A2|C2)P(A3|C2)=0.00000147489*0.015354144*0.120306074=2.7244e-9
很明显这组数据分类为男的概率大于分类为女的概率
求标准差和方差的方法
Excel中的NORMDIST函数:
NORMDIST(x,mean,standard_dev,cumulative)
x:正态分布中,需要计算的数值;
Mean:正态分布的平均值;
Standard_dev:正态分布的标准差;
Cumulative:取值为逻辑值,即False或True,决定了函数的形式当为True时,函数结果为累积分布
当为False时,函数结果为概率密度
NORMDIST(180,179.5,3.697,0)=0.1069
Python中的概率密度:
stats.norm.pdf(x, mu, sigma)
返回参数为 和 的正态分布密度函数在x处的值
from scipy import stats
mu = 179.5
sigma = 3.697
x = 180
prob = stats.norm.pdf(x, mu, sigma)
print(prob)
朴素贝叶斯分类:
常用于文本分类,文本过滤、情感预测、推荐系统等,尤其是对于英文等语言来说,分类效果很好
准备阶段,需要确定特征属性,属性值以及label => 训练集
训练阶段,输入是特征属性和训练样本,输出是分类器,主要工作是计算每个类别在训练样本中的出现频率及每个特征属性划分对每个类别的条件概率
应用阶段,使用分类器对新数据进行分类
三种分布方式
sklearn工具使用:
from sklearn.naive_bayes import GaussianNB
高斯朴素贝叶斯:特征变量是连续变量,符合高斯分布(正太分布),比如说人的身高,物体的长度
GaussianNB(priors=None) #模型创建
priors,先验概率大小,如果没有给定,模型则根据样本数据自己计算(利用极大似然法)
查看模型对象的属性:
class_prior_:每个样本的概率
class_count_:每个类别的样本数量
theta_:每个类别中每个特征的均值
sigma_:每个类别中每个特征的方差
from sklearn.naive_bayes import MultinomialNB
多项式朴素贝叶斯:特征变量是离散变量,符合多项分布,在文档分类中特征变量体现在一个单词出现的次数,或者是单词的TF-IDF值等
MultinomialNB(alpha=1.0, fit_prior=True, class_prior=None)
alpha:先验平滑因子,默认等于1,当等于1时表示拉普拉斯平滑
fit_prior:是否去学习类的先验概率,默认是True
class_prior:各个类别的先验概率,如果没有指定,则模型会根据数据自动学习, 每个类别的先验概率相同,即类别数N分之一
模型对象的属性:
class_count_: 训练样本中各类别对应的样本数
feature_count_: 每个类别中各个特征出现的次数
from sklearn.naive_bayes import BernoulliNB
伯努利朴素贝叶斯:特征变量是布尔变量,符合0/1分布,在文档分类中特征是单词是否出现
BernoulliNB(alpha=1.0, fit_prior=True, class_prior=None)
alpha:平滑因子,与多项式中的alpha一致
fit_prior:是否去学习类的先验概率,默认是True
class_prior:各个类别的先验概率,如果没有指定,则模型会根据数据自动学习, 每个类别的先验概率相同,即类别数N分之一
模型对象的属性:
class_count_: 训练样本中各类别对应的样本数
feature_count_: 每个类别中各个特征出现的次数
代码
# MNIST手写数字分类(多种分类方法)
# 分割数据,将25%的数据作为测试集,其余作为训练集
train_x, test_x, train_y, test_y = train_test_split(data, digits.target, test_size=0.25, random_state=33)
# 创建LR分类器
model = LogisticRegression()
model.fit(train_x, train_y)
predict_y=model.predict(test_x)
print('LR准确率: %0.4lf' % accuracy_score(predict_y, test_y))
# 创建GaussianNB分类器
model = GaussianNB()
model.fit(train_x, train_y)
predict_y=model.predict(test_x)
print('GaussianNB准确率: %0.4lf' % accuracy_score(predict_y, test_y))
# 创建MultinomialNB分类器
model = MultinomialNB()
model.fit(train_x, train_y)
predict_y=model.predict(test_x)
print('MultinomialNB准确率: %0.4lf' % accuracy_score(predict_y, test_y))
# 创建BernoulliNB分类器
model = BernoulliNB()
model.fit(train_x, train_y)
predict_y=model.predict(test_x)
print('BernoulliNB准确率: %0.4lf' % accuracy_score(predict_y, test_y))
根据训练的结果选择最接近的方案