机器学习之朴素贝叶斯分类器附C++代码

一、基本概念:

  • 先验概率(prior probability):是指根据以往经验和分析得到的概率,如全概率公式,它往往作为"由因求果"问题中的"因"出现的概率。比如,抛一枚硬币,正面朝上的概率P(A)=1/2,就是先验概率。
  • 联合概率:表示两个事件共同发生的概率。A与B的联合概率表示为 P(AB) 或者P(A,B),或者P(A∩B)。
  • 条件概率:已知事件A发生的条件下事件B发生概率,条件概率表示为P(B|A)
  • 后验概率:例如事件B1、B2、B3等都会导致事件A发生。现在事件A已经发生,求事件A发生是由B1、B2、B3那个事件引起的条件概率P(Bi|A),就是后验概率。举个在《概率论》中经常用到的例子,事件B1、B2、B3代表三个不同的工厂生产零件,事件A是生产次品的事件,P(A|Bi)是三个工厂的次品率。现在事件A发生了,判断是由那个工厂生产的这个次品P(Bi|A)

二、贝叶斯定理:

在现实生活中,我们可以很容易直接得出P(A|Bi),而P(Bi|A)则很难直接得出,但我们更关心P(Bi|A),贝叶斯定理实现了由P(A|Bi)计算P(Bi|A)的方法。

贝叶斯公式: 

          

贝叶斯算法的基础是概率推理,是在各种条件的存在不确定、仅知其出现的概率情况下,完成推理和决策任务。而朴素贝叶斯模型(Naive Bayesian Model)是基于独立假设的,即假设样本的每一个特征与其他特征都不相关。

三、贝叶斯分类器基本原理

此时贝叶斯公式写为:



训练:

1.  设样本集 ,其中。所有类别集合

2.  计算先验概率P(Ci)。

3.  计算类条件密度:

    



测试:

1.设为待分类项,而每个ai为X的一个特征属性

2.计算

3.根据贝叶斯定理求后验概率P(Ci|X),得到X属于Ci类别的后验概率;根据最大后验概率判断所属类别。

  P(C α |X)=max{P(Ci|X)} ,则测试样本属于Cα


四、举例说明

如图所示,为某电脑卖家统计的客户信息,有14个样本(X1,X2,...X14),其中每个样本有四个属性,{a1(age),a2(income),a3(student),a4(credit_rating)}。根据以上信息,如果再给出一个客户的这四种信息,如{(<30),medium,no,fair},判断他会不会买电脑。也是一个简单的二分类问题。

为了便于表示,把年龄<=30、31—40、>40用Tw(Twenty)、Th(Thirty)、F(Forty)来表示。


训练:

1. 设样本集 ,其中。所有类别集合

    

2.  计算先验概率P(C1)=5/14;P(C2)=9/14。

3.  计算类条件密度:

属性a1:P(TwC1)=3/14;P(ThC1)=0/14;P(FC1)=2/14;P(TwC2)=2/14;P(ThC2)=4/14;P(FC2)=3/14;

        P(Tw|C1)=3/5;P(Th|C1)=0/5;P(F|C1)=2/5;P(Tw|C2)=2/9;P(Th|C2)=4/9;P(F|C2)=3/9;

属性a2:P(HC1)=2/14;P(MC1)=2/14;P(LC1)=1/14;P(HC2)=2/14;P(MC2)=4/14;P(LC2)=3/14;

        P(H|C1)=2/5;P(M|C1)=2/5;P(L|C1)=1/5;P(H|C2)=2/9;P(M|C2)=4/9;P(L|C2)=3/9;

属性a3:P(NC1)=4/14;P(YC1)=1/14;P(NC2)=3/14;P(YC2)=6/14;

        P(N|C1)=4/5;P(Y|C1)=1/5;P(N|C2)=3/9;P(Y|C2)=6/9;

属性a4:P(FC1)=2/14;P(EC1)=3/14;P(FC2)=6/14;P(EC2)=3/14;

        P(F|C1)=2/5;P(E|C1)=3/5;P(F|C2)=6/9;P(E|C2)=3/9;

测试:

1.设X={(<30),medium,no,fair}为待分类项,

2.计算

P(X|C1)P(C1)=P(a1|C1)*P(a2|C1)*P(a3|C1)*P(a4|C1)P(C1)

            =P(Tw|C1)*P(M|C1)*P(N|C1)*P(F|C1)*P(C1)=(3/5)*(2/5)*(4/5)*(2/5)*(5/14)= 0.0274;

P(X|C2)P(C2)=P(a1|C2)*P(a2|C2)*P(a3|C2)*P(a4|C2)P(C2)

            =P(Tw|C2)*P(M|C2)*P(N|C2)*P(F|C2)*P(C2)=(2/9)*(4/9)*(3/9)*(6/9)*(9/14)= 0.0141;


3.根据贝叶斯定理求后验概率,得到X属于Ci类别的后验概率;根据最大后验概率判断所属类别。

  P(C α |X)=max{P(Ci|X)} ,则测试样本属于Cα

  P(X|C1)P(C1)>P(X|C2)P(C2)==>P(C1|X)>P(C2|X),

所以,此人不买电脑的概率大。

五、程序

1.这里只给出main函数部分,因为这个程序也是本人在网上下载别人的,可以验证,程序运行结果与计算结果相同

  地址:http://download.csdn.net/download/theone_jie/9464087

//朴素贝叶斯分类器程序
#include <cstdio>
#include <Windows.h>
#include "LBayesClassifier.h"

const int NUM =14;  //训练样本个数
const int Dim =4;   //训练样本的维数

int main()
{
    /*定义样本矩阵
    每一行代表一个样本
    第一列为age,第二列为income,第3列为student,第4列为credit_rating
    把个属性进行了数字化,(<=30:20)、(31-40:30)、(>40:40);
	(high:3)(medium:2)(low:1);(no:0)(yes:1);(fair:0)(excellent:1)
	*/
    int dataList[NUM*Dim] = 
	{   20,3,0,0,
		20,3,0,1,
		30,3,0,0,
		40,2,0,0,
		40,1,1,0,
		40,1,1,1,
		30,1,1,1,
		20,2,0,0,
		20,1,1,0,
		40,2,1,0,
		20,2,1,1,
		30,2,0,1,
		30,3,1,0,
		40,2,0,1}; 
    LBayesMatrix sampleMatrix(NUM, Dim, dataList);

    //定义样本的类别向量(0:不买电脑;1:买电脑)
    int classList[NUM] = {0,0,1,1,1,0,1,0,1,1,1,1,1,0};
    LBayesMatrix classVector(NUM, 1, classList);

    //定义贝叶斯原始问题
    LBayesProblem problem(sampleMatrix, classVector, BAYES_FEATURE_CONTINUS);

    //定义贝叶斯分类器, 并且训练
    LBayesClassifier classifier;
    classifier.TrainModel(problem);

    //输入新样本, 并预测新样本的类别
    LBayesMatrix newSample(1, Dim);
    newSample[0][0] = 20; 
	newSample[0][1] = 2; 
	newSample[0][2] = 0;
    newSample[0][3] = 0;
    int predictValue ; 
    classifier.Predict(newSample, &predictValue);

    printf("%d\n", predictValue);
    system("pause");
    return 0;
}


2.最后在附加了opencv自带的正态贝叶斯分类器

//opencv自带正态贝叶斯分类器(Normal Bayes Classifier)
#include "opencv2/ml/ml.hpp"

using namespace std;  
using namespace cv;  
const int NUM=14;   //训练样本的个数
const int D=4;     //维度
//14个维数为4的训练样本集
double inputArr[NUM][D] =   
					{  20,3,0,0,
					   20,3,0,1,
					   30,3,0,0,
					   40,2,0,0,
					   40,1,1,0,
					   40,1,1,1,
					   30,1,1,1,
					   20,2,0,0,
					   20,1,1,0,
					   40,2,1,0,
					   20,2,1,1,
					   30,2,0,1,
					   30,3,1,0,
					   40,2,0,1};  
  
//一个测试样本的特征向量  
double testArr[]={20,3,0,0};  
  
int main()  
{  
    Mat trainData(NUM, D, CV_32FC1);//构建训练样本的特征向量  
    for (int i=0; i<NUM; i++)  {  
        for (int j=0; j<D; j++)  {  
            trainData.at<float>(i, j) = inputArr[i][j+1];  
        }  
    }  
    Mat trainResponse=(Mat_<float>(NUM,1)<<
		0,0,1,1,1,0,1,0,1,1,1,1,1,0);//构建训练样本的类别标签  
   
    CvNormalBayesClassifier Mybayes;  
    bool trainFlag = Mybayes.train(trainData, trainResponse);//进行贝叶斯分类器训练  
    if (trainFlag)  {  
        cout<<"train over..."<<endl;  
        Mybayes.save("normalBayes.txt");  
    }  
    else  {  
        cout<<"train error..."<<endl;  
        system("pause");  
        exit(-1);  
    }  
    CvNormalBayesClassifier Tbayes;  
    Tbayes.load("normalBayes.txt");  
  
    Mat testSample(1, D, CV_32FC1);//构建测试样本  
    for (int i=0; i<D; i++)  {  
        testSample.at<float>(0, i) = testArr[i];  
    }    
    float flag = Tbayes.predict(testSample);//进行测试  
    cout<<"flag = "<<flag<<endl;  
    system("pause");  
    return 0;  
}
本人能力有限,难免有出错的地方。敬请赐教

更多资源:http://blog.csdn.net/lavorange/article/details/17841383
  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值