一天,小西找到小迪。python
小西:小迪,最近我闺蜜的男友向她求婚了。web
小迪:而后呢,她答应了吗?算法
小西:尚未呢,他们认识时间还不是很长。并且,我闺蜜以为那个男生有些方面不符合她的择偶标准,她如今也是很是纠结呢!网络
小迪:婚姻仍是要理性一点,若是她不知道该如何判断,或许朴素贝叶斯算法能够帮助她去理性得看待这个问题。dom
小西:朴素贝叶斯是什么?它是怎么帮助人类理性分析问题的呢?ide
小迪:贝叶斯分类算法是统计学的一种几率分类方法,朴素贝叶斯分类是贝叶斯分类中最简单的一种。其分类原理就是利用贝叶斯公式根据某特征的先验几率计算出其后验几率,而后选择具备最大后验几率的类做为该特征所属的类。之因此称之为”朴素”,是由于贝叶斯分类只作最原始、最简单的假设:全部的特征之间是统计独立的。svg
小西:听上去仍是很是多逻辑性呢!那咱们该如何使用它呢?函数
小迪:那咱们就以一个女生是否选择要嫁给一个男生为例解释一下这个算法。测试
想要搞懂朴素贝叶斯算法,必定要先理解条件几率公式跟全几率公式,这两个公式在大学时候咱们都学过,下面咱们来回顾一下。spa
假设某样本X有$a_1,a_2,…,a_n$个属性,那么有$P(X)=P(a_1,a_2,…,a_n) = P(a_1)*P(a_2)*…*P(a_n)$。知足这样的公式就说明特征统计独立。
条件几率(Condittional probability),就是指在事件B发生的状况下,事件A发生的几率,用P(A|B)来表示。
根据文氏图可知:在事件B发生的状况下,事件A发生的几率就是P(A∩B)除以P(B)。
同理可得:
因此,
接着看全几率公式,若是事件$A_1,A_2,A_3,…,A_n$构成一个完备事件且都有正几率,那么对于任意一个事件B则有:
根据条件几率和全几率公式,能够获得贝叶斯公式以下:
P(A)称为"先验几率"(Prior probability),即在B事件发生以前,咱们对A事件几率的一个判断。
P(A|B)称为"后验几率"(Posterior probability),即在B事件发生以后,咱们对A事件几率的从新评估。
P(B|A)/P(B)称为"可能性函数"(Likely hood),这是一个调整因子,使得预估几率更接近真实几率。
因此条件几率能够理解为:后验几率 = 先验几率 * 调整因子
若是"可能性函数">1,意味着"先验几率"被加强,事件A的发生的可能性变大;
若是"可能性函数"=1,意味着B事件无助于判断事件A的可能性;
若是"可能性函数"<1,意味着"先验几率"被削弱,事件A的可能性变小。
下面咱们就以“嫁不嫁”这个问题应用一下咱们的朴素贝叶斯算法。
颜值 | 性格 | 上进否 | 嫁与否 |
---|---|---|---|
帅 | 好 | 上进 | 嫁 |
不帅 | 好 | 通常 | 不嫁 |
不帅 | 很差 | 不上进 | 不嫁 |
帅 | 好 | 通常 | 嫁 |
不帅 | 好 | 上进 | 嫁 |
帅 | 很差 | 通常 | 不嫁 |
帅 | 好 | 不上进 | 嫁 |
不帅 | 很差 | 上进 | 不嫁 |
帅 | 很差 | 上进 | 嫁 |
不帅 | 好 | 不上进 | 不嫁 |
上面这张表是根据女生根据假象男生的性格来决定是否嫁给他的标准信息表,咱们利用这张表来针对特定男生的信息计算是否值得嫁的几率。
假设某个男生帅,性格很差,不上进,那么:
根据贝叶斯公式:
转换成分类任务的表达式:
<svg xmlns:xlink="http://www.w3.org/1999/xlink&...; width="34.537ex" height="6.313ex" viewBox="0 -1610.3 14870.2 2718" role="img" focusable="false" style="vertical-align: -2.573ex;" class="in-text-selection"><g stroke="currentColor" fill="currentColor" stroke-width="0" transform="matrix(1 0 0 -1 0 0)"><g transform="translate(1140,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">类</text></g><g transform="translate(1943,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">别</text></g><g transform="translate(3024,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">特</text></g><g transform="translate(3828,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">征</text></g><g transform="translate(7494,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">类</text></g><g transform="translate(8297,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">别</text></g><g transform="translate(9489,0)"><g transform="translate(120,0)"><g transform="translate(60,715)"><g transform="translate(1140,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">特</text></g><g transform="translate(1943,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">征</text></g><g transform="translate(3024,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">类</text></g><g transform="translate(3828,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">别</text></g></g><g transform="translate(1002,-803)"><g transform="translate(1140,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">特</text></g><g transform="translate(1943,0)"><text font-family="STIXGeneral,'Arial Unicode MS',serif" stroke="none" transform="scale(50.259) matrix(1 0 0 -1 0 0)">征</text></g></g></g></g></g></svg>
按照朴素贝叶斯的求解,能够转换为计算$P(嫁|帅\ 性格很差\ 不上进)$和$P(不嫁|帅\ 性格很差\ 不上进)$,最终选择嫁与不嫁的答案。
$P(嫁|帅\ 性格很差\ 不上进)=P(嫁)\frac{P(帅|嫁)P(性格很差|嫁)P(不上进|嫁)}{P(帅\ 性格很差\ 不上进)}$
$P(不嫁|帅\ 性格很差\ 不上进)=P(不嫁)\frac{P(帅|不嫁)P(性格很差|不嫁)P(不上进|不嫁)}{P(帅\ 性格很差\ 不上进)}$
分母的计算用到的是全几率公式:
因此$P(帅\ 性格很差\ 不上进) = \P(嫁)P(帅|嫁)P(性格很差|嫁)P(不上进|嫁) \+ P(不嫁)P(帅|不嫁)P(性格很差|不嫁)P(不上进|不嫁)$
由上面得出:
P(嫁)= 5/10 = 1/2
P(不嫁)= 5/10 = 1/2
P(帅|嫁) P(性格很差|嫁) P(不上进|嫁)= 4/5 1/5 1/5
P(帅|不嫁) P(性格很差|不嫁) P(不上进|不嫁) = 1/5 3/5 2/5
对于类别“嫁”的贝叶斯分子为:
P(嫁) P(帅|嫁) P(性格很差|嫁) P(不上进|嫁) = 1/2 4/5 1/5 1/5 = 2/125
对于类别“不嫁”的贝叶斯分子为:
P(不嫁) P(帅|不嫁) P(性格很差|不嫁) P(不上进|不嫁) = 1/2 1/5 3/5 2/5 = 3/125
因此最终结果为:
P(嫁|帅 性格很差 不上进) = (2/125) / (2/125 + 3/125) = 40%
P(不嫁|帅 性格很差 不上进) = (3/125) / (2/125 + 3/125) = 60%
60% > 40%,该女生选择不嫁。
小西:朴素贝叶斯就是根据先验几率与调整因子来肯定几率的,是吧!
小迪:没错,可是朴素贝叶斯的形式确不止如此。在scikit-learn中,一共有3个朴素贝叶斯的分类算法。分别是GaussianNB,MultinomialNB和BernoulliNB。
GaussianNB就是先验为高斯分布(正态分布)的朴素贝叶斯,假设每一个标签的数据都服从简单的正态分布。
其中$C_k$为Y的第k类类别。$\mu_k和\sigma_k^2$为须要从训练集估计的值。
高斯分布图像
咱们可使用用scikit-learn简单实现一下GaussianNB。
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="python" contenteditable="true" cid="n138" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">#导入包
import pandas as pd
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
from sklearn import datasets
iris=datasets.load_iris()
Xtrain, Xtest, ytrain, ytest = train_test_split(iris.data,
iris.target,
random_state=12)
clf = GaussianNB()
clf.fit(Xtrain, ytrain)
clf.predict(Xtest)
clf.predict_proba(Xtest)
accuracy_score(ytest, clf.predict(Xtest))</pre>
MultinomialNB就是先验为多项式分布的朴素贝叶斯。它假设特征是由一个简单多项式分布生成的。多项分布能够描述各类类型样本出现次数的几率,所以多项式朴素贝叶斯很是适合用于描述出现次数或者出现次数比例的特征。该模型经常使用于文本分类,特征表示的是次数,例如某个词语的出现次数。
多项式分布公式以下:
其中,$P(X_j=x_{jl}|Y=C_k)$是第k个类别的第j维特征的第l个取值条件几率。$m_k$是训练集中输出为第k类的样本个数。$\lambda$ 为一个大于0的常数,经常取为1,即拉普拉斯平滑。也能够取其余值。
BernoulliNB就是先验为伯努利分布的朴素贝叶斯。假设特征的先验几率为二元伯努利分布,即以下式:
此时$l$只有两种取值。$x_{jl}$只能取值0或者1。
在伯努利模型中,每一个特征的取值是布尔型的,即true和false,或者1和0。在文本分类中,就是一个特征有没有在一个文档中出现。
小西:那咱们该在什么状况下分别使用这三种朴素贝叶斯模型呢?
小迪:通常来讲,若是样本特征的分布大部分是连续值,使用GaussianNB会比较好。若是若是样本特征的分布大部分是多元离散值,使用MultinomialNB比较合适。而若是样本特征是二元离散值或者很稀疏的多元离散值,应该使用BernoulliNB。
小西:原来如此。
注:全部图片均来源于网络