这一篇就来复习一下“懒惰学习”的著名代表K近邻法(K-nearest neighbor,K-NN)。
我个人认为这个学习方法的思路很容易理解,尤其是在二维空间内,将《统计学习方法》上的例题看懂就很清楚了。
题外话:在我刚学机器学习的时候经常把KNN误记成是某个神经网络,毕竟和CNN,DNN,RNN一样都有NN嘛2333
k近邻法 | |
---|---|
输入 | 实例的特征向量(对应于特征空间的点) |
输出 | 实例的类别(可以取多类) |
三个基本要素 | k值、距离度量、分类决策规则 |
k k 近邻法本质就是,对于新的输入实例,在已给定的训练数据集中找到个与该实例最近的训练实例,这 k k 个实例中哪个类占多数,就将这个新输入实例分为这个类。
【k值的选择】
若选择较小的值,相当于用较小的邻域中的训练实例进行预测。这样容易受到训练数据中噪声点的干扰,使得模型变得复杂,该模型近似误差会减小,但估计误差会增大。(过拟合)
若选择较大的 k k 值,相当于用较大的邻域中的训练实例进行预测。这样的模型可能过于简单,使得误分类测试样例,该模型估计误差会减小,但近似误差会增大。(欠拟合)
【距离度量】
近邻模型的特征空间一般是 n n 维实数向量空间,使用的距离大多是欧式距离,但也可以是其它距离,如 Minkowsk M i n k o w s k 距离( Lp L p 距离),欧氏距离实质为 Minkowsk M i n k o w s k 距离 p=2 p = 2 时的情况。
【分类决策规则】
k
k
近邻中分类决策规则往往是多数表决规则,等价于经验风险最小化。
,
v
v
是类标号
还可以用距离加权表决规则。
【 k k 近邻的实现】
(1) 最简单的实现:线性扫描———计算输入实例与每一个训练实例的距离
缺点:当训练集很大时,计算非常耗时
(2) 使用特殊结构存储训练数据:树(划分空间没有重叠)、
R
R
树(划分空间相互有重叠)
【树】
构造
kd
k
d
树
输入:
k
k
维空间数据集{
x1,x2,...,xn
x
1
,
x
2
,
.
.
.
,
x
n
},其中
xi
x
i
={
x(1)i,x(2)i,...,x(k)i
x
i
(
1
)
,
x
i
(
2
)
,
.
.
.
,
x
i
(
k
)
}
输出:
kd
k
d
树
①构造根节点:选择
x(1)
x
(
1
)
为坐标轴,以
T
T
中所有实例的坐标的中位数为切分点,将其分为两个子区域;
左子节点:对应坐标
x(1)
x
(
1
)
小于切分点的子区域
右子节点:对应坐标
x(1)
x
(
1
)
大于切分点的子区域
深度为1
②重复:对深度为
j
j
的节点,选择为切分坐标轴(
l=j(modk)+1
l
=
j
(
m
o
d
k
)
+
1
),以该节点中所有实例的
x(l)
x
(
l
)
坐标的中位数为切分点,将该节点对应的区域切分为两个子区域。
左子节点:对应坐标
x(l)
x
(
l
)
小于切分点的子区域
右子节点:对应坐标
x(l)
x
(
l
)
大于切分点的子区域
深度为j+1
搜索 kd k d 树
输入:已构造的
kd
k
d
树;目标点
x
x
输出:的最近邻
①从根节点出发,递归地向下访问
kd
k
d
树;
若目标点
x
x
当前维的坐标小于切分点,那么移向左子节点
若目标点当前维的坐标大于切分点,那么移向右子节点
直到子节点为叶节点为止,以此叶节点为”当前最近点”(实质是DFS)
②递归地向上回退,在每个节点进行以下操作;
(1)检查以目标点
x
x
与”当前最近点”间的距离为半径的超球体是否和另一子节点对应的超平面相交。
若相交,则移动到另一个子节点,递归进行最近邻搜索(重复①②)
若不相交,向上回退
在这过程中,若当前点与目标点的距离比”当前最近点”与目标点距离更近,则更新”当前最近点”为当前点
③当回退到根节点时,搜索结束,得到最近邻点。
树复杂度分析
n n 为训练实例数