当前位置: 代码迷 >> 综合 >> 机器学习读书笔记:贝叶斯分类器
  详细解决方案

机器学习读书笔记:贝叶斯分类器

热度:41   发布时间:2024-02-25 06:17:48.0

文章目录

  • 朴素贝叶斯
    • 贝叶斯公式
    • 判别式模型 & 生成式模型
    • 朴素贝叶斯模型
    • 使用贝叶斯分类器
    • 代码
  • 半朴素贝叶斯模型
    • 超父-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(yx)=p(x)p(x,y)?,y(c1?,c2?...ci?)。根据之前的模型的概念,这个贝叶斯分类器模型的训练过程就是想让所有样本计算的p(y∣x)p(y|x)p(yx)与真实的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=1N?λij?P(ci?x)

  1. 这个公式计算的是真实分类为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(cx))

  1. 然后,把λ\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(cx)=1?P(cx),其实也就是不等于正确那一类的所有类别的概率总和。

? 那么,h?h^*h?就可以转换成:
h?=argmax?yP(c∣x)h^*=arg\max_yP(c|x) h?=argymax?P(cx)
? 从求最小就变成了求最大,这个分类器必须使得后验概率P(c∣x)P(c|x)P(cx)在每个样本上最大。

  1. 根据贝叶斯公式: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(cx)=p(x)P(x,c)?=P(x)P(c)P(cx)?。从这个公式中看,P(c)P(c)P(c)是每种类别的概率,这个东西的话,也成为先验概率,样本集固定了,这个东西就是可以通过样本集中的类别概率来统计的(大数定律),可以用ci类别的样本数/样本集个数c_i类别的样本数/样本集个数ci?/。同样,P(x)P(x)P(x)就是样本xxx出现的概率。

  2. 那么,分类器在求解P(c∣x)P(c|x)P(cx)的上最大,可以转变为分类器模型让P(x∣c)P(x|c)P(xc)上最大。这里做这个转换,我的理解是这样的:对于新的样本,计算就是计算P(c∣x)P(c|x)P(cx),也就是预测新样本的分类是ccc的概率。而这个概率可以通过贝叶斯公式来计算,其中最麻烦的就是P(x∣c)P(x|c)P(xc),而求解这个东西的概率可以再拆分成按照属性来计算:P(x∣c)=∏i=1dp(xi∣c)P(x|c) = \prod_{i=1}^d{p(x_i|c)}P(xc)=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(cx)=p(x)P(x,c)?=P(x)P(c)?i=1d?p(xi?c)

  3. 当然,第四步中的公式是基于每个属性都是独立这一前提才成立的。后面还会提到不成立的情况。

  4. 如果是基于所有样本都是独立采样这一前提的话,那么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=1d?p(xi?c)
    也就是贝叶斯分类器的基本形式。

使用贝叶斯分类器

? 贝叶斯分类器作为一种生成模型的分类器,是计算每种类别的概率,哪个最大就确定是那种类别。配合第二点和第四点来理解这句话,借用《机器学习》书中的例子:
在这里插入图片描述

上面的是训练集,假设来了一个新的样本:

在这里插入图片描述

  1. 对于这样的一个样本,我们就是要去求解他的P(c∣xi)P(c|x_i)P(cxi?),那么,对于类别C∈(好瓜,不是好瓜)C \in (好瓜,不是好瓜)C()只有两个类别,是一个二分类问题。通过上面提到的模型,实际上是分别求解新样本为好瓜情况下的p(c)p(c)p(c)p(x)p(x)p(x)p(x∣c)p(x|c)p(xc)这三个值,然后得到是好瓜的概率,然后再计算不是好瓜情况下的p(c)p(c)p(c)p(x)p(x)p(x)p(x∣c)p(x|c)p(xc)这三个值,然后得到是不是好瓜的概率。根据上一章节中,我们的规律是要最大化这个概率的,那么我们就是要选概率大的,所以计算出来的类别中,哪个概率大,这个样本的分类就是哪个。

  2. 先看下p(c)p(c)p(c),这个数是样本集定了就定了。就是某个类别占样本集中的比例;那么,p(c0)=好瓜数总数=817=0.471p(c_0) = \frac{好瓜数}{总数}= \frac{8}{17} = 0.471p(c0?)=?=178?=0.471p(c1)=不是好瓜数总数=917=0.529p(c_1) = \frac{不是好瓜数}{总数}= \frac{9}{17} = 0.529p(c1?)=?=179?=0.529.

  3. 然后就是计算每个属性在样本集中概率了,概率比较好算,就是样本中类别为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???

    举个栗子:

在这里插入图片描述
在这里插入图片描述

  1. 这里还有几个连续属性的没有计算,这些连续属性的话,一般假定服从正太分布:

在这里插入图片描述

这里还需要先针对样本集计算连续值的均值μc,i\mu_{c,i}μc,i?和方差σc,i\sigma_{c,i}σc,i?。然后再代入xix_ixi?进行计算:
在这里插入图片描述

  1. 概率出来之后,然后把好瓜的相关概率进行相乘,计算等于0.038。而不是好瓜的概率计算等于6.8×10?56.8 × 10^{-5}6.8×10?5。所以这个样本的类别会被判定为好瓜,然后这里把新样本纳入到样本集中,进行持续学习

  2. 上面的概率计算有一个问题,可以看到概率的连乘之后是一个很小的数了,如果再多几个属性,可能都会趋向于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(xc))=log(i=1d?p(xi?c))=i=1d?log(p(xi?c))

  3. 平滑与修正。

    这里还存在一个问题,如果使用第三步中的公式中分子为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(xc)=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=1d?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是基于最小生成树算法来生成:

  1. 通过某种策略计算属性与属性之间权重函数I(xi,xj∣y)I(x_i,x_j|y)I(xi?,xj?y)

  2. 以属性为节点构建完全图,节点与节点之间的权重就是第一步中的权重函数。

  3. 应用最小生成树算法(

    ),在这个完全图上生成一份最小生成树。

  4. 加入类别节点yyy,增加从yyy到每个属性节点的有向边。

在这里插入图片描述