• KNN算法 c++实现


    来源【机器学习实战之一】:C++实现K-近邻算法KNN_两个图像的特征向量应用knn模型进行匹配-CSDN博客

    k-近邻(kNN, k-NearestNeighbor)是在训练集中选取离输入的数据点最近的k个邻居,根据这个k个邻居中出现次数最多的类别(最大表决规则),作为该数据点的类别。 

    1. //计算每个训练数据到待分类元组的距离,取和待分类元组距离最近的k个训练数据,k个数据中哪个类别的训练数据占多数,则待分类元组就属于哪个类别。
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. using namespace std;
    12. const int col = 2;
    13. const int row = 12;
    14. typedef double TData;
    15. typedef char tData;
    16. //typedef pair Pari;
    17. ifstream fin; //输入文件流,可以用于从文件中读取数据。通过构造函数或 open() 成员函数打开指定的文件,然后使用输入运算符( >> )和其他输入操作从文件中读取数据:
    18. ofstream fout;
    19. class KNN
    20. {
    21. private:
    22. int k;
    23. TData TSet[row][col]; //训练数据
    24. TData Test[col]; //测试数据
    25. tData labels[row]; //类别
    26. map<int, double> dis_index;
    27. mapint> label_count;
    28. public:
    29. KNN(int k);
    30. double distance(TData* t1, TData* t2);
    31. void All_distance();
    32. void get_label();
    33. struct cmp
    34. {
    35. //调用运算符 operator() 的重载使得对象可以像函数一样使用,具有类似函数的行为,因此也称为函数对象。
    36. bool operator()(const pair<int,double>& a, const pair<int,double>& b) //常量引用类型 const T&
    37. {
    38. return a.second < b.second;
    39. }
    40. };
    41. };
    42. KNN::KNN(int k)
    43. {
    44. this->k = k;
    45. fin.open("data.txt");
    46. if (!fin)
    47. {
    48. cout << "can not open the data.txt" << endl;
    49. exit(1);
    50. }
    51. for (int i = 0; i < row; i++)
    52. {
    53. for (int j = 0; j < col; j++)
    54. {
    55. fin >> TSet[i][j];
    56. }
    57. fin >> labels[i];
    58. }
    59. cout << "请输入test data:" << endl;
    60. for(int i=0;i
    61. {
    62. cin >> Test[i];
    63. }
    64. }
    65. //数据集和测试数据对应坐标的距离和
    66. double KNN::distance(TData *t1, TData *t2)
    67. {
    68. double sum = 0;
    69. for (int i = 0; i < col; i++)
    70. {
    71. sum += pow((t1[i] - t2[i]), 2);
    72. }
    73. return sqrt(sum);
    74. }
    75. void KNN::All_distance()
    76. {
    77. double dis;
    78. for (int i = 0; i < row; i++)
    79. {
    80. dis = distance(TSet[i], Test);
    81. dis_index[i] = dis; //每一个训练数据到测试数据的dis
    82. }
    83. map<int, double>::const_iterator i = dis_index.begin();
    84. for (i; i != dis_index.end(); i++)
    85. {
    86. cout << "index=" << i->first << " distance=" << i->second << endl; //获取键和值
    87. }
    88. }
    89. //得到测试数据的类别
    90. void KNN::get_label()
    91. {
    92. vectorint,double>> vec_dis_index(dis_index.begin(), dis_index.end()); //包含了从 map 容器中复制出来的所有键值对
    93. //sort(vec_dis_index.begin(), vec_dis_index.end(), cmp()); //通常用来对数组或向量等容器类型进行排序sort(first, last [, comp]);
    94. sort(vec_dis_index.begin(), vec_dis_index.end(), [&](const pair<int, double>& a, const pair<int, double>& b) {return a.second < b.second; });
    95. for (int i = 0; i < k; i++)
    96. {
    97. cout << "index=" << vec_dis_index[i].first << " distance=" << vec_dis_index[i].second << " 类别=" << labels[vec_dis_index[i].first] << " 坐标=(" << TSet[vec_dis_index[i].first][0] << "," << TSet[vec_dis_index[i].first][1] << ")" << endl;
    98. label_count[labels[vec_dis_index[i].first]]++;
    99. }
    100. int max = 0;
    101. tData t;
    102. for (map<char, int>::const_iterator i = label_count.begin(); i != label_count.end(); i++)
    103. {
    104. if (i->second > max)
    105. {
    106. max = i->second;
    107. t=i->first;
    108. }
    109. }
    110. cout << "测试数据属于的类别" << t << endl;
    111. }
    112. int main()
    113. {
    114. int k;
    115. cout << "请输入k的值" << endl;
    116. cin >> k;
    117. KNN knn(k);
    118. knn.All_distance();
    119. knn.get_label();
    120. }

    结果


    例题: 

    某班有14个同学,已登记身高及等级,新同学易昌,身高1.74cm,等级是什么。请用knn算法进行分类识别,其中k=5。

    序号

    姓名

    身高(cm)

    等级

    1

    李丽

    1.5

    2

    吉米

    1.92

    3

    马大华

    1.7

    中等

    4

    王晓华

    1.73

    中等

    5

    刘敏

    1.6

    6

    张强

    1.75

    中等

    7

    李秦

    1.6

    8

    王壮

    1.9

    9

    刘冰

    1.68

    中等

    10

    张喆

    1.78

    中等

    11

    杨毅

    1.70

    中等

    12

    徐田

    1.68

    中等

    13

    高杰

    1.65

    14

    张晓

    1.78

    中等

     

    1. //计算每个训练数据到待分类元组的距离,取和待分类元组距离最近的k个训练数据,k个数据中哪个类别的训练数据占多数,则待分类元组就属于哪个类别。
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. using namespace std;
    15. ifstream fin; //输入文件流,可以用于从文件中读取数据。通过构造函数或 open() 成员函数打开指定的文件,然后使用输入运算符( >> )和其他输入操作从文件中读取数据:
    16. ofstream fout;
    17. struct Person {
    18. std::string name;
    19. double height;
    20. std::string category;
    21. };
    22. vector dataset;
    23. Person test;
    24. class KNN
    25. {
    26. private:
    27. int k;
    28. map<int, double> dis_index;
    29. mapint> label_count;
    30. public:
    31. KNN(int k);
    32. double distance(Person t1, Person t2);
    33. void All_distance();
    34. void get_label();
    35. };
    36. KNN::KNN(int k)
    37. {
    38. this->k = k;
    39. ifstream file("data.txt");
    40. if (file.is_open())
    41. {
    42. string line;
    43. while (getline(file, line)) {
    44. stringstream ss(line); //
    45. string name, category;
    46. double height;
    47. ss >> name >> height >> category;
    48. dataset.push_back({ name, height, category });
    49. }
    50. }
    51. }
    52. //数据集和测试数据
    53. double KNN::distance(Person t1, Person t2)
    54. {
    55. return abs(t1.height - t2.height);
    56. }
    57. void KNN::All_distance()
    58. {
    59. double dis;
    60. for (int i = 0; i < dataset.size(); i++)
    61. {
    62. dis = distance(dataset[i], test);
    63. dis_index[i] = dis; //每一个训练数据到测试数据的dis
    64. }
    65. map<int, double>::const_iterator i = dis_index.begin();
    66. cout << "index " << "姓名 " << "distance " << "类别 " << endl;
    67. for (i; i != dis_index.end(); i++)
    68. {
    69. cout << i->first+1 <<" " << dataset[i->first].name << " " << i->second << " " << dataset[i->first].category << endl; //获取键和值
    70. }
    71. }
    72. //得到测试数据的类别
    73. void KNN::get_label()
    74. {
    75. vectorint, double>> vec_dis_index(dis_index.begin(), dis_index.end()); //包含了从 map 容器中复制出来的所有键值对
    76. //sort(vec_dis_index.begin(), vec_dis_index.end(), cmp()); //通常用来对数组或向量等容器类型进行排序sort(first, last [, comp]);
    77. sort(vec_dis_index.begin(), vec_dis_index.end(),
    78. [&](const pair<int, double>& a, const pair<int, double>& b) {return a.second < b.second; });
    79. cout << endl<<"最近的k个簇的类别为" << endl;
    80. for (int i = 0; i < k; i++)
    81. {
    82. cout << "index=" << vec_dis_index[i].first+1 << " name="<< dataset[vec_dis_index[i].first].name<<" distance = " << vec_dis_index[i].second << " 类别 = " << dataset[vec_dis_index[i].first].category << endl;
    83. label_count[dataset[vec_dis_index[i].first].category]++;
    84. }
    85. int max = 0;
    86. string t;
    87. for (mapint>::const_iterator i = label_count.begin(); i != label_count.end(); i++)
    88. {
    89. if (i->second > max)
    90. {
    91. max = i->second;
    92. t = i->first;
    93. }
    94. }
    95. cout << endl<<"测试数据属于的类别" << t << endl;
    96. }
    97. int main()
    98. {
    99. int k;
    100. cout << "请输入k的值" << endl;
    101. cin >> k;
    102. cout << "输入测试数据" << endl;
    103. cin >> test.name >> test.height;
    104. KNN knn(k);
    105. knn.All_distance();
    106. knn.get_label();
    107. }

    运行结果

  • 相关阅读:
    9.19 校招 实习 内推 面经
    数据结构- 树
    如何免费获取基于公网 IP 的 SSL 证书 (无需域名)
    【毕业设计】树莓派智能捡垃圾机器人 - 机器视觉 单片机 物联网
    计算机视觉顶会顶刊
    Disruptor(一)Sequence
    配置bootstrap.yml
    opensips使用drouting进行路由
    智能合约漏洞案例,DEI 漏洞复现
    Go语言实用用法大全
  • 原文地址:https://blog.csdn.net/m0_70732442/article/details/133909118