k近邻算法简单、直观:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例 最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类. 下面先叙述k近邻算法,然后再讨论其细节.
输入:
(1) 训练样本集 D = {(xi, yi), i = 1, 2, …, N}
其中 xi 为第i个训练样本的特征向量, yi ∈ Y = {c1, c2, …, ck} 为实例的类别标号
(2) 观测样本x
输出: 测样本 x 所属的类别 y.
STEP0. 训练集 D 的输入部分预处理,并记录预处理的使用参数
STEP1. 指定 距离度量,并 选择K值
STEP2. 训练集D内找到预处理的样本 x 的 前K个近邻 ,记为 Nk(x):
Nk(x) = Nk,1(x) ∪…∪Nk,c(x)
Nk,i(x)-------x的前K个近邻中,属于第i类的部分
STEP3. 结合指定的 分类规则, 对 x 的类别y 进行预测:
k近邻法使用的模型实际上对应于对特征空间的划分.模型由三个基本要素—— 距离度量、k值的选择和分类决策规则 决定,
特征空间中两个实例点的距离是两个实例点相似程度的反映. k近邻模型的特征空间一般是n维实数向量空间Rn .使用的距离是 欧氏距离,但也可以是其他距离,如更一般的 Lp距离(Ip distance) 或 Minkowski距离(Minkowski distance).
设特征空间 X 是n维实数向量空间Rn,xi,xj∈ X,xi = (xi1, xi2, …, xin),xj = (xj1, xj2, …, xjn),xi,xj的 Lp距离定义为:
这里p ≥ 1. 当p = 2时,称为 欧氏距离(Euclidean distance), 即
当p=1时,称为 曼哈顿距离(Mahattan distance),即
当p = ∞时,它是 各个坐标距离的最大值,即
下图给出了二维空间中 p 取不同值时,与原点的Lp距离为1 (Lp = 1) 的点的图形.
下面的例子说明,由不同的距离度量所确定的最近邻点是不同的.
例3.1 已知二维空间的3个点x1 = (1, 1) ,x2 = (5, 1), x3 = (4, 4),试求在p取不同值时,Lp 距离下 x1 的最近邻点.
解: 因为 x1 和 x2 只有第二维上值不同,所以p为任何值时,Lp(x1, x2) = 4. 而
L1(x1, x3) = 6,L2(x1, x3) = 4.24, L3(x1, x3) = 3.78, L4(x, x) = 3.57
于是得到: p等于1或2时,x2是 x1 的最近邻点: p大于等于3时,x3 是 x1 的最近邻点.
k值的选择会对k近邻法的结果产生重大影响.
如果选择 较小的k值,就相当于用较小的邻域中的训练实例进行预测,“学习”的近似误差(approximation error)会减小,只有与输入实例较近的(相似的)训练实例才会对预测结果起作用.但 缺点是“学习”的估计误差(estimation error)会增大,预测结果会对近邻的实例点非常敏感.如果邻近的实例点恰巧是噪声,预测就会出错.换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合.
如果选择 较大的k值,就相当于用较大邻域中的训练实例进行预测. 其优点是可以减少学习的估计误差.但缺点是学习的近似误差会增大.这时与输入实例较远的(不相似的)训练实例也会对预测起作用,使预测发生错误. k 值的增大就意味着整体的模型变得简单.
如果k=N,那么无论输入实例是什么,都将简单地预测它属于在训练实例中最多的类.这时,模型过于简单,完全忽略训练实例中的大量有用信息,是不可取的.
在应用中,k值一般取一个比较小的数值.通常采用 交叉验证法 来选取最优的k值.
以单轮 m-fold cross validation为例:
STEP1. 训练集随机打乱,均分成 m 等份,每一份的训练样本数目 N/m.
STEP2. 对于每个备选 K值.
1). for i =1, …, m do
拿出第 i 份作为 验证集,其余m - 1份构成 估计集
利用 估计集,对 验证集的每个样本进行类别预测,得 预测错误率 Erri(K)
表示为 μErr(k) ± σErr(k)
STEP3. 取最小μErr(k)对应的K值 为最终的选择结果;
若 同时有多个k值最小的μErr(k),则取 较小σErr(k)对应的K值
k近邻法中的分类决策规则往往是 多数表决,即由输入实例的k个邻近的训练实例中的多数类决定输入实例的类.
多数表决规则(majority voting rule) 有如下解释: 如果分类的损失函数为 0-1 损失函数,分类函数为:
对给定的实例x∈X, 其最近邻的 k 个训练实例点构成集合 Nk(x) 如果涵盖 Nk(x) 的区域的类别是cj,那么误分类率是:
所以多数表决规则等价于 经验风险最小化.
观测 x 的 K个近邻: Nk(x) = Nk,1(x)∪…∪NK,C(x)
实现k近邻法时,主要考虑的问题是如何对训练数据进行 快速k近邻搜索.这点在特征空间的维数大及训练数据容量大时尤其必要.
k近邻法最简单的实现方法是 线性扫描(linear scan).这时要计算输入实例与每一个训练实例的距离.当训练集很大时,计算非常耗时,这种方法是不可行的.为了提高k近邻搜索的效率,可以考虑使用特殊的 结构存储训练数据,以减少计算距离的次数.具体方法很多,下面介绍其中的 kd树(kd tree)方法”.
kd树是一种 对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构. kd 树是 二叉树,表示对k维空间的一个划分(paritin). 构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域,kd 树的每个结点对应于一个k维超矩形区域.
构造kd树的方法如下: 构造根结点,使根结点对应于 k 维空间中包含所有实例点的超矩形区域;通过下面的递归方法,不断地对k维空间进行切分,生成子结点.在超矩形区域(结点),上选择一个坐标轴和在此坐标轴上的一个切分点,确定一个超平面, 这个超平面通过选定的切分点并垂直于选定的坐标轴,将当前超矩形区域 切分为左右两个子区域(子结点); 这时,实例被分到两个子区域.这个过程 直到子区域内没有实例时终止(终止时的结点为叶结点).在此过程中,将实例保存在相应的结点上。
通常,依次选择坐标轴对空间切分,选择训练实例点在选定坐标轴上的 中位数(median)为切分点,这样得到的kd树是平衡的. 注意,平衡的kd树搜索时的效率 未必是最优的.
(1)开始: 构造根结点,根结点对应于包含T的k维空间的超矩形区域.
选择 x 为坐标轴,以T中所有实例的 x 坐标的中位数为切分点,将根结点对应的超矩形区域切分为两个子区域.切分由通过切分点并与坐标轴 x 垂直的超平面实现.
由根结点生成深度为1的左、右子结点: 左子结点对应坐标 x 小于切分点的子区域,右子结点对应于坐标 x 大于切分点的子区域.
将落在切分超平面上的实例点保存在 根结点.
(2)重复:对深度为 j 的结点,选择 xL 为切分的坐标轴,L= j(modk)+1,以该结点的区域中所有实例的 x 坐标的 中位数为切分点,将该结点对应的超矩形区域切分为两个子区域。切分由通过切分点并与坐标轴 xL 垂直的超平面实现.
由该结点生成深度为j+1的左、右子结点:左子结点对应坐标x(小于切分点的子区域,右子结点对应坐标x(I)大于切分点的子区域.
将落在切分超平面上的实例点保存在该结点.
(3)直到两个子区域没有实例存在时停止,从而形成kd树的区域划分.
下面介绍如何利用 kd 树进行 k近邻搜索.可以看到,利用kd树可以省去对大部分数据点的搜索,从而减少搜索的计算量.这里以最近邻为例加以叙述,同样的方法可以应用到k近邻。给定一个目标点,搜索其最近邻。首先找到包含目标点的叶结点;然后从该叶结点出发,依次回退到父结点;不断查找与目标点最邻近的结点,当确定不可能存在更近的结点时终止。 这样搜索就被限制在空间的局部区域上,效率大为提高.
包含目标点的叶结点对应包含目标点的最小超矩形区域。以此叶结点的实例点作为当前最近点,目标点的最近邻一定在以目标点为中心并通过当前最近点的超球体的内部。然后返回当前结点的父结点,如果父结点的另一子结点的超矩形区域与超球体相交,那么在相交的区域内寻找与目标点更近的实例点。如果存在这样的点,将此点作为新的当前最近点,算法转到更上一级 的父结点,继续上述过程。如果父结点的另一子结 点的超矩形区域与超球体不相交,或不存在比当前最近点更近的点,则停止搜索.
下面叙述用kd树的最近邻搜索算法:
算法3.3(用kd树的最近邻搜索)
输入:已构造的kd树,目标点 x;
输出:x 的最近邻。
如果实例点是随机分布的,kd树搜索的 平均计算复杂度是0(logN), 这里N是训练实例数. kd 树更适用于训练实例数远大于空间维数时的k近邻搜索.当空间维数接近训练实例数时,它的效率会迅速下降,几乎接近线性扫描.