KNN
Representation
给定一个训练数据集,对新的输入实例,在训练数据集中找出与这个新实例最近的k个训练实例,然后统计最近的k个训练实例中所属类别计数最多的那个类。
根据给定的距离度量(如欧式距离),在训练集T中找出与x距离最近的k个点,并把涵盖这些点的领域记为Nk(x),根据决策规则(如多数表决)得到类别y。记住remember该模型公式。
y=argmaxcj∑xi∈Nk(x)I(yi=cj), i=1,2,…,N; j=1,2,…,K
其中训练集T={(x1,y1),(x2,y2),…,(xn,yn)};实例yi的类别为{c1,c2,…,cK};待分类样本x;设定好的最近邻个数k。
一般k会取一个较小的值,然后用过交叉验证来确定。这里所谓的交叉验证就是将样本划分一部分出来为预测样本,比如95%训练,5%预测,然后k分别取1,2,3,4,5之类的,进行预测,计算最后的分类误差,选择误差最小的k。
距离的度量(常见的距离度量有欧式距离,马氏距离等)。
k近邻法没有显示的学习过程。
Evalution
k近邻法中的分类决策规则往往是多数表决,等价于经验风险最小化。记住remember此策略。
Optimization
KD树(K-dimensional tree)即K维树:考虑这样的问题, 给定一个数据集D和某个点x,找出与x距离最近的k个点。这是一类很常见的问题,最简单的方法是暴力搜索,直接线性搜索所有数据,直到找到这k个点为止。对少量数据而言,这种方法还不错,但对大量、高纬度的数据集来说,这种方法的效率就差了。我们知道,排序好的数据查找起来效率很高,所以,可以利用某种规则把已有的数据“排列”起来,再按某种特定的搜索算法(通过KD树的搜索找到与搜索目标最近的k个点,这样KNN的搜索就可以被限制在空间的局部区域上了,可以大大增加效率。),以达到高效搜索的目的,记住rememberkd树思想。
数据集T=(x1,x2,…,xn),其中xi=(a1,a2,…,ak)。
构造KD树
(记住remember三点即可:下面的维度选择公式、划分是对当前区域内的实例点、实例保存在该节点)
开始构造根节点,根节点对应包含数据集的k维空间超矩形区域
选择a1作为坐标轴,以数据集中所有实例的a1坐标的中位数作为切分点,将根节点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴a1垂直的超平面实现;由根节点生成深度为1的左右子节点,左子节点对应坐标a1小于切分点的子区域,右子节点对应坐标a1大于切分点的子区域。将落在切分超平面上的实例点保存在根节点。
重复:对于深度为j的节点,为了生成j+1节点,选择al作为切分的坐标轴,l=j(mod k)+1,以该节点区域中所有实例的al坐标的中位数为切分点,将该节点对应的超巨型区域分为两个子区域,切分有通过切分点并与坐标轴al垂直的超平面实现。将落在切分超平面上的实例点保存在该节点。
直到两个子区域没有实例存在时停止。
例子:有6个二维数据点:{(2,3),(5,4),(9,6),(4,7),(8,1),(7,2)}。

搜索KD树(J知道是先找到包含目标点的叶节点,然后逐步回撤回去,找更新点;找到就往上回到更上一级父节点)
首先从根节点开始递归往下找到包含目标点的叶子节点。
将这个叶子节点认为是当前的“近似最近点”。
递归向上回退,如果以目标点圆心,以“近似最近点”为半径的球与根节点的另一半子区域边界相交,那么在相交的区域内寻找与目标点更近的实例点,如果存在这样的点,将此点作为新的”近似最近点“,算法找到更上一级的父节点。
重复3的步骤,直到另一子区域与球体不相交或者不存在比当前最近点更近的点。
最后更新的”近似最近点“是与目标点真正的最近点。

Code
Reference
Last updated