文章目录
- 朴素贝叶斯
-
- 贝叶斯公式
- 判别式模型 & 生成式模型
- 朴素贝叶斯模型
- 使用贝叶斯分类器
- 代码
- 半朴素贝叶斯模型
-
- 超父-SPODE(Super-Parent ODE)
- TAN(Tree Augmented Naive Bayes)
朴素贝叶斯
贝叶斯公式
? 贝叶斯分类器是基于贝叶斯公式,之前写过一篇关于贝叶斯公式的文章:
判别式模型 & 生成式模型
? 之前的几种模型都是判别式模型,而贝叶斯分类器是一种生成式模型,我自己的一个最简单的理解就是用概率的方式去考虑分类问题–万物皆概率。之前也有过一篇文章:
朴素贝叶斯模型
根据上面两个知识点,我们可以知道,贝叶斯分类器就是想用p(y∣x)=p(x,y)p(x),y∈(c1,c2...ci)p(y|x) = \frac{p(x, y)}{p(x)}, y \in (c_1, c_2 ... c_i)p(y∣x)=p(x)p(x,y)?,y∈(c1?,c2?...ci?)。根据之前的模型的概念,这个贝叶斯分类器模型的训练过程就是想让所有样本计算的p(y∣x)p(y|x)p(y∣x)与真实的yyy之间的差异,或者说损失最小。这里就定义了这个损失的概念:
R(ci∣x)=∑j=1NλijP(ci∣x)R(c_i|x)=\sum_{j=1}^N\lambda_{ij}P(c_i|x) R(ci?∣x)=j=1∑N?λij?P(ci?∣x)
- 这个公式计算的是真实分类为cjc_jcj?类别的样本被分成的cic_ici?类别的损失。对jjj进行就和就是一个误判的样本对应其他各种类别的总体风险。我们的目标就是让这个目标函数降到最小。如果某种判定准则hhh可以让每个样本上对其他每类都能损失最小化,那么自然就可以在样本集整体上损失最小化。那么我们就是要找到这样一个准则,或者说映射关系,也可以说模型:叫做最优贝叶斯分类器: h?h^*h?:
h?=argmin?y(R(c∣x))h^*=arg\min_y(R(c|x)) h?=argymin?(R(c∣x))
- 然后,把λ\lambdaλ定义成:
λij={0,ifi=j1,ifi≠j\lambda_{ij}=\begin{cases}0, if i=j \\ 1, if i\neq j\end{cases} λij?={ 0,ifi=j1,ifi??=j?
? 那么R(c∣x)=1?P(c∣x)R(c|x)=1-P(c|x)R(c∣x)=1?P(c∣x),其实也就是不等于正确那一类的所有类别的概率总和。
? 那么,h?h^*h?就可以转换成:
h?=argmax?yP(c∣x)h^*=arg\max_yP(c|x) h?=argymax?P(c∣x)
? 从求最小就变成了求最大,这个分类器必须使得后验概率P(c∣x)P(c|x)P(c∣x)在每个样本上最大。
-
根据贝叶斯公式:P(c∣x)=P(x,c)p(x)=P(c)P(c∣x)P(x)P(c|x)=\frac{P(x,c)}{p(x)}=\frac{P(c)P(c|x)}{P(x)}P(c∣x)=p(x)P(x,c)?=P(x)P(c)P(c∣x)?。从这个公式中看,P(c)P(c)P(c)是每种类别的概率,这个东西的话,也成为先验概率,样本集固定了,这个东西就是可以通过样本集中的类别概率来统计的(大数定律),可以用ci类别的样本数/样本集个数c_i类别的样本数/样本集个数ci?类别的样本数/样本集个数。同样,P(x)P(x)P(x)就是样本xxx出现的概率。
-
那么,分类器在求解P(c∣x)P(c|x)P(c∣x)的上最大,可以转变为分类器模型让P(x∣c)P(x|c)P(x∣c)上最大。这里做这个转换,我的理解是这样的:对于新的样本,计算就是计算P(c∣x)P(c|x)P(c∣x),也就是预测新样本的分类是ccc的概率。而这个概率可以通过贝叶斯公式来计算,其中最麻烦的就是P(x∣c)P(x|c)P(x∣c),而求解这个东西的概率可以再拆分成按照属性来计算:P(x∣c)=∏i=1dp(xi∣c)P(x|c) = \prod_{i=1}^d{p(x_i|c)}P(x∣c)=∏i=1d?p(xi?∣c),也就是根据每种属性在样本集中的概率来计算。最终把这些概率连乘。而P(c∣x)=P(x,c)p(x)=P(c)P(x)∏i=1dp(xi∣c)P(c|x)=\frac{P(x,c)}{p(x)}=\frac{P(c)}{P(x)}\prod_{i=1}^d{p(x_i|c)}P(c∣x)=p(x)P(x,c)?=P(x)P(c)?∏i=1d?p(xi?∣c)。
-
当然,第四步中的公式是基于每个属性都是独立这一前提才成立的。后面还会提到不成立的情况。
-
如果是基于所有样本都是独立采样这一前提的话,那么P(x)P(x)P(x)这个对于所有的样本都是相同的,可以忽略,那么第四步中的公式就可以变成:
P(c)∏i=1dp(xi∣c)P(c)\prod_{i=1}^d{p(x_i|c)} P(c)i=1∏d?p(xi?∣c)
也就是贝叶斯分类器的基本形式。
使用贝叶斯分类器
? 贝叶斯分类器作为一种生成模型的分类器,是计算每种类别的概率,哪个最大就确定是那种类别。配合第二点和第四点来理解这句话,借用《机器学习》书中的例子:
上面的是训练集,假设来了一个新的样本:
-
对于这样的一个样本,我们就是要去求解他的P(c∣xi)P(c|x_i)P(c∣xi?),那么,对于类别C∈(好瓜,不是好瓜)C \in (好瓜,不是好瓜)C∈(好瓜,不是好瓜)只有两个类别,是一个二分类问题。通过上面提到的模型,实际上是分别求解新样本为好瓜情况下的p(c)p(c)p(c)、p(x)p(x)p(x)、p(x∣c)p(x|c)p(x∣c)这三个值,然后得到是好瓜的概率,然后再计算不是好瓜情况下的p(c)p(c)p(c)、p(x)p(x)p(x)、p(x∣c)p(x|c)p(x∣c)这三个值,然后得到是不是好瓜的概率。根据上一章节中,我们的规律是要最大化这个概率的,那么我们就是要选概率大的,所以计算出来的类别中,哪个概率大,这个样本的分类就是哪个。
-
先看下p(c)p(c)p(c),这个数是样本集定了就定了。就是某个类别占样本集中的比例;那么,p(c0)=好瓜数总数=817=0.471p(c_0) = \frac{好瓜数}{总数}= \frac{8}{17} = 0.471p(c0?)=总数好瓜数?=178?=0.471;p(c1)=不是好瓜数总数=917=0.529p(c_1) = \frac{不是好瓜数}{总数}= \frac{9}{17} = 0.529p(c1?)=总数不是好瓜数?=179?=0.529.
-
然后就是计算每个属性在样本集中概率了,概率比较好算,就是样本中类别为cic_ici?的,每种属性的概率(公式1):
P(xi∣c)=∣Dc,xi∣DcP(x_i|c)=\frac{|D_{c,x_i}|}{D_c} P(xi?∣c)=Dc?∣Dc,xi??∣?举个栗子:
- 这里还有几个连续属性的没有计算,这些连续属性的话,一般假定服从正太分布:
这里还需要先针对样本集计算连续值的均值μc,i\mu_{c,i}μc,i?和方差σc,i\sigma_{c,i}σc,i?。然后再代入xix_ixi?进行计算:
-
概率出来之后,然后把好瓜的相关概率进行相乘,计算等于0.038。而不是好瓜的概率计算等于6.8×10?56.8 × 10^{-5}6.8×10?5。所以这个样本的类别会被判定为好瓜,然后这里把新样本纳入到样本集中,进行持续学习。
-
上面的概率计算有一个问题,可以看到概率的连乘之后是一个很小的数了,如果再多几个属性,可能都会趋向于0,而在计算机中也会导致精度不够,最后都等于0,所以会在之前的连乘前加上logloglog运算:
log(p(x∣c))=log(∏i=1dp(xi∣c))=∑i=1dlog(p(xi∣c))log(p(x|c)) = log(\prod_{i=1}^d{p(x_i|c)})=\sum_{i=1}^d{log({p(x_i|c)})} log(p(x∣c))=log(i=1∏d?p(xi?∣c))=i=1∑d?log(p(xi?∣c)) -
平滑与修正。
这里还存在一个问题,如果使用第三步中的公式中分子为0,也就是说在样本集中如果某个属性不存在。那么不管如何计算都会等于0。所以需要进行一下修改(公式2):
P^(xi∣c)=Dc,xi+1∣Dc∣+Ni\hat{P}{(x_i|c)} = \frac{D_{c,x_i}+1}{|D_c|+N_i} P^(xi?∣c)=∣Dc?∣+Ni?Dc,xi??+1?
这里面的NiN_iNi?就是第iii个属性可能的取值数目。
代码
? 训练代码就是根据上面的公式计算各个属性对应的各个类别的概率,形成向量。
def trainNB0(trainMatrix,trainCategory):numTrainDocs = len(trainMatrix)numWords = len(trainMatrix[0])pAbusive = sum(trainCategory)/float(numTrainDocs)p0Num = ones(numWords); p1Num = ones(numWords) #change to ones() p0Denom = 2.0; p1Denom = 2.0 #change to 2.0for i in range(numTrainDocs):if trainCategory[i] == 1:p1Num += trainMatrix[i]p1Denom += sum(trainMatrix[i])else:p0Num += trainMatrix[i]p0Denom += sum(trainMatrix[i])p1Vect = log(p1Num/p1Denom) #change to log()p0Vect = log(p0Num/p0Denom) #change to log()return p0Vect,p1Vect,pAbusive
? 判别的话就是根据这些向量直接进行概率计算。
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise multp0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)if p1 > p0:return 1else: return 0
半朴素贝叶斯模型
? 朴素贝叶斯的朴素之处就在于假设所有的属性都是相互独立的,所以公式P(x∣c)=∏i=1dp(xi∣c)P(x|c) = \prod_{i=1}^d{p(x_i|c)}P(x∣c)=∏i=1d?p(xi?∣c)才成立。但显然很多情况下,这个假设是不成立的。那么把样本间的属性分量的相互依赖关系引入贝叶斯公式中,就形成了一些其他半朴素贝叶斯模型。
? 如果属性之间有依赖关系的话,需要将上面的公式做一个改造:
P(c)∏i=1dp(xi∣c,pai)P(c)\prod_{i=1}^d{p(x_i|c,pa_i)} P(c)i=1∏d?p(xi?∣c,pai?)
? 其中的paipa_ipai?是指属性xix_ixi?所依赖的属性。然后根据上面的公式2来解释这个公式就是样本集中样本为ccc,依赖papapa属性的属性的个数。
? 而这些相互依赖关系,最简单也是最常用的一种就是“独依赖估计”策略。所谓的“独依赖”就是假设每个属性在类别之外最多仅依赖于一个其他的属性。根据不同的依赖方法,可以形成不同的独依赖模型。
超父-SPODE(Super-Parent ODE)
? 选择一个属性作为其他属性的依赖属性,这里使用交叉验证来挑其中某个属性来作为其他的依赖属性。需要注意一下的是,图中的边的含义按照箭头方向是指属性x1x_1x1?决定x2x_2x2?,或者说x2x_2x2?依赖于x1x_1x1?:
TAN(Tree Augmented Naive Bayes)
? TAN是基于最小生成树算法来生成:
-
通过某种策略计算属性与属性之间权重函数I(xi,xj∣y)I(x_i,x_j|y)I(xi?,xj?∣y)。
-
以属性为节点构建完全图,节点与节点之间的权重就是第一步中的权重函数。
-
应用最小生成树算法(
),在这个完全图上生成一份最小生成树。
-
加入类别节点yyy,增加从yyy到每个属性节点的有向边。