zoukankan      html  css  js  c++  java
  • 模式识别之分类器knn---c语言实现带训练数据---反余弦匹配

    邻近算法
       

    KNN算法的决策过程
      k-Nearest Neighbor algorithm
    是K最邻近结点算法(k-Nearest Neighbor algorithm)的缩写形式,是电子信息分类器算法的一种

    该算法的基本思路是:在给定新文本后,考虑在训练文本集中与该新文本距离最近(最相似)的 K 篇文本,根据这 K 篇文本所属的类别判定新文本所属的类别
      左图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。
      K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。
      KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight),如权值与距离成正比。
      该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。因此可以采用权值的方法(和该样本距离小的邻居权值大)来改进。该方法的另一个不足之处是计算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。目前常用的解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。
    KNN-主要应用领域
    ·文本分类·聚类分析·数据挖掘·机器学习·预测分析·减少维度·模式识别·图像处理 
    我的kNN分类算法程序:


    ------------------- Code written by Stephen Liu -----------------------
    #include 
    #include 
    #define MAX 1000
    using namespace std;
    int m, i, j;
    int types;
    class str
    {
    public:
      float x;
      float y;
      float distance;
      int type;
    };
    str data;//输入的已知类别的数据
    str point;//需要根据kNN判断类别的未知数据
    str temp;
    void input_data()
    {
    cout << "请输入已知点的个数:";
    cin >> m;
    for ( i = 1; i <= m; i++)
    {
      cout <<"请输入点 " << i  <<"  的坐标x , y 和所属类别:" ;
      cin >> data.x >> data.y >> data.type;
    }
    }
    void Distance()//计算未知类别点与所有已知类别点的距离
    {
    for ( i = 1; i <= m; i++ )
      data.distance = sqrt  (  (data.x - point.x) * (data.x - point.x) + (data.y - point.y) * (data.y - point.y) );
    }
    void sort()//对距离进行从小到大排序
    {
    for( i = 1; i <= m; i++)
      for(j = m; j > i; j--)
      {
       if(data.distance  < data.distance)
       {
        temp=data;
        data=data;
        data=temp;
       }
      } 
    }
    int kNN( )
    {
    int the_type,num = 0, k;
    cout <<"请输入kNN的k值:";
    cin >> k;
    for ( i = 1; i <= 99; i++)
      types = 0;
    for ( i = 1; i <= k; i++)//对已排序的前k位距离类别进行统计
      types.type ] ++;
    for ( i = 1; i <= 99; i++)//找出未知类别点属于的类别

      if (types > num )
      {
       num = types;
       the_type = i;
      }
    }
    return ( the_type);
    }
    int main()
    {
    input_data();
    cout <<"请输入未知类别点的坐标x,y(输入0 0退出):";
    cin >> point.x >> point.y;
    do
    {
      Distance();
      sort();
      cout <<"点( " << point.x << " , " << point.y <<" )属于类"<<  kNN() << endl;
      cout <<"请输入未知类别点的坐标x,y(输入0 0退出):";
      cin >> point.x >> point.y;
    }
    while ( point.x != 0 && point.y != 0);
    cout <<"======= kNN分类算法 Stephen Liu  E-mail:stephenliu1989@163.com   2010.8 ======= ";
    system("pause");
    return 0;
    }
    ------------------------- Code end ---------------------------------
    我的评价:
    这是kNN分类算法的最简单的一种情况,当k取不同值时分类可能会出现不同。样本过大时,由于要比较的次数增多,效率降低。

    http://emuch.net/html/201009/2366638.html 原理

    http://download.csdn.net/download/wang123sf/1770715 代码

  • 相关阅读:
    动态表单之数据分页
    SQL Server 批量生成bcp命令
    SQL Server 全文索引的硬伤
    简单实用SQL脚本Part2:日期和时间函数
    使用SQL Server 扩展函数进行性能优化
    留念2010年5月5日
    C#获取URL参数值
    SQL Server扩展函数的基本概念
    SQL Server 空间换时间的数据库设计
    简单实用SQL脚本Part:查找SQL Server 自增ID值不连续记录
  • 原文地址:https://www.cnblogs.com/pengkunfan/p/3950781.html
Copyright © 2011-2022 走看看