hit2015spring晨凫追风\frac{hit2015spring}{晨凫追风}

欢迎关注我的博客:http://blog.csdn.NET/hit2015spring

k近邻算法

是一种常用的监督学习的方法:给定测试样本,基于某种距离度量找出训练集中与其最靠近的k个训练样本,然后基于k个邻居的信息来进行预测。通常:

分类任务中用投票,选择k个样本中出现最多的类别标记作为预测结果
回归任务中:平均法
还可以基于距离的远近进行加权平均或者加权投票,距离越近权重越大

没有显示的训练过程,训练时间开销为0,是一种懒惰学习

分类的结果与k的选择距离计算方式的选择有关系

上图可以看出二维空间中,距离的计算方式不同,包含的区域也是不相同的。故会影响结果

k值得选择也会对结果产生影响,k值小的话,相当于用较小的邻域中的训练实例进行预测,学习的近似误差会减小,只有与输入实例较近的训练实例才会对预测结果起作用,但是估计误差会增大,意味着会产生过拟合。

kd树的构建

实现k近邻方法时,面临一个计算速度的挑战问题,当特征空间的维数非常大以及训练数据非常大的时候,我们优化这个搜索的方法就显得尤为重要了

一般方法:最简单的是实现一个线性扫描,就是计算输入的实例与每一个训练实例之间的距离,训练集很大的时候,计算会耗时很长,于是就出现了kd树的这种方法。

构造kd树的数学描述比较难懂:

输入的是kk维空间数据集T={x1,x2,⋯,xN}T=\{x_1,x_2,\cdots,x_N\},注意这里的k维指的是特征的维度是k维,即xi=(x(1)i,x(2)i,⋯,x(k)i),i=1,2,⋯,Nx_i = (x_i^{(1)},x_i^{(2)},\cdots,x_i^{(k)}),\qquad i = 1,2,\cdots,N

(1)开始:构造根结点,根结点对应于包含TT的kk维空间的超矩形区域.选择x(1)x^{(1)}为坐标轴,以TT中所有的实例的x(1)x^{(1)}坐标的中位数为切分点,将根结点对应的超矩形区域划分为两个子区域。切分由通过切分点并与坐标轴x(1)x^{(1)}垂直的超平面实现。

由根结点生成深度为1的左右两个子结点:左结点对应坐标x(1)x^{(1)}小于切分点的子区域,右结点对应于坐标x(1)x^{(1)}大于切分点的子区域,落在切分超平面的点保存在根结点

(2)重复:对深度为j的结点,选择x(l)x^{(l)}为切分的坐标轴,以该结点的区域内部所有的实例的x(l)x^{(l)}坐标的中位数作为切分点,将该结点对应的矩形区域切分为两个子区域。切分由通过切分点并与坐标轴x(l)x^{(l)}垂直的超平面实现。
该结点生成左右两个结点,左结点对应坐标x(l)x^{(l)}小于切分点的子区域,右子结点对应坐标x(l)x^{(l)}大于切分点的子区域。落在切分超平面上的实例点保存在该结点。

(3)直到两个子区域没有实例存在时停止。

直接通过一个例子来理解:

简单的理解就是:每次选择一个维度的特征,把该实例点划分为两个部分,一个大于中位数,一个小于中位数,中位数就保留在这个结点,其他的放到下一层中,继续上面的过程。

当然了这里面的关键是怎么选取要切分那个维度呢?

最简单的方法就是轮着来,即如果这次选择了在第i维上进行数据划分,那下一次就在第j(j≠i)维上进行划分,例如:j = (i mod k) + 1。想象一下我们切豆腐时,先是竖着切一刀,切成两半后,再横着来一刀,就得到了很小的方块豆腐。

可是“轮着来”的方法是否可以很好地解决问题呢?再次想象一下,我们现在要切 的是一根木条,按照“轮着来”的方法先是竖着切一刀,木条一分为二,干净利落,接下来就是再横着切一刀,这个时候就有点考验刀法了,如果木条的直径(横截 面)较大,还可以下手,如果直径较小,就没法往下切了。因此,如果K维数据的分布像上面的豆腐一样,“轮着来”的切分方法是可以奏效,但是如果K维度上数 据的分布像木条一样,“轮着来”就不好用了。因此,还需要想想其他的切法。

如果一个K维数据集合的分布像木条一样,那就是说明这K维数据在木条较长方向 代表的维度上,这些数据的分布散得比较开,数学上来说,就是这些数据在该维度上的方差(invariance)比较大,换句话说,正因为这些数据在该维度 上分散的比较开,我们就更容易在这个维度上将它们划分开,因此,这就引出了我们选择维度的另一种方法:最大方差法(max invarince),即每次我们选择维度进行划分时,都选择具有最大方差维度。

最后再给一个例子看看:

运用kd树查找

构建好了kd树之后就是利用kd树来进行最近邻查找了:

(1)将查询数据Q从根结点开始,按照Q与各个结点比较的结果向下访问kd树,直到查找到叶子结点。

就是把Q的k个特征,在每一个结点上面的维度k与对应的分割的值m(那个中位数)这样向下走,就到了一个叶子结点,把Q与结点上面的数据进行计算距离,记做当前的最近邻点P_point和最小距离P_dist。

(2)进行回溯操作,这个操作是为了找到离Q点更加近的最近邻点。即判断没有被访问的分支里面的点是否还具有更近的点。

如果Q与其父结点下的未被访问过的分支之间的距离小于Dcur,则认为该分支中存在离P更近的数据,进入该结点,进行(1)步骤一样的查找过程,如果找到更近的数据点,则更新为当前的“最近邻点”Pcur,并更新Dcur

怎样判断未被访问的树的分支里面是否有离Q更近的点?

从几何空间上来看,就是判断以Q为中心center和以Dcur为半径Radius的超球面(Hypersphere)与树分支Branch代表的超矩形(Hyperrectangle)之间是否相交。

在实现中,在构造树的过程中,记录下每个子树所在的分割维度k和分割值m,(k, m),Q与子树的距离则为|Q(k) - m|。即这个距离和当前存的最小距离相比较,如果有比这个距离小,那就进去搜索,如果没有那就往上面回溯。

就是理解为超球体和超平面是否相交

以上就是Kd-tree的构造过程和基于Kd-Tree的最近邻查找过程。

下面用一个简单的例子来演示基于Kd-Tree的最近邻查找的过程。

数据点集合:(2,3), (4,7), (5,4), (9,6), (8,1), (7,2) 。

已建好的Kd-Tree:

假设我们的k-d tree就是上面通过样本集{(2,3), (5,4), (9,6), (4,7), (8,1), (7,2)}创建的。
我们来查找点(2.1,3.1),在(7,2)点测试到达(5,4),在(5,4)点测试到达(2,3),然后search_path中的结点为<(7,2), (5,4), (2,3)>,从search_path中取出(2,3)作为当前最佳结点nearest, dist为0.141;
然后回溯至(5,4),以(2.1,3.1)为圆心,以dist=0.141为半径画一个圆,并不和超平面y=4相交,如下图,所以不必跳到结点(5,4)的右子空间去搜索,因为右子空间中不可能有更近样本点了。
于是在回溯至(7,2),同理,以(2.1,3.1)为圆心,以dist=0.141为半径画一个圆并不和超平面x=7相交,所以也不用跳到结点(7,2)的右子空间去搜索。
至此,search_path为空,结束整个搜索,返回nearest(2,3)作为(2.1,3.1)的最近邻点,最近距离为0.141。

参考文章
参考文章

福利答谢大家!

感谢您阅读本篇文章,对此特别发放一个无门槛的现金红包,打开支付宝扫码领取!

k近邻算法与kd树的创建和搜索相关推荐

  1. K近邻算法的kd树实现

    k近邻算法的介绍 k近邻算法是一种基本的分类和回归方法,这里只实现分类的k近邻算法. k近邻算法的输入为实例的特征向量,对应特征空间的点:输出为实例的类别,可以取多类. k近邻算法不具有显式的学习过程 ...

  2. K近邻算法和KD树详细介绍及其原理详解

    相关文章 K近邻算法和KD树详细介绍及其原理详解 朴素贝叶斯算法和拉普拉斯平滑详细介绍及其原理详解 决策树算法和CART决策树算法详细介绍及其原理详解 线性回归算法和逻辑斯谛回归算法详细介绍及其原理详 ...

  3. (平衡)kd树的创建与搜索

    普通kd树的创建 算法逻辑 我们采用面向对象编程的方法.通过关键字class创建一个名为kdTree的类,在类kdTree中定义一些属性与方法(可以理解成c语言中的函数). #面向对象编程 class ...

  4. K近邻法之kd树及其Python实现

    作为机器学习中一种基本的分类方法,K近邻(KNN)法是一种相对简单的方法.其中一个理由是K近邻法不需要对训练集进行学习.然而,不需要对训练集进行学习,反过来也会造成对测试集进行判定时,计算与空间复杂度 ...

  5. 统计学习笔记(3)——k近邻法与kd树

    在使用k近邻法进行分类时,对新的实例,根据其k个最近邻的训练实例的类别,通过多数表决的方式进行预测.由于k近邻模型的特征空间一般是n维实数向量,所以距离的计算通常采用的是欧式距离.关键的是k值的选取, ...

  6. 《统计学习方法》—— k近邻方法、kd树以及python3实现

    前言 k近邻方法的初衷很简单,就是找最近的k个数据,根据这些数据的标记,按照某种规则,给新的数据标记.这里,我们可以看到三个重点:k值,距离度量和决策规则. k值决定方法的复杂程度.考虑k很大,足以包 ...

  7. 从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    原文出自:http://blog.csdn.net/v_JULY_v/article/details/8203674 前言 前两日,在微博上说:"到今天为止,我至少亏欠了3篇文章待写:1.K ...

  8. 【转】从K近邻算法、距离度量谈到KD树、SIFT+BBF算法

    最近在看<统计学习方法>,发现这么一篇好文章,与大家分享 转自:http://blog.csdn.net/v_july_v/article/details/8203674?reload 前 ...

  9. 机器学习算法系列之K近邻算法

    本系列机器学习的文章打算从机器学习算法的一些理论知识.python实现该算法和调一些该算法的相应包来实现. 目录 K近邻算法 一.K近邻算法原理 k近邻算法 通俗解释 近邻距离的度量 k值的选择 KN ...

  10. C++实现的简单k近邻算法(K-Nearest-Neighbour,K-NN)

    C++实现的简单的K近邻算法(K-Nearest Neighbor,K-NN) 前一段时间学习了K近邻算法,对K近邻算法有了一个初步的了解,也存在一定的问题,下面我来简单介绍一下K近邻算法.本博客将从 ...

最新文章

  1. Anaconda中pytorch环境搭建(包括详细的虚拟环境创建,以及虚拟环境中jupyter notebook的使用)
  2. 秒懂QPS、TPS、PV、UV、GMV、IP、RPS!
  3. WinAPI: PtInRect - 判断点是否在矩形中
  4. FPGA基础知识极简教程(8)详解三态缓冲器
  5. 安装gcc 4.8.2 for cxx 11
  6. 为不同目录设置Forms身份验证
  7. JEECG第17期架构培训班15号开班啦!每期十个名额,想报名的抓紧时间啦!
  8. System.Net.Mail和System.Web.Mail
  9. 机器学习(三)k均值聚类
  10. 宝塔反代默认缓存了html吗,宝塔面板安装 OneList 设置反代
  11. Elasticsearch模块功能之-索引分片分配(Index shard allocation)
  12. 随手记_英语_学术写作
  13. idea 创建项目并同步到git仓库
  14. Spring 揭秘 12.1
  15. win10 如何启用虚拟化 Hyper-V
  16. WEKA( OneR,过拟合)
  17. SWUST OJ 299: 平方和
  18. windows7 VCP安装失败的解决办法
  19. windows内码、外码、字符映射表
  20. 分享16个Python接单平台,做私活爽歪歪!(附100个爬虫源码)

热门文章

  1. 【文摘】2008年度_Atom处理器
  2. Ubuntu 安装netstat网络工具
  3. JavaScript 根据身份证号获取年龄
  4. C# WinForm 功能代码备忘-刘欣
  5. openlayers中海图的加载
  6. hdu1879继续畅通工程(最小生成树kru算法)
  7. Shader Reflection Probe 获取图像
  8. AngularJS总结
  9. 【AI SoC】全志R329 高算力低功耗,当下智能音箱的最优解?
  10. 计算机类专业哪些专业比较好,计算机类专业有哪些 哪个专业比较好