【数据挖掘算法】KNN学习

KNN算法

  KNN(k-nearest-neighbour)是数据挖掘领域的基本算法之一,原理比较简单,在各类别均衡、样本容量比较大的情况下比较实用。
  

算法原理

  算法以样本间的距离作为相似性测度。在同一测量空间中以测试样本为中心,检测一定范围内的k个样本类别,用“投票法”得出测试样本的类别。

#设k为离测试样本最近的样本数,d为数据集
for 数据集中的每条数据 do
    计算其余所有点与样本点距离
    对距离从小到大排序,取前k个
    计算k个样本中出现最多的类别,将它赋给测试样本
end for

有必要关注的地方有三点:
距离的量度
  欧式距离很常用,但是它忽略了量纲的影响。两点之间的欧式距离与测量单位有关,所以当不同分量的量纲不同时需要进行标准化处理。
  欧式距离
  明氏距离是对欧式距离的扩展,当p=2时二者相同。
  明氏距离
  马氏距离考虑了量纲的影响,据此得出的距离与测量单位无关。
  这里写图片描述
  根据实际情况可以针对不同类别样本对测试样本距离的影响赋予不同的权值,这样可以减少错误率。对于文本数据挖掘,常用夹角余弦作为相似性测度。
  
k的取值
  因为样本类别由k个样本决定,所以k的取值在算法中显得十分重要。当k较小时样本点太少,容易受到噪声的影响。当k较大时分类精度会下降,错分的概率上升。
  根据经验,k低于训练样本数的平方根。
  
效率
  由于需要对每一个点进行全数据集的检索,本算法的效率比较低,k越大,数据量越大越是如此。当然在一些比如说数据集是一个稀疏矩阵的情况下可以改进数据存储算法,相对于暴力求解距离,可以采用kd树或者ball树来改进提高检索效率。
  

特点

  该算法属于消极学习法,是基于实例的学习。优点在于易于理解,无需建模。缺点在于花费较大,不像决策树那样可解释性不强。

实现

下面是用R的简单实现,采用暴力求解:

#KNN
#x is train data,k is the number of neighbors
#return the labels of testdata
KNN <- function(x,testdata,k) {
  nearestNeighbor <- matrix(NA,nrow = k,ncol = 3,byrow = T,
                            dimnames = list(1:k,c("index","label","distance")))
  distance<-0
  label<-0
  for(i in seq(testdata[,1])) {
    for(j in seq(x[,1])) {
        tempDistance <- sqrt(sum((testdata[i,] - x[j,-1])^2))
        distance<-c(distance,tempDistance)
    }
    distance<-distance[-1]#得到第i个记录与其他所有记录的距离
    for(g in seq(k)) {#找到最近的k个变量,按距离从小到大排列
      nearestNeighbor[g,]<-c(which.min(distance),x[which.min(distance),1],distance[which.min(distance)])
      distance<-distance[-which.min(distance)]
    }
    label<-c(label,names(which.max( table(nearestNeighbor[,2]) )))
    distance<-0
  }
  label<-label[-1]
}

参考

【1】【欧式距离与马氏距离区别】
http://blog.csdn.net/u010167269/article/details/51627338?_t_t_t=0.0028043033089488745
【2】【模式识别相似性测度距离】
http://blog.csdn.net/whu_zcj/article/details/50772750
【3】《数据挖掘导论》
【4】【kd树算法思路】
http://www.360doc.com/content/16/1003/00/36492363_595405515.shtml

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值