朴素贝叶斯分类

来源:互联网 发布:外网访问centos 编辑:程序博客网 时间:2024/05/18 06:46

我们开始讨论OpenCV的机器学习库,首先学习一个监督学习分类器NormalBayesClassifier,叫做正态贝叶斯分类器或者朴素贝叶斯分类器。它假设所有的特征之间相互独立,虽然这种假设不太符合实际,但是在实际运用中,发现这种假设得到的结果却也能够得到惊人的性能。朴素贝叶斯分类器不能处理回归问题,但是它能够有效的处理多类问题,而不仅仅是两类问题。朴素贝叶斯分类器是当前快速发展的贝叶斯网络的最简单情况。贝叶斯网络是因果模型。
朴素贝叶斯学习模型比较简单,我们照很多张照片,计算这些照片的特征,计算每个物体的训练集中某个特征出现的比例。在实际计算中,我们不允许0概率,因为这样会出去某个存在的物体;因此,0概率被赋予一个很小的值。一般情况下,如果没有很多的数据,简单的模型(朴素贝叶斯)会比很多复杂模型获得很好的性能,因为复杂模型使用了太多的假设,以致产生欠拟合。

朴素贝叶斯分类器的训练方法如下:

    virtual bool train( const CvMat* trainData, const CvMat* responses,        const CvMat* varIdx = 0, const CvMat* sampleIdx=0, bool update=false );

只支持CV_ROW_SAMPLE类型的数据。即数据的每一个行就是一个特征。参数varIdx 和sampleIdx可选,他们允许你标记你想使用哪些特征和数据样本。很多情况下会使用所有数据样本。因而赋值为NULL,这两个向量中0意味着跳过。最后,当update变量为true的时候。使用新数据样本更新模型,update为false的时候,从零开始训练模型。
朴素贝叶斯分类器的预测方法计算了他的输入向量的最大可能性的类别,一个或者多个数据按行排列在输入矩阵中。如果只有一个输入向量,则只返回一个浮点数,results将被设为NULL。

    virtual float predict( const CvMat* samples, CV_OUT CvMat* results=0 ) const;

关于OpenCV朴素贝叶斯有一篇文章写得不错。链接如下,可以一起学习。
http://blog.csdn.net/zhaocj/article/details/50615049

OpenCV实现的贝叶斯分类器不是我们所熟悉的朴素贝叶斯分类器(Naïve Bayes Classifier),而是正态贝叶斯分类器(Normal Bayes Classifier),两者虽然英文名称很相似,但它们是不同的贝叶斯分类器。前者在使用上有一个限制条件,那就是变量的特征之间要相互独立,而后者没有这个苛刻的条件,因此它的适用范围更广。

#include "opencv2/core/core.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include "opencv2/ml/ml.hpp"#include <iostream>using namespace cv;using namespace std;int main( int argc, char** argv ){       float trainingData[8][3] = { {6, 180, 12}, {5.92, 190, 11}, {5.58, 170, 12}, {5.92, 165, 10},                                {5, 100, 6}, {5.5, 150, 8},{5.42, 130, 7}, {5.75, 150, 9}};    Mat trainingDataMat(8, 3, CV_32FC1, trainingData);     float responses[8] = {'M', 'M', 'M', 'M', 'F', 'F', 'F', 'F'};    Mat responsesMat(8, 1, CV_32FC1, responses);    CvNormalBayesClassifier nbc;    nbc.train(trainingDataMat, responsesMat);     float myData[3] = {6, 130, 8};    Mat myDataMat(1, 3, CV_32FC1, myData);    float r = nbc.predict( myDataMat );    cout<<endl<<"result:  "<<(char)r<<endl;    return 0; }

得到的结果为:
result: M

0 0