基于C++的朴素贝叶斯分类器

基于C++的朴素贝叶斯分类器

github链接
使用c++编写的朴素贝叶斯分类器,其中似然中的离散分量,以及先验概率使用拉普拉斯平滑,连续分量为正态分布。

警告,此代码仅为初学学习之用,请勿用作任何工程项目!

一、跑起来

方式一

使用vscode+cmake插件或者Clion打开目录。然后直接编译运行。

方式二

1、确保安装cmake环境,没有请先装cmake。
2、在工程目录下键入:

mkdir build
cd build
cmake ..
make

3、运行build目录下的程序Bayers_classifier程序

二、用起来

1、建立模型

Simple_Bayes_Classifier::Info info;
/**
    struct Info {
        int sample_num; // 样例数量
        std::vector<int> header; // 样例格式,
                                 // 如当前分量为离散值则为样例可能取值的数量,
                                 // 如为连续值则填0,
                                 // 例如,现有样例格式为这样 :
                                 //           x0 属于 {"东","南","西","北"}
                                 //           x1 属于 {"左","右"}
                                 //           x2 属于 {x|0<x<100} 为连续值
                                 // 则 header={4, 2, 0}
                                                           
        int class_num; // 分类数量
        int sample_size; // 样例分量维度大小
    } 
 */
Simple_Bayes_Classifier model(info);

2、读取文件,训练模型

model.train("data/1.txt"); // 文件格式为:每行一个样例,每个样例n个分量用空格隔开,最后为该样例所属分类

示例文件格式:

3、开始分类, 构造出一个待分类的样例,然后分类结果赋值到样例的belong_to字段

Sample s;
s.add_parameter(x); s.add_parameter(y);
model.classify(s);
std::cout << s.belong_to << std::endl;

三、学起来

贝叶斯分类器的基石为Bayes公式:

P ( A i ∣ B ) = P ( B ∣ A i ) P ( A i ) ∑ j = 1 n P ( B ∣ A j ) P ( A j ) P(A_i|B)=\frac{P(B|A_i)P(A_i)}{\sum_{j=1}^nP(B|A_j)P(A_j)} P(AiB)=j=1nP(BAj)P(Aj)P(BAi)P(Ai)

若现在存在样例的向量为 x \boldsymbol{x} x,而其所属分类为 c c c的概率为:

P ( c ∣ x ) = p ( c ) p ( x ∣ c ) p ( x ) P(c|\boldsymbol{x})=\frac{p(c)p(\boldsymbol{x}|c)}{p(\boldsymbol{x})} P(cx)=p(x)p(c)p(xc)

其中,我们把 p ( c ) p(c) p(c)称为先验概率(prior),而 p ( x ∣ c ) p(\boldsymbol{x}|c) p(xc)则为似然(likelihood)而 p ( x ) p(\boldsymbol{x}) p(x)称为证据(evidence)。当分类器工作时,遵循 h ( x ) h(\boldsymbol{x}) h(x),我们需要比较 n n n种分类,选择概率最大的分类。
h ( x ) = a r g m a x c ∈ Y P ( c ∣ x ) h(\boldsymbol{x})=argmax_{c\in Y}P(c|\boldsymbol{x}) h(x)=argmaxcYP(cx)

P ( c ∣ x ) ∝ p ( c ) p ( x ∣ c ) P(c|\boldsymbol{x}) \propto p(c)p(\boldsymbol{x}|c) P(cx)p(c)p(xc)

所以我们可以忽略证据,针对每个待分类的样例,对每种分类计算先验概率和似然即可。

先验概率 p ( c ) p(c) p(c)一般直接进行数量统计,即:
p ( c ) = ∣ D c ∣ ∣ D ∣ p(c)=\frac{|D_c|}{|D|} p(c)=DDc

其中 D c D_c Dc为训练集中。所属类别 c c c的样例集,而 ∣ D ∣ |D| D为全体训练集。

而计算较为困难的是似然 p ( x ∣ c ) p(\boldsymbol{x}|c) p(xc),在朴素贝叶斯中,我们认为向量 x \boldsymbol{x} x的所有分量的取值是独立的,此时有:
p ( x ∣ c ) = ∏ i = 0 n p ( x i ∣ c ) p(\boldsymbol{x}|c)=\prod_{i=0}^np(x_i|c) p(xc)=i=0np(xic)

此时即可进行运算,这里如果 x i x_i xi为离散值,则可以直接进行统计:

p ( x i ∣ c ) = ∣ D i , c ∣ ∣ D c ∣ p(x_i|c)=\frac{|D_{i,c}|}{|D_c|} p(xic)=DcDi,c

其中 D i , c D_{i,c} Di,c是训练集中满足:所属类别为 c c c i i i分量为 x i x_i xi的集合。

而如果 x i x_i xi为连续值,则这里可以将其看成正态分布:

p ( x i ∣ c ) = 1 2 π σ i , c e − ( x i − μ i , c ) 2 2 σ i , c 2 p(x_i|c)=\frac{1}{\sqrt{2\pi}\sigma_{i,c}}e^{-\frac{(x_i-\mu_{i,c} )^2}{2\sigma_{i,c}^2}} p(xic)=2π σi,c1e2σi,c2(xiμi,c)2

其中 σ i , c 2 , μ i , c \sigma_{i,c}^2,\mu_{i,c} σi,c2,μi,c分别为所属类别为 c c c的训练集的 i i i分量的方差和均值。

至此我们解决了朴素贝叶斯分类器。

在有些时候,向量 x \boldsymbol{x} x的分量不是独立的,一种常见的情况是所有分量满足多维正态分布 N ( μ , Σ ) N(\mu, \Sigma) N(μ,Σ)。为了清晰设置 e x p ( x ) = e x exp(x)=e^x exp(x)=ex

p ( x ) = 1 ( 2 π ) d 2 ∣ Σ ∣ 1 2 e x p ( − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) ) p(\boldsymbol{x})=\frac{1}{(2\pi)^{\frac{d}{2}}|\Sigma|^{\frac{1}{2}}}exp\left ( -\frac{1}{2} (\boldsymbol{x}-\boldsymbol{\mu} )^T\Sigma^{-1}(\boldsymbol{x}-\boldsymbol{\mu} ) \right ) p(x)=(2π)2d∣Σ211exp(21(xμ)TΣ1(xμ))

其中

μ i = E [ x i ] \mu_i=E[x_i] μi=E[xi]
Σ i , j = E [ ( x i − μ i ) ( x j − μ j ) ] \Sigma_{i,j}=E[(x_i-\mu_i)(x_j-\mu_j)] Σi,j=E[(xiμi)(xjμj)]

这里我们将结果取对数

g i ( x ) = l n ( p ( x ∣ c i ) p ( c i ) ) = l n p ( x ∣ c i ) + l n p ( c i ) g_i(\boldsymbol{x})=ln(p(\boldsymbol{x}|c_i)p(c_i))=lnp(\boldsymbol{x}|c_i)+lnp(c_i) gi(x)=ln(p(xci)p(ci))=lnp(xci)+lnp(ci)

g i ( x ) = − 1 2 ( x − μ ) T Σ − 1 ( x − μ ) − d 2 l n 2 π − 1 2 l n ∣ Σ i ∣ + l n p ( c i ) g_i(\boldsymbol{x})=-\frac{1}{2} (\boldsymbol{x}-\boldsymbol{\mu} )^T\Sigma^{-1}(\boldsymbol{x}-\boldsymbol{\mu} )-\frac{d}{2}ln2\pi -\frac{1}{2}ln|\Sigma_i|+lnp(c_i) gi(x)=21(xμ)TΣ1(xμ)2dln2π21lnΣi+lnp(ci)

此时有决策函数:

g i , j ( x ) = g i ( x ) − g j ( x ) g_{i,j}(x)=g_i(x)-g_j(x) gi,j(x)=gi(x)gj(x)

g i , j ( x ) = 0 g_{i,j}(x)=0 gi,j(x)=0为决策界,当 g i , j ( x ) ≥ 0 g_{i,j}(x)\ge 0 gi,j(x)0归为 i i i类,否则归为 j j j。至此,我们讨论了贝叶斯分类器中,样例各分量满足多维正态分布的情况。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值