k近邻的最简单实现方法是线性扫描,有时也称为蛮力实现,其通过计算新的输入实例与每一个训练实例的距离,然后找出最小距离的k个实例点,紧接着根据决策规则进行预测.当训练集很小时,这种方法显得有效;而当样本量很大时,计算量也随之增大,这将非常耗时.
为了提高k近邻的搜索效率,可以考虑将训练数据使用某种结构进行存储起来,进而减少计算距离的次数,这样的方法有:kd树,球形树,BBF树,MVP树等.下面只介绍其中的kd树.
一. kd树
kd树是二叉树,表示对k维空间的一个划分 (也就是说这里的k是指维数). 其实现过程分为两大步骤:构造和搜索.
1. 构造kd树
过程大致描述为: 构造根结点(根结点对应的是k维空间中包含所有实例点的超矩形区域),在超矩形区域上选择一个坐标轴和此坐标轴上的一个切分点,通过一个超平面(该超平面通过选定的切分点并垂直于选定的坐标轴)将当前超矩形区域切分为左右两个子区域(也称为子结点), 这时,实例被分到两个子区域.不断地重复切分过程直到子区域内没有实例时终止,终止时的结点称为叶结点.
2. 搜索kd树
给定一个目标点,搜索其最近邻,其大致过程描述为:
首先找到包含目标点的叶结点(即包含目标点的最小超矩形区域),然后从该叶结点出发,依次退回到父结点,不断地查找与目标点最邻近的结点,当确定不可能存在更近的结点时终止,这样就可以将搜索限制在局部区域上,进而提高搜索效率.
对于搜索k近邻的过程,大致可以总结为以下几步:
1)寻找包含目标结点的叶结点
从根结点出发,若目标点当前维的坐标小于切分点的坐标,则移动到左子结点,否则移动到右子结点.直到向下访问到叶结点为止.
2)选择好的叶结点作为当前最近点
3)从叶结点向根结点退回,在每个结点进行以下操作:
a. 如果该结点中包含比当前最近点距离目标点更近的实例点时,以该实例点作为当前最近点.
b. 检查另一子结点对应的区域是否与"以目标点为球心,以目标点与当前最近点的距离为半径"的球体相交.若相交,则移动到另一子结点,搜索更近的实例点;若不相交,则继续向根结点退回.
4)当退回到根结点时,第一轮搜索结束,最终选择的当前最近点即为最近邻点,并将当前最近点从根结点中移动到近邻点集合中.
5)通过以上搜索得到第一近邻点,重复上述步骤k-1次,最终将得到k个近邻点.
2. 预测
如果是分类问题,归纳为k个近邻点中最多数的那个类别;如果是回归问题,用k个最近邻点输出的平均值作为预测值.
参考:
李航博士著<统计学习方法>
网友评论