国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

C++基于特征向量的KNN分類算法

2020-01-26 13:35:05
字體:
來源:轉載
供稿:網友

K最近鄰(k-Nearest Neighbor,KNN)分類算法,是一個理論上比較成熟的方法,也是最簡單的機器學習算法之一。該方法的思路是:如果一個樣本在特征空間中的k個最相似(即特征空間中最鄰近)的樣本中的大多數屬于某一個類別,則該樣本也屬于這個類別。KNN算法中,所選擇的鄰居都是已經正確分類的對象。該方法在定類決策上只依據最鄰近的一個或者幾個樣本的類別來決定待分樣本所屬的類別。 KNN方法雖然從原理上也依賴于極限定理,但在類別決策時,只與極少量的相鄰樣本有關。由于KNN方法主要靠周圍有限的鄰近的樣本,而不是靠判別類域的方法來確定所屬類別的,因此對于類域的交叉或重疊較多的待分樣本集來說,KNN方法較其他方法更為適合。

#include "stdafx.h"#include <iostream>#include <fstream>#include <sstream>#include <string>#include <vector>#include <set>#include <map>#include <cmath> using namespace std; //樣本特征結構體struct sample{ string type; vector<double> features;}; //讀取訓練樣本train.txt,訓練樣本格式:類型名+特征向量void readTrain(vector<sample>& train, const string& file){ ifstream fin(file.c_str()); //file是存儲希望讀寫的文件名的string對象,fin是讀的流 if(!fin) { cerr<<"Unable to open the input file: "<<file<<endl; exit(1); }  string line;  double d=0.0; while(getline(fin,line)) //fin是讀入流,getline從輸入流fin讀入一行到line { istringstream stream(line); //bind to stream to the line we read sample ts; stream>>ts.type; while(stream>>d) //read a word from line {  ts.features.push_back(d); //在trains.features的末尾添加一個值為d的元素 } train.push_back(ts); //在train的末尾添加一個值為ts的元素 } fin.close();} //讀取測試樣本test.txt,每行都是一個特征向量void readTest(vector<sample>& test, const string& file){ ifstream fin(file.c_str()); if(!fin) { cerr<<"Unable to open the input file: "<<file<<endl; exit(1); }  string line; double d=0.0; while(getline(fin,line)) { istringstream stream(line); //bind to stream to the line we read sample ts; while(stream>>d) {  ts.features.push_back(d); } test.push_back(ts); } fin.close();} //輸出結果,為每一個向量賦予一個類型,寫入result.txt中void writeResult(const vector<sample>& test, const string& file){ ofstream fout(file.c_str()); if(!fout) { cerr<<"Unable to write the input file: "<<endl; exit(1); }  for(vector<sample>::size_type i=0;i!=test.size();++i) { fout << test[i].type << '/t'; for(vector<double>::size_type j=0;j!=test[j].features.size();++j) {  fout<<test[i].features[j]<<' '; } fout<<endl; }} //KNN算法的實現void knnProcess(vector<sample>& test, const vector<sample>& train, const vector<vector<double> >& dm, unsigned int k){ for (vector<sample>::size_type i = 0; i != test.size(); ++i) { multimap<double, string> dts; //保存與測試樣本i距離最近的k個點  for (vector<double>::size_type j = 0; j != dm[i].size(); ++j) {  if (dts.size() < k) //把前面k個插入dts中  {  dts.insert(make_pair(dm[i][j], train[j].type)); //插入時會自動排序,按dts中的double排序,最小的排在最后  }  else  {  multimap<double, string>::iterator it = dts.end();  --it;   if (dm[i][j] < it->first) //把當前測試樣本i到當前訓練樣本之間的歐氏距離與dts中最小距離比較,若更小就更新dts  {   dts.erase(it);   dts.insert(make_pair(dm[i][j], train[j].type));  }  } } map<string, double> tds; string type = ""; double weight = 0.0; //下面for循環主要是求出與測試樣本i最鄰近的k個樣本點中大多數屬于的類別,即將其作為測試樣本點i的類別 for (multimap<double, string>::const_iterator cit = dts.begin(); cit != dts.end(); ++cit) {  // 不考慮權重的情況,在 k 個樣例中只要出現就加 1  // ++tds[cit->second];   // 這里是考慮距離與權重的關系,距離越大權重越小  tds[cit->second] += 1.0 / cit->first;  if (tds[cit->second] > weight)  {  weight = tds[cit->second];  type = cit->second; //保存一下類別  } } test[i].type = type; }} // 計算歐氏距離double euclideanDistance(const vector<double>& v1, const vector<double>& v2){ if(v1.size() != v2.size()) { cerr<<"Unable to get a distance! "<<endl; }  else { double distance = 0.0;  for (vector<double>::size_type i = 0; i != v1.size(); ++i) {  distance += (v1[i] - v2[i]) * (v1[i] - v2[i]); } return sqrt(distance); }} /*初始化距離矩陣,該矩陣是根據訓練樣本和測試樣本而得,矩陣的行數為測試樣本的數目,列數為訓練樣本的數目,每一行為一個測試樣本到各個訓練樣本之間的歐式距離組成的數組*/void initDistanceMatrix(vector<vector<double> >& dm, const vector<sample>& train, const vector<sample>& test){ for (vector<sample>::size_type i = 0; i != test.size(); ++i) { vector<double> vd; for (vector<sample>::size_type j = 0; j != train.size(); ++j) {  vd.push_back(euclideanDistance(test[i].features, train[j].features)); } dm.push_back(vd); }} //封裝void xfxKnn(const string& file1, const string& file2, const string& file3, int k){ vector<sample> train,test; readTrain(train, file1.c_str()); readTest(test, file2.c_str()); vector< vector<double> > dm; initDistanceMatrix(dm, train, test); knnProcess(test, train, dm, k); writeResult(test, file3.c_str());} // 測試int main(){ xfxKnn("train.txt", "test.txt", "result.txt", 5); return 0;}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 柏乡县| 江西省| 水富县| 崇仁县| 清徐县| 观塘区| 双牌县| 松江区| 鹰潭市| 岳普湖县| 额尔古纳市| 舞钢市| 赣州市| 惠东县| 申扎县| 广德县| 武川县| 长治市| 犍为县| 普宁市| 漳浦县| 迁西县| 金坛市| 海晏县| 固安县| 麦盖提县| 乌苏市| 湘潭县| 鲁山县| 台山市| 攀枝花市| 南昌市| 南宫市| 南投市| 托克逊县| 普安县| 闻喜县| 北碚区| 宣武区| 德保县| 文山县|