简介
设训练数据集由
独立同分布产生。朴素贝叶斯法通过训练数据集学习联合概率密度函数
。具体地学习学习先验概率分布
和条件概率分布
,于是根据贝叶斯公式
就可以得到联合概率密度函数
了。从上面的描述中知道贝叶斯分类器要计算条件概率和先验概率来估计联合概率分布,属于产生式模型(Generative models )。产生式模型可以根据联合分布生成条件分布,比如,可以让机器生成不同场景、物体并让物体交互(感觉用到游戏中就可以避免单调的游戏背景了)。而在对数据建模完成后,就可以对数据分类了,根据公式
-(1)
确定类别,而因为
,因此贝叶斯分类器选取联合概率最大的类别作为样本的类别。
opencv2.4.9中的贝叶斯
opencv2.4.9中实现的贝叶斯分类器是正态贝叶斯分类器(opencv中文版中也称它为朴素贝叶斯分类器),实现过程在CvNormalBayesClassifier类中。机器学习中文参考手册中有以下描述:
Normal Bayes 这个简单的分类器模型是建立在每一个类别的特征向量服从正态分布的基础上的(尽管,不必是独立的),因此,整个分布函数被假设为一个高斯分布,每一类别一组系数。当给定了训练数据,算法将会估计每一个类别的向量均值和方差矩阵,然后根据这些进行预测。
简言之,正态贝叶斯分类器假设条件概率分布函数服从正态分布,分布函数是高斯函数,通过计算样本的均值和方差,从而来计算各个类别的概率。高斯分布函数数学表达式如下:
它简单是因为它假设所有的特征之间相互独立,而这在现实中很少见(如,找到一只眼睛常常意味着另一只眼睛在附近)。 正态贝叶斯分类器不能处理回归问题,但是它能有效地处理多类问题,而不仅仅是两类问题。这个分类器是当前快速发展的贝叶斯网络(也叫概率图模型)的最简单情况。
代码分析
关于参数的较详细的说明可以参考:http://blog.csdn.net/godenlove007/article/details/8913007。
从数学的角度来解释下代码,则可以知道代码所做的事情就是计算如下等式。
train函数计算:
predict函数计算:
至于为什么会跟公式(1)有些出入,请参考《opencv2.4.9中贝叶斯分类器理解(二)》中的推导.
使用方法
这里仍然使用预测蘑菇是否有毒的测试数据,opencv中给出的例子是mushroom.cpp用的是决策树分类器,数据文件是agaricus-lepiota.data。
贝叶斯分类器的使用代码如下:
int main(int argc, char** argv)
{
CvMat *data = 0, *missing = 0, *responses = 0;
const char* base_path = argc >= 2 ? argv[1] : "C:/opencv2.4.9/sources/samples/c/agaricus-lepiota.data";
if (!mushroom_read_database(base_path, &data, &missing, &responses))
{
printf("\nUnable to load the training database\n\n");
return -1;
}
Mat X = Mat(data, true);
X.convertTo(X, CV_32FC1);
Mat Y = Mat(responses, true);
Y.convertTo(Y, CV_32FC1);
cvReleaseMat(&data);
cvReleaseMat(&missing);//missing is not used in this program.
cvReleaseMat(&responses);
int SAMPLES = X.rows;
float SPLIT = 0.8f;
Mat X_train = X(Range(0, (int)(SAMPLES*SPLIT)), Range::all());
Mat Y_train = Y(Range(0, (int)(SAMPLES*SPLIT)), Range::all());
Mat X_test = X(Range((int)(SAMPLES*SPLIT), SAMPLES), Range::all());
Mat Y_test = Y(Range((int)(SAMPLES*SPLIT), SAMPLES), Range::all());
CvNormalBayesClassifier *bayes = new CvNormalBayesClassifier;
bayes->train(X_train, Y_train, Mat(), Mat(), false);
// perform classifier testing and report results
Mat result(Y_test.rows, Y_test.cols, CV_32F);
bayes->predict(X_test, &result);
int err = 0;
for (int i = 0; i < X_test.rows; i++){
int trueRes = *(Y_test.data + i);
float predictRes = *(result.data + i);
if (fabs(trueRes - predictRes) >= FLT_EPSILON){
err++;
}
}
cout <<"error number="<< err << " " <<"precision="<< 100-err*1.f / Y_test.rows * 100 << "%\n";
system("pause");
return 0;
}
我得到的结果是:
error number=3 precision=99.8154%
(转载请注明作者和出处:http://blog.csdn.net/CHIERYU 未经允许请勿用于商业用途)