k 近邻法是一种基本的分类与回归方法,其三个基本要素是k值的选择、距离度量、分类决策规则,一个实现方法是kd树。
它的基本思想是给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。当k=1
时为特殊情况,称为最近邻算法。
当三要素确定之后,对于任何一个新的输入实例,它所属的类唯一地确定。
- 距离度量: 欧氏距离,DTW距离, L p L_p Lp距离,Minkowski距离等;
- k值的选择: k值减小意味着整体模型变得复杂,易发生过拟合,增大意味着整体模型变得简单,一般取一个比较小的值,通常采用交叉验证法莱选取最优k值。
- 分类决策规则: 通常是多数表决,即由输入实例的k个邻近的训练实例中的多数类决定输入实例的类。
- k近邻法的实现 – kd树: 主要是考虑特征空间维数很大或者训练数据容量大时,用线性扫描的机制(传统方法)很耗时。
kd树构造算法:
输入:k维空间数据集T;
输出:kd树;
(1)构造根节点,它对应于包含T的k维空间的超矩形区域,选择
x
(
1
)
x^{(1)}
x(1)为坐标轴,以T中所有实例的
x
(
1
)
x^{(1)}
x(1)坐标的中位数为切分点,将根节点对应的超矩形区域切分为两个子区域,切分点由通过切分点并与坐标轴
x
(
1
)
x^{(1)}
x(1)垂直的超平面实现。并生成深度为1的左右子节点,左子节点对应坐标
x
(
1
)
x^{(1)}
x(1)小于切分点的子区域,右子节点则对应大于切分点的子区域,将落在切分超平面的实例点保存在根节点。(由于每个节点上都有一个实例,所以实际切分时并不是严格地以中位点为切分点,如果是奇数则按中位点,偶数则按照中位点右边那个实例为切分点)。
(2)重复:对深度为
j
j
j的节点,选择
x
(
l
)
x^{(l)}
x(l)为切分的坐标轴(其中,
l
=
j
(
m
o
d
k
)
+
1
l=j(mod k)+1
l=j(modk)+1),同样按上述法则生成深度为
j
+
1
j+1
j+1的左右子节点,分别代表2个子区域,并将落在切分超平面上的实例点保存在该节点上。
(3)上述操作直到左右2个子区域没有实例为止。
搜索kd树(以最近邻为例):
输入:已经构造好的kd树,目标点
x
x
x;
输出:
x
x
x的最近邻;
(1)在kd树中找到包含目标点的叶子节点;
(2)将此叶子节点的实例点设为当前最近点;
(3)递归地向上回退,在每个节点进行下述操作:
- 先判断这个新的节点上的实例点是否距离目标点更近:如果更近,则将其设为当前最近点;
- 接着判断该节点的另一子节点区域内是否会有更近的点:先判断以目标点为圆心,目标点与当前最近点为半径的点与另一子节点对应的超球体是否相交(通过判断圆心与该节点的分割超平面是否相交即可判断),相交则进入其另一子节点,继续相应的操作(也就是看其上的实例点与目标点的距离是否会更近);如果不相交,则不需要进入另一子节点,而是继续向上回溯。
(4)当回溯到根节点时,则搜索结束,最后的“当前最近点”则为最邻近点。