机器学习(周志华) 第七章贝叶斯分类器

本文介绍了贝叶斯决策论的基本概念,如后验概率的应用、期望损失函数、贝叶斯最优分类器及其计算,重点讲解了朴素贝叶斯和半朴素贝叶斯,以及贝叶斯网的结构、学习和推断。最后提到了EM算法在处理缺失数据中的关键作用。
摘要由CSDN通过智能技术生成

关于周志华老师的《机器学习》这本书的学习笔记
记录学习过程
本博客记录Chapter7

1 贝叶斯决策论

假设有 N N N种可能的类别标记,即 Y = { c 1 , c 2 , … , c N } Y=\{c_1,c_2,…,c_N\} Y={c1,c2,,cN} λ i j \lambda_{ij} λij是将一个真实标记为 c j c_j cj的样本误分类到 c i c_i ci的损失。基于后验概率 P ( c i ∣ x ) P(c_i|\bold x) P(cix)可获得将样本 x \bold x x误分类到 c i c_i ci所产生的期望损失(expected loss),即在样本 x \bold x x上的“条件风险”(conditional risk)( P ( c j ∣ x ) P(c_j|\bold x) P(cjx):表示样本 x \bold x x c j c_j cj的概率):
R ( c i ∣ x ) = ∑ j = 1 N λ i j P ( c j ∣ x ) R(c_i|\bold x)=\sum_{j=1}^N\lambda_{ij}P(c_j|\bold x) R(cix)=j=1NλijP(cjx)
我们的任务是寻找一个判别准则 h : χ ↦ Y h:\chi \mapsto Y h:χY最小化总体风险
R ( h ) = E X [ R ( h ( x ) ∣ x ) ] R(h)=E_X[R(h(\bold x)|\bold x)] R(h)=EX[R(h(x)x)]
显然,对于每一个样本 x \bold x x,若 h h h能最小化条件风险 R ( h ( x ) ∣ x ) R(h(\bold x)|\bold x) R(h(x)x),则总体风险 R ( h ) R(h) R(h)就能最小化。这体现了贝叶斯判定准则(Bayes decision rule):为最小化总体风险,只需要在每个样本上选择哪个能使条件风险 R ( c ∣ x ) R(c|\bold x) R(cx)最小的类别标记:
h ∗ ( x ) = arg ⁡ min ⁡ c ∈ Y   R ( c ∣ x ) h^*(\bold x) = \mathop{\arg\min}_{c \in Y}\space R(c|\bold x) h(x)=argmincY R(cx)
此时, h ∗ h^* h被称为贝叶斯最优分类器(Bayes optimal classifier),与之对应的总体风险 R ( h ∗ ) R(h^*) R(h)对应贝叶斯风险(Bayes risk) 1 − R ( h ∗ ) 1-R(h^*) 1R(h)反映了分类器所能达到的最好性能

+++

若期望损失 λ i j \lambda_{ij} λij符合:
λ i j = { 0 ,     i f    i = j 1 ,     o t h e r w i s e \lambda_{ij}=\begin{cases} 0,\space\space\space if \space\space i=j\\ 1,\space\space\space otherwise \end{cases} λij={0,   if  i=j1,   otherwise
此时条件风险 R ( c ∣ x ) = 1 − P ( c ∣ x ) R(c|\bold x)=1-P(c|\bold x) R(cx)=1P(cx)

于是,最小化分类错误率的贝叶斯最优分类器:
h ∗ ( x ) = arg ⁡ min ⁡ c ∈ Y   P ( c ∣ x ) h^*(\bold x)=\mathop{\arg\min}_{c\in Y}\space P(c|\bold x) h(x)=argmincY P(cx)
选择后验概率 P ( c ∣ x ) P(c|\bold x) P(cx)最大的类别标记

+++

不难看出,欲使用贝叶斯判定准则来最小化决策风险,首先要获得后验概率 P ( c ∣ x ) P(c|x) P(cx)。 然而,在现实任务中这通常难以直接获得。从这个角度来看,机器学习所要实现的是基于有限的训练样本集尽可能准确地估计出后验概率 P ( c ∣ x ) P(c| x) P(cx)。大体来说,主要有两种策略:

  • 给定 x x x,可通过直接建模 P ( c ∣ x ) P(c| x) P(cx)来预测 c c c,这样得到的是 “判别式模型”(discriminativemodels)
  • 也可先对联合概率分布 P ( x , c ) P(x,c) P(x,c)建模,然后再由此获得 P ( c ∣ x ) P(c | x) P(cx),这样得到的是 “生成式模型’(generative models)

显然,前面介绍的决策树、BP神经网络、支持向量机等,都可归入判别式模型的范畴。对生成式模型来说,必然考虑
P ( c ∣ x ) = P ( x , c ) P ( x ) = P ( x ∣ c ) P ( c ) P ( x ) P(c|x)=\frac{P(x,c)}{P(x)}=\frac{P(x|c)P(c)}{P(x)} P(cx)=P(x)P(x,c)=P(x)P(xc)P(c)
其中, P ( c ) P(c) P(c)是先验(prior)概率, P ( x ∣ c ) P(x|c) P(xc)是样本 x x x对于类标记 c c c的类条件概率,或称为似然(likelihood); P ( x ) P(x) P(x)是用于归一化的证据因子(evidence)。对于给定样本,证据因子和类标记无关,因此估计 P ( c ∣ x ) P(c|x) P(cx)的问题就转化为如何基于训练数据 D D D估计先验 P ( c ) P(c) P(c)和似然 P ( x ∣ c ) P(x|c) P(xc) 根据大数定理, P ( c ) P(c) P(c)可以用各类样本出现的频率来进行估计;对于类条件概率 P ( x ∣ c ) P(x|c) P(xc)来说,由于其涉及关于 x x x所有属性的联合概率,直接根据样本出现频率来估计会遭到严重困难。

2 极大似然估计

假设 P ( x ∣ c ) P(x|c) P(xc)具有确定的形式并且被参数 θ c \theta_c θc唯一确定,则我们的任务就是利用训练集 D D D估计参数 θ c \theta_c θc

事实上,概率模型训练过程就是参数估计(parameter estimation)。对于参数训练过程,有频率学主义学派和贝叶斯学派。前者认为参数虽然未知,但是是客观存在的固定值,可以优化似然函数来确定参数;后者认为参数是未观察到的随机变量,其本身可以有分布,因此可以假定参数服从一个先验分布,然后基于观测到的数据来计算参数的后验分布。

这一节我们采用频率主义学派的极大似然估计(MLE)方法
L L ( θ c ) = log ⁡ P ( D c ∣ θ c ) = ∑ x ∈ D c log ⁡ P ( x ∣ θ c ) LL(\theta_c)=\log P(D_c|\theta_c)=\sum_{x\in D_c}\log P(x|\theta_c) LL(θc)=logP(Dcθc)=xDclogP(xθc)
此时参数 θ c \theta_c θc的极大似然估计为 θ c ^ \hat {\theta_c} θc^:
θ ^ c = arg ⁡ max ⁡ θ c   L L ( θ c ) \hat \theta_c = \mathop{\arg \max}_{\theta_c}\space LL(\theta_c) θ^c=argmaxθc LL(θc)
需注意的是,这种参数化的方法虽能使类条件概率估计变得相对简单,但估计结果的准确性严重依赖于所假设的概率分布形式是否符合潜在的真实数据分布。在现实应用中,欲做出能较好地接近潜在真实分布的假设,往往需在一定程度上利用关于应用任务本身的经验知识,否则若仅凭“猜测”来假设概率分布形式,很可能产生误导性的结果。

3 朴素贝叶斯分类器

朴素贝叶斯分类器(naive Bayes classifier)采用了 “属性条件独立性假设”,即假设对已知的类别,所有的属性相互独立。因此,后验概率可以写为:
P ( c ∣ x ) = P ( x ∣ c ) P ( c ) P ( x ) = P ( c ) P ( x ) ∏ i = 1 d P ( x i ∣ c ) P(c|x)=\frac{P(x|c)P(c)}{P(x)}=\frac{P(c)}{P(x)}\prod_{i=1}^dP(x_i|c) P(cx)=P(x)P(xc)P(c)=P(x)P(c)i=1dP(xic)
其中, d d d为属性数目,即 x x x的维数。

由于对于所有类别, P ( x ) P(x) P(x)相同,因此贝叶斯判定准则为:
h n b ( x ) = arg ⁡ max ⁡ c ∈ Y   P ( c ) ∏ i = 1 d P ( x i ∣ c ) h_{nb}(x)=\mathop{\arg\max}_{c\in Y} \space P(c)\prod_{i=1}^dP(x_i|c) hnb(x)=argmaxcY P(c)i=1dP(xic)
朴素贝叶斯的训练过程就是基于训练集 D D D来估计类先验概率 P ( c ) P(c) P(c),并为每个属性估计条件概率 P ( x i ∣ c ) P(x_i|c) P(xic)。其中
P ( c ) = ∣ D C ∣ ∣ D ∣ P ( x i ∣ c ) = ∣ D c , x i ∣ ∣ D c ∣ P(c)=\frac{|D_C|}{|D|}\\ P(x_i|c)=\frac{|D_{c,x_i|}}{|D_c|} P(c)=DDCP(xic)=DcDc,xi
对连续属性可以考虑概率密度函数,假定 P ( x i ∣ c ) ∼ N ( μ c , i , σ c , i 2 ) P(x_i|c)\thicksim N(\mu_{c,i},\sigma_{c,i}^2) P(xic)N(μc,i,σc,i2),其中 μ c , i \mu_{c,i} μc,i σ c , i 2 \sigma_{c,i}^2 σc,i2分别是第 c c c类样本在第 i i i个属性上取值的均值和方差,有:
p ( x i ∣ c ) = 1 2 π σ c , i e − ( x i − μ c , i ) 2 2 σ c , i 2 p(x_i|c)=\frac{1}{\sqrt{2\pi}\sigma_{c,i}}e^{-\frac{(x_i-\mu_{c,i})^2}{2\sigma_{c,i}^2}} p(xic)=2π σc,i1e2σc,i2(xiμc,i)2
为了避免其他属性携带的信息被训练集中未出现的属性值“抹去”,在估计概率值的时候通常要进行平滑,我们采用拉普拉斯修正。即令 N N N表示训练集 D D D种可能出现的类别数;令 N i N_i Ni表示第 i i i个属性可能的取值数,则:
P ^ ( c ) = ∣ D C ∣ + 1 ∣ D ∣ + N P ^ ( x i ∣ c ) = ∣ D c , x i ∣ + 1 ∣ D c ∣ + N i \hat P(c)=\frac{|D_C|+1}{|D|+N}\\ \hat P(x_i|c)=\frac{|D_{c,x_i|+1}}{|D_c|+N_i} P^(c)=D+NDC+1P^(xic)=Dc+NiDc,xi+1
在现实任务中朴素贝叶斯分类器有多种使用方式。例如:

  • 若任务对预测速度要求较高,则对给定训练集,可将朴素贝叶斯分类器涉及的所有概率估值事。先计算好存储起来,这样在进行预测时只需“查表”即可进行判别
  • 若任务数据更替频繁,则可采用“懒惰学习”(lazy learning) 方式,先不进行任何训练,待收到预测请求时再根据当前数据集进行概率估值
  • 若数据不断增加,则可在现有估值基础上,仅对新增样本的属性值所涉及的概率估值进行计数修正即可实现增量学习

4 半朴素贝叶斯分类器

朴素贝叶斯采取的属性条件独立性假设往往在现实中很难成立,因此人们尝试对属性条件独立性假设进行一定程度的放松,采用“半朴素贝叶斯分类器”。

半朴素贝叶斯分类器的基本思想:适当考虑一部分属性间的相互依赖信息,从而既不需要进行完全联合概率计算,又不至于忽略比较强的属性依赖关系。“独依赖估计”(ODE):是半朴素贝叶斯分类器最常用的策略,即假设每个属性在类别之外最多仅依赖于一个其他属性

几种常见的方法:

  • SPOED方法(super-parent ODE)所有属性都依赖于同一个属性,称为“超父”

  • TAN方法(Tree Augmented naive Bayes):在最大带权生成树的基础上,通过计算任意两个属性之间的互信息,构建最大带权生成树

    互信息计算公式:
    I ( x i , x j ∣ y ) = ∑ x i , x j ; c ∈ Y P ( x i , x j ∣ c ) log ⁡ P ( x i , x j ∣ c ) P ( x i ∣ c ) P ( x j ∣ c ) I(x_i,x_j|y)=\sum_{x_i,x_j;c\in Y}P(x_i,x_j|c)\log \frac{P(x_i,x_j|c)}{P(x_i|c)P(x_j|c)} I(xi,xjy)=xi,xj;cYP(xi,xjc)logP(xic)P(xjc)P(xi,xjc)

  • ADOE(Averaged One-Dependent Estimator):基于集成学习机制,更为强大的独依赖分类器。ADOE尝试将每个属性作为超父来构建SPODE,将具有足够训练数据支撑的SPODE集成起来作为最终结果。

image.png

5 贝叶斯网

贝叶斯网称为“信念网”(belief network),借助有向无环图(Directed Acyclic Graph,DAG)来刻画属性之间的依赖关系,并使用条件概率表(Contional Probability Table,CPT)来描述属性的联合概率分布。

一个贝叶斯网络由结构 G G G和参数 θ \theta θ两部分构成。( B = < G , θ > B=<G,\theta> B=<G,θ>)。
G G G是一个有向无环图,每个结点对应一个属性,若两个属性有直接依赖关系,则由一条边连接起来。 θ \theta θ定量描述依赖关系,假设属性 x i x_i xi G G G中的父节点集为 π i \pi_i πi,则 θ \theta θ包含了每个属性的条件概率表 θ x i ∣ π i = P ( x i ∣ π i ) \theta_{x_i|\pi_i}=P(x_i|\pi_i) θxiπi=P(xiπi)

image.png

5.1 结构

贝叶斯网结构有效地表达了属性间的条件独立性。给定父结点集,贝叶斯网络假设每个属性与它的非后裔属性独立,于是 B = < G ; θ > B=<G;\theta> B=<G;θ>将属性 x 1 , x 2 , … , x d x_1,x_2,…,x_d x1,x2,,xd的联合概率分布定义为:
P B ( x 1 , x 2 , … , x d ) = ∏ i = 1 d P B ( x i ∣ i i ) = ∏ i = 1 d θ x i ∣ π i P_B(x_1,x_2,…,x_d)=\prod_{i=1}^dP_B(x_i|i_i)=\prod_{i=1}^d\theta_{x_i|\pi_i} PB(x1,x2,,xd)=i=1dPB(xiii)=i=1dθxiπi
贝叶斯网络中由三种典型依赖关系

image.png

  • 同父关系:给定父结点 x 1 x_1 x1的取值, x 3 x_3 x3 x 4 x_4 x4就条件独立
  • 顺序结构:给定 x x x的值, y y y z z z就条件独立
  • V型结构:也叫冲撞结构,给定 x 4 x_4 x4的取值, x 1 x_1 x1 x 2 x_2 x2必定不独立;但 x 4 x_4 x4的值如果完全位置,则 x 1 x_1 x1 x 2 x_2 x2是相互独立的。这种独立性称为“边际独立性”。

为了分析图中变量之间的条件独立性,可以使用“有向分离”:

  • 找到所有V型结构,在V型结构的两个父结点之间加上一条无向边
  • 将所有有向边改为无向边

由此产生的图叫道德图(moral graph),将父结点相连的过程称为“道德化”。(孩子的父母之间应该有牢靠的关系,不然是不道德的)

基于道德图能直观、迅速地找到变量间的条件独立性。假定道德图中有变量 x , y x,y x,y和变量集合 z = z z={z} z=z,若变量 x x x y y y能在图上被 z z z分开,即从道德图中将变量集合 z z z去除后, x x x y y y分属两个连通分支,则称变量 x x x y y y z z z有向分离。

5.2 学习

贝叶斯学习网中的首要任务就是根据训练数据集找出结构最“恰当”的贝叶斯网

采用评分函数,评估贝叶斯网和训练数据的契合程度,然后基于这个评分函数寻找结构最优的贝叶斯网是一种常用的方法。常用评分函数通常基于信息论准则,此类准则将学习问题看作一个数据压缩任务,学习的目标是找到一个能以最短编码长度描述训练数据的模型,此时编码的长度包括了描述模型自身所需的字节长度使用该模型描述数据所需的字节长度。对贝叶斯网学习而言,模型就是贝叶斯网,每个贝叶斯网描述了一个在训练数据上的概率分布,自有一套编码机制能使那些经常出现的样本有更短的编码。于是,我们应选择那个综合编码长度(包括描述网络和编码数据)最短的贝叶斯网,这就是 “最小描述长度”(Minimal Description Length,简称MDL)准则

评分函数可以写为如下(其中,|B|是贝叶斯网的参数个数, f ( θ ) f(\theta) f(θ)表示描述每个参数 θ \theta θ​所需要的编码位数),第一项是计算编码贝叶斯网的编码位数,第二项是描述概率分布 P B P_B PB对数据集 D D D的拟合程度。
s ( B ∣ D ) = f ( θ ) ∣ B ∣ − L L ( B ∣ D ) L L ( B ∣ D ) = ∑ i = 1 m log ⁡ P B ( x i ) s(B|D)=f(\theta)|B|-LL(B|D)\\ LL(B|D)=\sum_{i=1}^m\log P_B(x_i) s(BD)=f(θ)BLL(BD)LL(BD)=i=1mlogPB(xi)
f ( θ ) f(\theta) f(θ)为1,则对应AIC评分函数;若 f ( θ ) = 1 2 log ⁡ m f(\theta)=\frac{1}{2}\log m f(θ)=21logm为,则对应BIC评分函数;若 θ \theta θ为0,则对应极大似然估计。

不幸的是,从所有可能的网络结构空间搜索最优贝叶斯网结构是一个NP难问题,难以快速求解。有两种常用的策略能在有限时间内求得近似解:第一种是贪心法,例如从某个网络结构出发,每次调整一条边(增加、 删除或调整方向),直到评分函数值不再降低为止;第二种是通过给网络结构施加约束来削减搜索空间,例如将网络结构限定为树形结构等。

5.3 推断

贝叶斯网络训练好之后能用来回答“查询”,即通过一些属性变量的观测值来推测其他属性变量的取值。通过已知变量来推测待查询变量的过程称为“推断”(inference),已知变量观测值称为“证据”(evidence)。

根据贝叶斯网定义的联合概率分布来精确计算后验概率是NP难的问题,需要借助“近似推断”,降低精度要求,在有限时间内求得近似解。我们常采用吉布斯采样(Gibbs sampling)

  • Q = { Q 1 , Q 2 , … , Q n } Q=\{Q_1,Q_2,…,Q_n \} Q={Q1,Q2,,Qn}表示待查询变量, E = { E 1 , E 2 , … , E k } E=\{E_1,E_2,…,E_k\} E={E1,E2,,Ek}为证据变量,已知取值为 e = { e 1 , e 2 , … , e k } e=\{e_1,e_2,…,e_k\} e={e1,e2,,ek}。目标是计算后验概率 P ( Q = q ∣ E = e ) P(Q=q|E=e) P(Q=qE=e)

  • 吉布斯采样先随机产生一个与证据 E = e E=e E=e一致的样本 q 0 q^0 q0作为初始点,然后每步从当前样本出发产生下一个样本。在第 t t t次采样,我们先假设 q t = q t − 1 q^t=q^{t-1} qt=qt1,然后对非证据变量逐个进行采样改变其取值,采样概率根据贝叶斯网B和其他变量的当前取值计算获得。假定经过 T T T次采样得到的与 q q q一致的样本共有 n q n_q nq个,近似估算出后验概率:
    P ( Q = q ∣ E = e ) = n q T P(Q=q|E=e)=\frac{n_q}{T} P(Q=qE=e)=Tnq

实质上,吉布斯采样是在贝叶斯网所有变量的联合状态空间与证据 E = e E=e E=e一致的子空间中进行 “随机漫步”(random wallk)。每一步仅依赖于前一步的状态,这是一个“马尔可夫链”(Markov chain)。在一定条件下,无论从什么初始状态开始,马尔可夫链第t步的状态分布在 t → ∞ t→\infty t时必收敛于一个平稳分布(stationary distribution); 对于吉布斯采样来说,这个分布恰好是 P ( Q ∣ E = e ) P(Q | E=e) P(QE=e)。因此,在 T T T很大时,吉布斯采样相当于根据 P ( Q ∣ E = e ) P(Q|E=e) P(QE=e)采样,从而保证了式(17)收敛于 P ( Q = q ∣ E = e ) P(Q=q|E= e) P(Q=qE=e)

image.png

6 EM算法

现实生活中,我们往往会遇到样本“不完整”的情况。未观测的变量的学名是“隐变量”,令 X X X表示已观测变量集, Z Z Z表示隐变量集, θ \theta θ表示模型参数,若对 θ \theta θ做极大似然估计,则要最大化对数似然:
L L ( θ ∣ X , Z ) = l n P ( X , Z ∣ θ ) LL(\theta|X,Z)=ln P(X,Z|\theta) LL(θX,Z)=lnP(X,Zθ)
由于Z是隐变量,因此无法直接求解,这时我们可以通过对 Z Z Z计算期望,来最大化已观测数据的对数“边际似然”:
L L ( θ ∣ X ) = l n P ( X ∣ θ ) = l n ∑ Z P ( X , Z ∣ θ ) LL(\theta|X)=lnP(X|\theta)=ln\sum_ZP(X,Z|\theta) LL(θX)=lnP(Xθ)=lnZP(X,Zθ)
EM算法是常用的估计参数隐变量的利器。其基本思想:**若 θ \theta θ已知,则可根据训练数据推断出最优隐变量的值(E步);反之,若 Z Z Z的值已知,则可方便地对 θ \theta θ做极大似然估计。**步骤如下:

  • 以初始值 θ 0 \theta^0 θ0为起点,对式(19),可以迭代执行以下步骤直到收敛:
    • 基于 θ t \theta^t θt推断隐变量 Z Z Z的期望,记 Z t Z_t Zt
    • 基于已观测变量 X X X Z Z Z对参数 θ \theta θ做极大似然估计,记为 θ t + 1 \theta^{t+1} θt+1

进一步,若我们不是取Z的期望,而是基于 θ t θ^t θt计算隐变量 Z Z Z的概率分布 P ( Z ∣ X , θ t ) P(Z| X, \theta^t) P(ZX,θt),则EM算法的两个步骤是:

  • E步(Expectation):以当前参数 θ t θ^t θt推断隐变量分布 P ( Z ∣ X , θ t ) P(Z | X,\theta^t) P(ZX,θt),并计算对数似然 L L ( θ ∣ X , Z ) LL(\theta| X,Z) LL(θX,Z)关于 Z Z Z的期望
    Q ( θ ∣ θ t ) = E Z ∣ X , θ t L L ( θ ∣ X , Z ) Q(\theta|\theta^t)=E_{Z|X,\theta^t}LL(\theta|X,Z) Q(θθt)=EZX,θtLL(θX,Z)

  • M步(Maximization):寻找参数最大化期望似然,即
    θ t + 1 = arg ⁡ max ⁡ θ   Q θ ∣ θ t \theta_{t+1}=\mathop{\arg\max}_{\theta}\space Q{\theta|\theta^t} θt+1=argmaxθ Qθθt

简要来说, EM算法使用两个步骤交替计算:第一步是期望(E)步,利用当前估计的参数值来计算对数似然的期望值;第二步是最大化(M)步,寻找能使E步产生的似然期望最大化的参数值,然后,新得到的参数值重新被用于E步,直至收敛到局部最优解。
事实上,隐变量估计问题也可通过梯度下降等优化算法求解,但由于求和的项数将随着隐变量的数目以指数级上升,会给梯度计算带来麻烦;而EM算法则可看作一种非梯度优化方法。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是朴素贝叶斯分类的伪代码: 1. 训练阶段: (1)对于每个类别 i,计算先验概率P(Y=i)。 (2)对于每个特征 j,计算在每个类别 i 下该特征的条件概率P(Xj=x|Y=i)。 2. 测试阶段: (1)对于输入样本 x,计算该样本属于每个类别 i 的条件概率P(Y=i|X=x)。 (2)将样本分到概率最大的类别中。 下面是朴素贝叶斯分类的 C++ 代码实现,其中假设特征和类别都是离散的: ``` #include <iostream> #include <vector> #include <map> #include <cmath> using namespace std; // 计算先验概率 map<int, double> cal_prior_prob(vector<int>& labels) { map<int, double> prior_prob; int total = labels.size(); for (int i = 0; i < total; i++) { int label = labels[i]; if (prior_prob.find(label) == prior_prob.end()) { prior_prob[label] = 0.0; } prior_prob[label] += 1.0; } for (auto iter = prior_prob.begin(); iter != prior_prob.end(); iter++) { iter->second /= total; } return prior_prob; } // 计算条件概率 map<int, map<int, double>> cal_cond_prob(vector<vector<int>>& features, vector<int>& labels) { map<int, map<int, double>> cond_prob; int total = labels.size(); int feature_num = features[0].size(); for (int i = 0; i < total; i++) { int label = labels[i]; if (cond_prob.find(label) == cond_prob.end()) { cond_prob[label] = map<int, double>(); } for (int j = 0; j < feature_num; j++) { int feature = features[i][j]; if (cond_prob[label].find(j) == cond_prob[label].end()) { cond_prob[label][j] = map<int, double>(); } if (cond_prob[label][j].find(feature) == cond_prob[label][j].end()) { cond_prob[label][j][feature] = 0.0; } cond_prob[label][j][feature] += 1.0; } } for (auto iter1 = cond_prob.begin(); iter1 != cond_prob.end(); iter1++) { int label = iter1->first; for (auto iter2 = iter1->second.begin(); iter2 != iter1->second.end(); iter2++) { int feature = iter2->first; int feature_total = iter2->second.size(); for (auto iter3 = iter2->second.begin(); iter3 != iter2->second.end(); iter3++) { iter3->second /= feature_total; } } } return cond_prob; } // 预测 int predict(vector<int>& feature, map<int, double>& prior_prob, map<int, map<int, double>>& cond_prob) { int label = -1; double max_prob = -1.0; for (auto iter = prior_prob.begin(); iter != prior_prob.end(); iter++) { int cur_label = iter->first; double cur_prob = log(iter->second); for (int i = 0; i < feature.size(); i++) { cur_prob += log(cond_prob[cur_label][i][feature[i]]); } if (cur_prob > max_prob) { max_prob = cur_prob; label = cur_label; } } return label; } // 测试 void test(vector<vector<int>>& features, vector<int>& labels, map<int, double>& prior_prob, map<int, map<int, double>>& cond_prob) { int total = labels.size(); int correct = 0; for (int i = 0; i < total; i++) { int predict_label = predict(features[i], prior_prob, cond_prob); if (predict_label == labels[i]) { correct++; } } cout << "Accuracy: " << (double)correct / total << endl; } int main() { // 读取数据,features存放特征,labels存放类别 vector<vector<int>> features; vector<int> labels; // 训练 map<int, double> prior_prob = cal_prior_prob(labels); map<int, map<int, double>> cond_prob = cal_cond_prob(features, labels); // 测试 test(features, labels, prior_prob, cond_prob); return 0; } ``` 注意:这里的代码只是朴素贝叶斯分类的一种实现方式,可能还有其他实现方式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值