您的位置:首页 > 运维架构

OpenCV实现朴素贝叶斯分类器诊断病情

2016-11-03 23:17 405 查看
贝叶斯定理由英国数学家托马斯.贝叶斯(Thomas Baves)在1763提出,因此得名贝叶斯定理。贝叶斯定理也称贝叶斯推理,是关于随机事件的条件概率的一则定理。

对于两个事件A和B,事件A发生则B也发生的概率记为P(B|A),事件B发生则A也发生的概率记为P(A|B),这样如果A发生B也必然发生或者B发生A也必然发生,则有P(B|A)=P(A|B)=1,这种情况是一种确定性推理。

更多的情况下,概率推理是不确定性推理,AB之间是一种不确定性概率关系,例如条件A发生时B会发生的概率计算公式为:



这种情况在现实中一般是容易推导计算出来的,或者根据先验知识是可以获取到的,例如如下两种情况:

1.条件A:一个人感冒了;条件B:这个人会发烧

2.条件A:一个人是女生;条件B:这个人会留长发

根据先验知识,条件B发生的概率是可以根据条件A推理得出的。在另一种更普遍的情况下,我们更加关心的是如果条件B发生,那么条件A发生的概率是多少?

1.条件B:一个人发烧了;条件A:这个人感冒了

2.条件B:一个人留长发;条件A:这个人是女生

这个问题称为“逆概率推理”,即已知A发生时B发生的概率,那么如果B已经发生,A发生的概率P(A|B)=?

贝叶斯公式

设有一个样本空间S,划分为B1,B2,....Bc一共c 类,或者成为c个事件,A为引发S中各个事件发生的事件,贝叶斯公式定义为:



其中P(Bi|A)称为后验概率,表示时间A发生后,各不相容的条件Bi发生的概率,它是在A的结果出现之后才能计算的,所以称为后验概率。

P(A|Bj)称为类条件概率,表示在各条件Bi存在时,事件A发生的概率。

P(Bj)称为先验概率,表示各不相容的条件Bi出现的概率,它与结果A是否出现无关,仅表示根据先验知识或者主观推断,认为总体上各个条件出现的可能性之间的差别。

贝叶斯是一位牧师,据不可靠消息,贝叶斯提出贝叶斯公式的目的是为了从统计理论上证明上帝的存在,尝试以一个科学的东西证明一个非科学的东西的科学性,这不科学。

朴素贝叶斯分类器(Naive Baves classifier)的“朴素”(Naive)之处在于,其假设了各个特征之间是独立的,简化了贝叶斯各个特征之间的相互关联,更易于推广应用。

以下代码是使用Opencv中正态贝叶斯Normal BavesClassifier 类建立的一个简单的病情诊断功能。假定以下是根据警院历来可靠数据获取的体温、咳嗽、流涕三个症状的严重程度判定的三类病情,分别是冷感冒、肺炎、热感冒。朴素贝叶斯根据这10组数据进行训练,然后输入一位病人的数据,自动进行诊断,以下是训练数据:



Opencv代码实现:

#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[10][3] = { {34, 1, 1}, {35, 2, 2}, {36, 3,3},{37,8,4},{38,9,5},
{39,10,6},{40,7,7},{41,4,8},{42,5,9},{43,6,10}};
Mat trainingDataMat(10, 3, CV_32FC1, trainingData);

float responses[10] = {1,1,1,2,2,2,3,3,3};
Mat responsesMat(10, 1, CV_32FC1, responses);

NormalBayesClassifier nbc;
nbc.train(trainingDataMat, responsesMat);

float myData[3] = {40, 8, 10}; //病人发烧、咳嗽、流涕数据
Mat myDataMat(1, 3, CV_32FC1, myData);
float r = nbc.predict( myDataMat );
int result=r;
string output;
switch(result)
{
case 1:
output="冷感冒";
break;
case 2:
output="肺炎";
break;
case 3:
output="热感冒";
break;
default:
output="健康";
break;
}
cout<<endl<<"该病人诊断为:  "<<output<<endl<<endl;
system("pause");
return 0;

}


输入病人的数据为:发烧-40、咳嗽-8、流涕-10,诊断结果为:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: