OpenCV實現樸素貝葉斯分類器診斷病情
貝葉斯定理由英國數學家托馬斯.貝葉斯(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,診斷結果為: