最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2018年12月26日 11:11:42   作者:長相憶兮長相憶  
這篇文章主要為大家詳細介紹了C++基于特征向量的KNN分類算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下

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循環(huán)主要是求出與測試樣本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;
}

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

相關文章

  • C++模擬實現list功能

    C++模擬實現list功能

    list的底層是一個循環(huán)雙向鏈表結構,雙向鏈表中每個元素存儲在互不相關的獨立節(jié)點中,在節(jié)點中通過指針指向其前一個元素和后一個元素,接下來通過本文給大家分享C++模擬實現list的示例代碼,需要的朋友可以參考下
    2021-08-08
  • C語言算法練習之數組求素數

    C語言算法練習之數組求素數

    這篇文章主要為大家介紹了C語言算法練習中數組求素數的實現方法,文中的示例代碼講解詳細,對我們學習C語言有一定幫助,需要的可以參考一下
    2022-09-09
  • C++淺析引用的定義與使用

    C++淺析引用的定義與使用

    引用是C++一個很重要的特性,顧名思義是某一個變量或對象的別名,對引用的操作與對其所綁定的變量或對象的操作完全等價,這篇文章主要給大家總結介紹了C++中引用的相關知識點,需要的朋友可以參考下
    2022-07-07
  • C++實現十大排序算法及排序算法常見問題

    C++實現十大排序算法及排序算法常見問題

    法是程序的靈魂,無論學習什么語言,做什么工程項目,都要考慮算法的效率實現,下面這篇文章主要給大家介紹了關于C++實現十大排序算法及排序算法常見問題的相關資料,需要的朋友可以參考下
    2021-09-09
  • C語言數組任意位置插入一個元素方法

    C語言數組任意位置插入一個元素方法

    這篇文章主要給大家分享C語言數組任意位置插入一個元素方法,
    2021-11-11
  • c++ 類函數作為模板參數實現方式詳解

    c++ 類函數作為模板參數實現方式詳解

    這篇文章主要介紹了c++ 類函數作為模板參數實現方式,在實現中加入增強邏輯,這種方式對代碼侵入性過高,而且無法控制該邏輯是否需要,如果不需要的話又得重新修改代碼實現,需要的朋友可以參考下
    2023-03-03
  • C語言中的字符(char)詳細講解

    C語言中的字符(char)詳細講解

    本篇文章主要介紹C語言中char的知識,并附有代碼實例,以便大家在學習的時候更好的理解,有需要的可以看一下
    2016-07-07
  • VsCode安裝和配置c/c++環(huán)境小白教程(圖文)

    VsCode安裝和配置c/c++環(huán)境小白教程(圖文)

    本文主要介紹了VsCode安裝和配置c/c++環(huán)境小白教程,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • C語言實現順序表的插入刪除

    C語言實現順序表的插入刪除

    這篇文章主要介紹了C語言實現順序表的插入刪除,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • 用c語言實現《狼人殺》游戲發(fā)牌系統(tǒng)

    用c語言實現《狼人殺》游戲發(fā)牌系統(tǒng)

    大家好,本篇文章主要講的是用c語言實現《狼人殺》游戲發(fā)牌系統(tǒng),感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01

最新評論

杭州市| 长乐市| 西畴县| 东乌| 邓州市| 永德县| 本溪市| 琼海市| 辽源市| 屯留县| 正镶白旗| 曲麻莱县| 五莲县| 舞阳县| 庐江县| 泗洪县| 安龙县| 衡山县| 嘉善县| 永川市| 灌南县| 洪洞县| 武穴市| 临海市| 资阳市| 嘉义市| 乐业县| 古田县| 社旗县| 嫩江县| 太保市| 阳谷县| 长宁县| 高雄市| 锦州市| 清徐县| 盖州市| 龙海市| 福清市| 莆田市| 博乐市|