工作是這樣的, 我們希望學習到下面的事情:
A. 產生最簡單的兩個 normal distribution 分佈 training sets
B. 丟給 KNN 學習
C. 放 sample data 給 KNN, 進行預測
這裡有幾個關鍵:
如何產生 training data
// Step 0: 建立 100 組 (x,y) 資料的陣列 與 存放標準答案的陣列
int train_sample_count=100;
CvMat* trainData = cvCreateMat(train_sample_count,2,CV_32FC1);
CvMat* trainClasses = cvCreateMat( train_sample_count, 1,
CV_32FC1 );
CvRNG rng_state = cvRNG(-1); // 亂數產生器: 產生 normalization 使用
// Step 1: 第一筆資料
// 陣列 index 0 - 99 的地方, 放training set 數值
// 分佈型態 normal distribution,
// mean value=(200,200), Variance=(50,50)
CvMat trainData1;
cvGetRows( trainData, &trainData1, 0, train_sample_count/2 );
cvRandArr( &rng_state, &trainData1, CV_RAND_NORMAL,
cvScalar(200,200), cvScalar(50,50));
// Step 2: 指定第一筆資料全部屬於類別 1
CvMat trainClasses1;
cvGetRows(trainClasses, &trainClasses1, 0, train_sample_count/2 );
cvSet( &trainClasses1, cvScalar(1));
如何把 training set 丟給 KNN 物件學習?
// Step 1: 建立 KNN 物件
int K=10;
CvKNearest knn( trainData, trainClasses, 0, false, K );
如何對一個 testing sample 進行分類?
// Step 1: 進行 KNN 的預測
// a. 設定 testing sample 的值
sample.data.fl[0] = (float)j;
sample.data.fl[1] = (float)i;
// [關鍵片段]
// b. 利用 KNN 演算法取得最近的 K 個 samples. ex:[0,1,0,...,1]
// return the nearest class
float response = knn.find_nearest(&sample,K,0,0,nearests,0);
// c. KNN 預測的結果與標準答案的比較
for(k = 0, accuracy = 0; k < K; k++ ){
if( nearests->data.fl[k] == response)
accuracy++; // 計算 K 個最接近的 label, 符合標準答案的數量
}
// d. 若預測結果正確的數值超過一半, 則使用紅色/綠色表示
// 否則使用橘色表示
cvSet2D( img, i, j, response == 1 ?
(accuracy > 5 ? CV_RGB(180,0,0) : CV_RGB(180,120,0)) :
(accuracy > 5 ? CV_RGB(0,180,0) : CV_RGB(120,120,0)) );
}
現在你可以看完整的範例了. [View]
Enjoy.
by Jing.