KNN(K-Nearest-Neighbour) Classifiers, 即K-近邻算法,是一种懒惰机器学习算法(lazy learning)。简而言之,它在拿到训练集数据时并不急着去建模,而是在拿到测试集数据后,再到训练集数据中去寻找该测试样本最近的“邻居”,即距离最近的K个训练样本,依照训练样本数据的所属类别,加权或不加权地得出测试数据的类别。那么应该选择多少个邻居呢,即K取值是多还是少好呢?如果K选得小,得到的测试数据分类结果的偏差(bais)就小,同时方差(variance)增大;而如果K选得大,结果的偏差会增大,同时方差却会减小。

K近邻算法一般而言有4步:定下K值-->变量标准化-->计算测试样本到每个训练样本的距离-->加权或不加权地进行预测。下面用打高尔夫球的例子做具体计算。数据如下,共14条数据,以第一条数据作为测试样本。其中,temperature表示当天温度,humidity表表示当天湿度,play是要预测的变量,即是否打高尔夫。选择K=3,下面计算距离。

明氏距离:

这里为了方便计算,取p=1.那么第一个观测值到第2、第3个训练样本的明氏距离为:

dis1=|85-80|+|85-90|=10,dis2=|85-83|+|85-86|=3。

其他的计算方法相同,可以用R计算出每个训练样本离测试样本的距离:

library(kknn)
golf <- read.csv("golf.csv",header=T)
golf.train <- golf[-1,c(2:3,5)]
golf.test <- golf[1,2:3]
golf.kknn <- kknn(Play~.,golf.train,golf.test,k=3,scale=F,distance=1,kernel= "rectangular")
golf.kknn$CL #邻居的类别
golf.kknn$D #邻居与它的距离
golf.kknn$C #邻居的观测值号

kknn函数的参数依次为:formula,训练集,测试集,邻居的个数K,是否标准化(一般标准化,这里先不标准化),明氏距离中的参数p的值(这里设定p=1),加权方法(这里是rectangular,表示等权重,即不加权)。查看kknn选择的3个邻居的类别、距离以及所属的观测值编号:

可见,与测试样本距离最近的三个邻居分别是(删去了第一行测试数据了以后的)第2个、第1个和第12个观测值,其与测试样本的明氏距离分别为3,10和14,所属类别分别为yes,no,yes。在不加权时,各个邻居权重相等,那么很显然测试样本的分类应该听邻居中的“大多数”的,即选择yes这一类。如果选择加权呢?

加权的方式有很多种,R中提供的有:Possible choices are "rectangular" (which is standard unweighted knn), "triangular", "epanechnikov" (or beta(2,2)), "biweight" (or beta(3,3)), "triweight" (or beta(4,4)), "cos", "inv", "gaussian", "rank" and "optimal".

这里先用triangular法演示计算过程,三角加权函数的公式为:

其中,为使u处于-1到1之间,需要对u进行调整,R中使用的调整方式为:第i个邻居到测试样本的距离/排在第k+1远的邻居到它的距离,即:

在这里,最近的邻居的u1=3/15=0.2,其中15是计算出的第4远的邻居距测试样本的距离,则K(u1)=1-0.2=0.8,第二远的邻居u2=10/15=0.667,K(u1)=1-0.667=0.333,第三远的邻居u3=14/15=0.933,K(u3)=1-0.933=0.067,因此三者的权重分别为:0.8/(0.8+0.333+0.067)=0.67,0.333/(0.8+0.333+0.067)=0.28,0.067/(0.8+0.333+0.067)=0.05.所以测试样本被归为yes类的概率是0.67+0.05=0.72,而被归为no类的概率为0.28.可以看到,此结果与R的预测结果几乎相同。

golf.kknn <- kknn(Play~.,golf.train,golf.test,k=3,scale=F,distance=1,kernel= "triangular")
golf.kknn$CL #邻居的类别
golf.kknn$W #邻居的权重
golf.kknn$prob #分类结果

运行结果如下:

此外,R的kknn包中还有可以自动选择最优参数的函数:train.kknn和cv.kknn,前者采用留一交叉验证做参数选择,后者采用交叉验证做参数选择(可以自己选择折数),可以用下面的代码进行:

#取distance=2
golf.tkknn <- train.kknn(Play~.,golf[,c(2:3,5)],kernel = c("rectangular", "triangular", "epanechnikov", "optimal"),distance=2,scale=T)
plot(golf.tkknn)
golf.tkknn$MISCLASS #显示错误率
golf.tkknn #输出最优参数情况
golf.tkknn <- train.kknn(Play~.,golf[,c(2:3,5)],kernel = c("rectangular", "triangular", "epanechnikov", "optimal"),distance=1,scale=T)
plot(golf.tkknn)
golf.tkknn$MISCLASS
golf.tkknn

两者选择结果相同,最小错误率均为0.36,最好的加权方法都选择了不加权。

Minimal misclassification: 0.3571429
Best kernel: rectangular
Best k: 9


由图像也可以看到,无论k取多少,错误率最小的都是rectangular法(不加权),在k=9就明显最小。

KNN算法以及R语言的实现相关推荐

  1. 人工晶状体计算——人工智能算法(R语言)

    人工晶状体计算--人工智能算法(R语言) 1. 准备数据 2. 建立模型 2.1 方法1 2.2 方法2 1. 准备数据 准备数据Data.xlsx,示例如图 Age AL ACD K1 K2 WTW ...

  2. k均值聚类算法案例 r语言iris_K-means算法原理

    聚类的基本思想 俗话说"物以类聚,人以群分" 聚类(Clustering)是一种无监督学习(unsupervised learning),简单地说就是把相似的对象归到同一簇中.簇内 ...

  3. r语言kmodes_聚类分析——k-means算法及R语言实现

    我们知道『物以类聚,人以群分』,这里并不是分类问题,而是聚类问题. 两者主要区别在于,分类是将一组数据根据不同的类区分,已经知道有哪些类,也就是数据已经有了类的标签.而聚类是一种事先不知道有多少类,通 ...

  4. 分类树/装袋法/随机森林算法的R语言实现

    原文首发于简书于[2018.06.12] 本文是我自己动手用R语言写的实现分类树的代码,以及在此基础上写的袋装法(bagging)和随机森林(random forest)的算法实现.全文的结构是: 分 ...

  5. k均值聚类算法案例 r语言iris_聚类分析—系统聚类

    聚类就是按照某个特定标准把一个数据集分割成不同的类或簇,最后的结果是希望同类之间的差异性尽可能小,不同类之间的差异性尽可能大.不同的类具有能够表达异于其他类的指标,这样针对不同的类,后续就能采取不一样 ...

  6. r语言nonzerocoef函数_lars算法的R语言操作指南

    Package 'lars' February 20, 2015 Type Package Version 1.2 Date 2013-04-23 Title Least Angle Regressi ...

  7. 【人工智能】利用C语言实现KNN算法进行手写数字识别

    KNN算法称为邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法.所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表. kNN算法的核心 ...

  8. R语言之离群点检验(part2)--局部离群点因子LOF检验

    学习笔记 参考文献:<R语言与数据挖掘> 局部离群点因子检验 概述 局部离群点因子(LOF)是一种基于密度的局部离群点的算法.局部离群点因子算法,将一个点的局部密度与其邻域点的局部密度进行 ...

  9. 【视频】马尔可夫链蒙特卡罗方法MCMC原理与R语言实现|数据分享

    原文链接:http://tecdat.cn/?p=2687 在贝叶斯方法中,马尔可夫链蒙特卡罗方法尤其神秘(点击文末"阅读原文"获取完整代码数据). 它们肯定是数学繁重且计算量大的 ...

  10. R语言中的多项式回归、局部回归、核平滑和平滑样条回归模型

    全文下载链接:http://tecdat.cn/?p=20531 当线性假设无法满足时,可以考虑使用其他方法(点击文末"阅读原文"获取完整代码数据). 相关视频 多项式回归 扩展可 ...

最新文章

  1. pandas使用groupby函数、agg函数获取每个分组聚合对应的标准差(std)实战:计算分组聚合单数据列的标准差(std)、计算分组聚合多数据列的标准差(std)
  2. c++ 重载 重写_Java | 深入理解方法调用的本质(含重载与重写区别)
  3. [SQL] 外卖系统数据库设计
  4. arcgis坐标系学习总结
  5. linux java进程消失_Linux系统下的Java进程无故消失怎么办?
  6. TensorFlow 笔记3--模型的保存与恢复
  7. JMeter 压力测试使用CSV参数
  8. 《Windows via C/C++》学习笔记 —— 内核对象的“线程同步”之“事件内核对象”...
  9. 【CITE】C#默认以管理员身份运行程序实现代码
  10. 安装moodle3.6
  11. 安装最新版SopCast 0.4.1
  12. 玩转云服务器,怎样用云服务器架设搭建游戏:浪剑天下架设教程,手把手教你架设游戏服务器,小白一看就会
  13. 深圳旅游區景點及簡介
  14. ToB产品如何做好产品推广:找到机会点
  15. ajax 一个完整的ajax请求
  16. Jarvis OJ PORT51
  17. 暴风影音2007全功能完美版和Symantec Norton的冲突 1
  18. Dubbo2.7.3入门
  19. c语言中“|”和“||”区别
  20. tkinter教程4:控件LabelFrame和Entry

热门文章

  1. 项目实战之电子商城数据库源码
  2. 【Python】用150行代码模拟太阳系行星运转+源码
  3. Linux中巧用zip命令压缩和解压缩文件
  4. 中国网游未来发展方向预测
  5. 使用vue3+vite+cesium,在地图上显示图标,并且点击实体弹出消息框
  6. 【转】PV3D的小练习~太阳系八大行星
  7. TalkingData游戏统计对接
  8. 图片验证码的逻辑实现
  9. python is not defined
  10. 字节和兆字节的换算_兆字节(MB)中有多少个字节?