kNN(K-Nearest Neighbor)最邻近规则分类

2023-05-16

K最近邻分类算法

方法的思路:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于这一类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分类样本所属的类别。KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight),如权值与距离成正比(组合函数)。

该算法在分类时有个主要的不足是,当样本不平衡时,如一个类的样本容量很大,而其他类样本容量很小时,

有可能导致当输入一个新样本时,该样本的K个邻居中大容量类的样本占多数。 该算法只计算“最近的”邻居样本,某

一类的样本数量很大,那么或者这类样本并不接近目标样本,或者这类样本很靠近目标样本。无论怎样,数量并不能

影响运行结果。可以采用权值的方法(和该样本距离小的邻居权值大)来改进

该方法的另一个不足之处算量较大,因为对每一个待分类的文本都要计算它到全体已知样本的距离,才能求得它的K个最近邻点。目前常用的

解决方法是事先对已知样本点进行剪辑,事先去除对分类作用不大的样本。该算法比较适用于样本容量比较大的类域

的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分


简单来说,K-NN可以看成:有那么一堆你已经知道分类的数据,然后当一个新数据进入的时候,就开始跟训练数据

里的每个点求距离,然后挑离这个训练数据最近的K个点看看这几个点属于什么类型,然后用少数服从多数的原则,

给新数据归类。



算法步骤:

step.1---初始化距离为最大值

step.2---计算未知样本和每个训练样本的距离dist

step.3---得到目前K个最临近样本中的最大距离maxdist

step.4---如果dist小于maxdist,则将该训练样本作为K-最近邻样本

step.5---重复步骤2、3、4,直到未知样本和所有训练样本的距离都算完

step.6---统计K-最近邻样本中每个类标号出现的次数

step.7---选择出现频率最大的类标号作为未知样本的类标号


KNN的matlab简单实现代码

 

function target=KNN(in,out,test,k)
% in:       training samples data,n*d matrix
% out: training samples' class label,n*1
% test:     testing data
% target:   class label given by knn
% k:        the number of neighbors
ClassLabel=unique(out);
c=length(ClassLabel);
n=size(in,1);
% target=zeros(size(test,1),1);
dist=zeros(size(in,1),1);
for j=1:size(test,1)
    cnt=zeros(c,1);
    for i=1:n
        dist(i)=norm(in(i,:)-test(j,:));
    end
    [d,index]=sort(dist);
    for i=1:k
        ind=find(ClassLabel==out(index(i)));
        cnt(ind)=cnt(ind)+1;
    end
    [m,ind]=max(cnt);
    target(j)=ClassLabel(ind);
end
 
R语言的实现代码如下
library(class)
data(iris)
names(iris)
m1<-knn.cv(iris[,1:4],iris[,5],k=3,prob=TRUE)
attributes(.Last.value)
library(MASS)
m2<-lda(iris[,1:4],iris[,5])  与判别分析进行比较
b<-data.frame(Sepal.Length=6,Sepal.Width=4,Petal.Length=5,Petal.Width=6)
p1<-predict(m2,b,type="class")

C++ 实现 :

//    KNN.cpp     K-最近邻分类算法
//

#include <stdlib.h>
#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <iostream>
#include <math.h>
#include <fstream>
using namespace std;

//
//    宏定义
//

#define  ATTR_NUM  4                        //属性数目
#define  MAX_SIZE_OF_TRAINING_SET  1000      //训练数据集的最大大小
#define  MAX_SIZE_OF_TEST_SET      100       //测试数据集的最大大小
#define  MAX_VALUE  10000.0                  //属性最大值
#define  K  7
//结构体
struct dataVector {
 int ID;                      //ID号
 char classLabel[15];             //分类标号
 double attributes[ATTR_NUM]; //属性 
};
struct distanceStruct {
 int ID;                      //ID号
 double distance;             //距离
 char classLabel[15];             //分类标号
};

//
//    全局变量
//

struct dataVector gTrainingSet[MAX_SIZE_OF_TRAINING_SET]; //训练数据集
struct dataVector gTestSet[MAX_SIZE_OF_TEST_SET];         //测试数据集
struct distanceStruct gNearestDistance[K];                //K个最近邻距离
int curTrainingSetSize=0;                                 //训练数据集的大小
int curTestSetSize=0;                                     //测试数据集的大小

//
//    求 vector1=(x1,x2,...,xn)和vector2=(y1,y2,...,yn)的欧几里德距离
//

double Distance(struct dataVector vector1,struct dataVector vector2)
{
 double dist,sum=0.0;
 for(int i=0;i<ATTR_NUM;i++)
 {
  sum+=(vector1.attributes[i]-vector2.attributes[i])*(vector1.attributes[i]-vector2.attributes[i]);
 }
 dist=sqrt(sum);
 return dist;
}

//
//    得到gNearestDistance中的最大距离,返回下标
//

int GetMaxDistance()
{
 int maxNo=0;
 for(int i=1;i<K;i++)
 {
  if(gNearestDistance[i].distance>gNearestDistance[maxNo].distance) maxNo = i;
 }
    return maxNo;
}

//
//    对未知样本Sample分类
//

char* Classify(struct dataVector Sample)
{
 double dist=0;
 int maxid=0,freq[K],i,tmpfreq=1;;
 char *curClassLable=gNearestDistance[0].classLabel;
 memset(freq,1,sizeof(freq));
 //step.1---初始化距离为最大值
 for(i=0;i<K;i++)
 {
  gNearestDistance[i].distance=MAX_VALUE;
 }
 //step.2---计算K-最近邻距离
 for(i=0;i<curTrainingSetSize;i++)
 {
  //step.2.1---计算未知样本和每个训练样本的距离
  dist=Distance(gTrainingSet[i],Sample);
  //step.2.2---得到gNearestDistance中的最大距离
  maxid=GetMaxDistance();
  //step.2.3---如果距离小于gNearestDistance中的最大距离,则将该样本作为K-最近邻样本
  if(dist<gNearestDistance[maxid].distance) 
  {
   gNearestDistance[maxid].ID=gTrainingSet[i].ID;
   gNearestDistance[maxid].distance=dist;
   strcpy(gNearestDistance[maxid].classLabel,gTrainingSet[i].classLabel);
  }
 }
 //step.3---统计每个类出现的次数
 for(i=0;i<K;i++)  
 {
  for(int j=0;j<K;j++)
  {
   if((i!=j)&&(strcmp(gNearestDistance[i].classLabel,gNearestDistance[j].classLabel)==0))
   {
    freq[i]+=1;
   }
  }
 }
 //step.4---选择出现频率最大的类标号
 for(i=0;i<K;i++)
 {
  if(freq[i]>tmpfreq)  
  {
   tmpfreq=freq[i];
    curClassLable=gNearestDistance[i].classLabel;
  }
 }
 return curClassLable;
}

//
//    主函数
//

void main()
{   
 char c; 
    char *classLabel="";
 int i,j, rowNo=0,TruePositive=0,FalsePositive=0;
 ifstream filein("iris.data");
 FILE *fp;
 if(filein.fail()){cout<<"Can't open data.txt"<<endl; return;}
 //step.1---读文件 
 while(!filein.eof()) 
 {
  rowNo++;//第一组数据rowNo=1
  if(curTrainingSetSize>=MAX_SIZE_OF_TRAINING_SET) 
  {
   cout<<"The training set has "<<MAX_SIZE_OF_TRAINING_SET<<" examples!"<<endl<<endl;
   break ;
  }  
  //rowNo%3!=0的100组数据作为训练数据集
  if(rowNo%3!=0)
  {   
   gTrainingSet[curTrainingSetSize].ID=rowNo;
   for(int i = 0;i < ATTR_NUM;i++) 
   {     
    filein>>gTrainingSet[curTrainingSetSize].attributes[i];
    filein>>c;
   }   
   filein>>gTrainingSet[curTrainingSetSize].classLabel;
   curTrainingSetSize++;
   
  }
  //剩下rowNo%3==0的50组做测试数据集
  else if(rowNo%3==0)
  {
   gTestSet[curTestSetSize].ID=rowNo;
   for(int i = 0;i < ATTR_NUM;i++) 
   {    
    filein>>gTestSet[curTestSetSize].attributes[i];
    filein>>c;
   }  
   filein>>gTestSet[curTestSetSize].classLabel;
   curTestSetSize++;
  }
 }
 filein.close();
 //step.2---KNN算法进行分类,并将结果写到文件iris_OutPut.txt
 fp=fopen("iris_OutPut.txt","w+t");
 //用KNN算法进行分类
 fprintf(fp,"************************************程序说明***************************************\n");
 fprintf(fp,"** 采用KNN算法对iris.data分类。为了操作方便,对各组数据添加rowNo属性,第一组rowNo=1!\n");
 fprintf(fp,"** 共有150组数据,选择rowNo模3不等于0的100组作为训练数据集,剩下的50组做测试数据集\n");
 fprintf(fp,"***********************************************************************************\n\n");
 fprintf(fp,"************************************实验结果***************************************\n\n");
 for(i=0;i<curTestSetSize;i++)
 {
        fprintf(fp,"************************************第%d组数据**************************************\n",i+1);
  classLabel =Classify(gTestSet[i]);
     if(strcmp(classLabel,gTestSet[i].classLabel)==0)//相等时,分类正确
  {
   TruePositive++;
  }
  cout<<"rowNo: ";
  cout<<gTestSet[i].ID<<"    \t";
  cout<<"KNN分类结果:      ";
  cout<<classLabel<<"(正确类标号: ";
  cout<<gTestSet[i].classLabel<<")\n";
  fprintf(fp,"rowNo:  %3d   \t  KNN分类结果:  %s ( 正确类标号:  %s )\n",gTestSet[i].ID,classLabel,gTestSet[i].classLabel);
  if(strcmp(classLabel,gTestSet[i].classLabel)!=0)//不等时,分类错误
  {
  // cout<<"   ***分类错误***\n";
   fprintf(fp,"                                                                      ***分类错误***\n");
  }
  fprintf(fp,"%d-最临近数据:\n",K);
  for(j=0;j<K;j++)
  {
  // cout<<gNearestDistance[j].ID<<"\t"<<gNearestDistance[j].distance<<"\t"<<gNearestDistance[j].classLabel[15]<<endl;
   fprintf(fp,"rowNo:  %3d   \t   Distance:  %f   \tClassLable:    %s\n",gNearestDistance[j].ID,gNearestDistance[j].distance,gNearestDistance[j].classLabel);
  }
  fprintf(fp,"\n"); 
 }
    FalsePositive=curTestSetSize-TruePositive;
 fprintf(fp,"***********************************结果分析**************************************\n",i);
 fprintf(fp,"TP(True positive): %d\nFP(False positive): %d\naccuracy: %f\n",TruePositive,FalsePositive,double(TruePositive)/(curTestSetSize-1));
 fclose(fp);
    return;
}

以上内容为参考网上有关资料;加以总结;





本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kNN(K-Nearest Neighbor)最邻近规则分类 的相关文章

  • 最近邻插值法(nearest_neighbor)

    1 原理与应用 最近邻插值法nearest neighbor是最简单的灰度值插值 也称作零阶插值 xff0c 就是令变换后像素的灰度值等于距它最近的输入像素的灰度值 最近邻插值法可应用于图像的缩放 xff0c 因为简单的变换与计算 xff0
  • 机器学习——KNN

    机器学习算法 KNN KNN算法和KD Tree 思维导图
  • 【数据聚类|深度聚类】Nearest Neighbor Matching for Deep Clustering(NNM)论文研读

    文章目录 Abstract Intorduction Related work Deep Clustering Contrastive Representation Learning Methodology Unsupervised Rep
  • Introduction to Using the Global Nearest Neighbor Tracker

    MATLAB R2019b global nearest neighbor GNN tracker xff1a 最近邻 1 目标 Choose the assignment algorithm to associate detections
  • 基于k近邻(KNN)的手写数字识别

    作者 xff1a faaronzheng 转载请注明出处 xff01 最近再看Machine Learning in Action k近邻算法这一章节提供了不少例子 xff0c 本着Talk is cheap的原则 xff0c 我们用手写数
  • 基于Hadoop的Knn算法实现

    Knn算法的核心思想是如果一个样本在特征空间中的K个最相邻的样本中的大多数属于某一个类别 则该样本也属于这个类别 并具有这个类别上样本的特性 该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别 Knn方法在类
  • K最近邻算法(KNN)---sklearn+python实现

    k 近邻算法概述 简单地说 k近邻算法采用测量不同特征值之间的距离方法进行分类 k 近邻算法 优点 精度高 对异常值不敏感 无数据输入假定 缺点 计算复杂度高 空间复杂度高 适用数据范围 数值型和标称型 k 近邻算法 kNN 它的工作原理是
  • 100-Days-Of-ML系列Day

    今天继续学习机器学习算法 KNN KNN是通过测量不同特征值之间的距离进行分类的一种算法 它的思路是 如果一个样本在特征空间的k个最相似 即特征空间中最近邻 的样本大多数属于某一个类别 则该样本也属于这个类别 其中k通常是不大于20的整数
  • sklearn K近邻KNeighborsClassifier参数详解

    原文网址 https scikit learn org stable modules generated sklearn neighbors KNeighborsClassifier html class sklearn neighbors
  • 泡菜懒惰学习者

    Pickle 是否为像 KNeighborsClassifier 这样的懒惰学习者保存来自 scikit 的训练数据 如果是这样 我们可以从 pickle 对象访问这些数据吗 询问数据隐私问题 Eg knn fit Xtrain Ytrai
  • 如何在 python 中使用 kNN 动态时间扭曲

    我有一个带有两个标签的时间序列数据集 0 and 1 我在用动态时间扭曲 DTW 作为使用 k 最近邻 kNN 进行分类的相似性度量 如这两篇精彩的博客文章中所述 https nbviewer jupyter org github mark
  • 使用 Python 从图像创建数据集以进行人脸识别

    我正在尝试用 Python 编写一个人脸识别程序 我将应用 k nn 算法进行分类 首先 我将图像转换为灰度 然后使用图像的像素 总共 128x128 16384 个特征 创建一个长列向量 通过使用 Opencv 的 imagedata 函
  • 使用 KNN 分类器进行数字识别之前的预处理

    现在我正在尝试使用 OpenCV 创建数字识别系统 WEB上有很多文章和例子 甚至在堆栈溢出 https stackoverflow com questions 9413216 simple digit recognition ocr in
  • 使用 opencv 3.0 的 cv2 中的 KNN train()

    我正在尝试使用 cv2 python 2 7 和 opencv 3 0 运行 k 最近邻 我使用类似的代码复制了相同的错误消息http docs opencv org 3 0 beta doc py tutorials py ml py k
  • Sklearn KNeighborsRegressor 自定义距离度量

    我正在使用 KNeighborsRegressor 但我想将它与自定义距离函数一起使用 我的训练集是 pandas DataFrame 如下所示 week day hour minute temp humidity 0 1 9 0 1 1
  • K 最近邻算法 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 使用 KNN 算法 假设 k 5 现在我尝试通过获取 5 个最近的邻居来对未知对象进行分类 如果确定 4 个最近邻居后 接下来的 2 个
  • Java 中字符串(非结构化数据)的 K 最近邻实现

    我正在寻找 Java 中针对非结构化数据的 K 最近邻算法的实现 我发现了许多数字数据的实现 但是我如何实现它并计算文本 字符串 的欧几里得距离 以下是 double 的一个示例 public static double Euclidean
  • 如果 kNN 没有训练阶段,当我们将 .fit() 方法应用于 Scikit-learn 中的 kNN 模型时会发生什么?

    由于 kNN 在 RAM 级别处理训练和预测 并且不需要显式的训练过程 那么当拟合 knn 模型时到底会发生什么 我认为这一步与训练模型有关 谢谢 这是如果我跳过拟合步骤将会得到的错误 NotFittedError This KNeighb
  • 当尝试在 R 中运行 kNN 时,我收到由 coercionNAs 引入的错误 NAs?

    我正在尝试在数据集上运行 kNN 但我不断收到一些 NA 错误 我已经用尽了堆栈溢出试图找到这个问题的解决方案 我在任何地方都找不到任何有用的东西 这是我正在使用的数据集 https www kaggle com tsiaras uk ro
  • 从距离矩阵开始查找 K 个最近邻

    我正在寻找一个接受良好优化的函数n X n距离矩阵并返回n X k矩阵的索引k第 i 行中第 i 个数据点的最近邻居 我发现了无数的不同R可以让您执行 KNN 的软件包 但它们似乎都在同一函数中包含距离计算和排序算法 特别是 对于大多数例程

随机推荐

  • CV和NLP不分家

    嗯 xff0c 好久没有登陆csdn了 xff0c 看了一下 xff0c 距离上一篇文章发表已经过去了整整半年的时间了 xff0c 消息堆叠了将近100条 也没办法一一回复了 xff0c 因为这么长时间过去了 xff0c 不知道大家的问题都
  • 2022-09-14-openstack介绍

    1 云计算介绍 计算 xff08 CPU 内存 xff09 存储和网络是 IT 系统的三类资源 通过云计算平台 xff0c 这三类资源变成了三个资源池 当需要虚机的时候 xff0c 只需要向平台提供虚机的规格 平台会快速从三个资源池分配相应
  • docker debian中apt-get源替换为阿里源

    场景 docker容器内安装太慢 xff0c 实在受不了这速度了 解决方案 将默认的debian源替换为阿里源 cat命令 因为默认不带vim 查看源配置文件 xff1a span class token function cat span
  • Spring整合Junit

    原始Junit测试Spring的问题 在测试类中 xff0c 每个测试方法都有以下两行代码 xff1a ApplicationContext ac 61 new ClassPathXmlApplicationContext 34 bean
  • STM32驱动舵机(附例程)

    一 PWM Mode xff1a 当计数值小于CRR寄存器值时输出为有效电平 xff0c 而有效电平要根据OCXInit来设置 xff0c 设置的有效电平为高则当CNT值小于设置的CRR寄存器值时输出有效电平高电平 xff0c 当CNT值大
  • Win10下安装Anaconda后,conda不是内部或者外部命令

    今天在安装TAnaconda时 xff0c 在开始 gt 运行 gt cmd时输入如下命令 xff1a conda version 时显示出错 xff0c cuda不是内部或者外部命令 xff1b 第一直觉就是去检查环境变量 xff0c 你
  • VM16-ubuntu16桥接网络频繁掉线

    故障说明 旧电脑使用的vm15 ubuntu16 xff0c 通过移植安装到新电脑 xff0c 后又通过升级把虚拟机升级到vm16 xff0c 更改网络连接的NAT模式到桥接模式 xff0c 发现网络即使出现正常连接的图标和正确的IP地址但
  • IPTV机顶盒刷机过程--山东电信【天邑TY608】

    IPTV机顶盒刷机过程 山东电信 天邑TY608 准备工具拆机过程开始刷机 准备工具 双公头USB数据线 刷机小板 xff0c 我用的是淘宝买的USB转TTL的CH340G的小板 电烙铁 焊锡丝 焊锡膏 单排排针 拆机过程 这个型号的机顶盒
  • OpenStack Availability Zone和Aggregate Hosts理解

    1 availability zone az是在region范围内的再次切分 xff0c 只是工程上的独立 xff0c 例如可以把一个机架上的机器划分在一个az中 xff0c 划分az是为了提高容灾性和提供廉价的隔离服务 选择不同的regi
  • Mysql 根据月份分组并返回分组中的所有数据

    现有数据如下 xff1a 交易描述 金额 时间 交易A 1000 2021 01 28 交易B 2000 2021 01 30 交易C 3000 2021 02 03 交易D 4000 2021 02 04 交易E 5000 2021 02
  • 程序设计思维与实践 Week13 作业 (3/4/数据班)

    A TT 的神秘任务1 xff08 必做 xff09 这一天 xff0c TT 遇到了一个神秘人 神秘人给了两个数字 xff0c 分别表示 n 和 k xff0c 并要求 TT 给出 k 个奇偶性相同的正整数 xff0c 使得其和等于 n
  • 安装scikit-learn问题

    1 问题描述如下 xff1a pytorch root 64 cento conda install scikit learn Solving environment failed CondaHTTPError HTTP 000 CONNE
  • 火狐下setting a property that has only a getter 的错误, 真是诡异...

    刚刚遇到了个很诡异的问题 xff0c 有一段看似没有错误的js代码硬是在火狐下会报个 setting a property that has only a getter 错误 xff0c 而在其他浏览器下却可以正常运行 xff0c 代码大概
  • 最新社区版idea插件“intellij-spring-assistant”

    1 背景 idea社区版已经用了好长时间了 xff0c 其中丰富的插件库让社区版使用起来与专业版无差异 xff0c 完全能够满足当前工作需求 xff0c 但是随着版本的不断更新 xff0c 原作者已不再更新 xff0c 导致无法在新版本上使
  • VS2017/2019中默认编码问题,修改文本编码格式 为UTF-8

    1 修改VS中单个文本编码方式 VS2017 2019中默认格式为 GB2312 很多时候可能出现乱码情况 xff0c 就是编码问题 xff0c 接下来 xff0c 可以修改编码方式 xff1a 操作方法如下所示 xff1a 首先 xff0
  • 宏定义中的括号和自增自减运算(1)

    宏定义中容易引起许多运算优先级的问题 xff0c 需要用括号加以约束 例如 define abs x x gt 0 x x abs a b abs a 43 1 带入展开后 xff0c 结果如下 xff1a a b gt 0 a b a b
  • K-means算法

    算法描述 xff1a 1 gt 从N个数据中选出K个元素作为质心 xff0c 即数据将被分成K簇 2 gt 依次计算剩下的每一个元素到K个元素的相异度 xff0c 一般是计算距离 xff0c 将这些元素分别划分到相异度最低的簇中去 3 gt
  • 编程领域中的事务概念解析

    在编程领域 xff0c 事务 xff08 Transaction xff09 是一个非常重要的概念 它可以帮助我们处理分布式系统中的并发问题 保证数据的一致性和完整性 本文将详细解释事务的概念及其在编程中的应用 一 什么是事务 xff1f
  • C++流概述

    C 43 43 流概述 在程序设计中 xff0c 数据输入 输出 xff08 I O xff09 操作是必不可少的 xff0c C 43 43 语言的数据输入 输出操作是通过I O流库来实现的 C 43 43 中把数据之间的传输操作称为流
  • kNN(K-Nearest Neighbor)最邻近规则分类

    K最近邻分类算法 方法的思路 xff1a 如果一个样本在特征空间中的k个最相似 xff08 即特征空间中最邻近 xff09 的样本中的大多数属于这一类别 xff0c 则该样本也属于这个类别 KNN算法中 xff0c 所选择的邻居都是已经正确