引言
k近邻算法(k-Nearest Neighbor,简称kNN):给定一个训练数据集,对于新的输入实例,在训练数据集中找到与该实例最接近的kkk个实例,通过这kkk个实例投票决定该输入实例的类别。
k近邻算法
输入: 训练集T={(x1,y1),(x2,y2),...,(xN,yN)}T=\{(x_1,y_1),(x_2,y_2),...,(x_N,y_N)\}T={(x1,y1),(x2,y2),...,(xN,yN)}
输出: 实例xxx所对应的类别yyy
- 根据给定的距离度量方式,在训练数据集中找到距离输入样例xxx最近的kkk个点,将包含这kkk个点的xxx邻域记作Nk(x)N_k(x)Nk(x)
- 在Nk(x)N_k(x)Nk(x)中根据分类决策规则(如多数表决)将xxx划分到某个类别yyy
特殊地,当kkk等于1时,相当于将输入实例xxx划分到训练数据集中与xxx距离最近点所属的类别。
k近邻模型
唯一确定一个k近邻模型由三方面构成:距离度量方式、k值的选取和分类决策规则。
一、距离度量方式
我们用两个点的距离远近来度量它们的相似程度,kkk近邻模型的特征空间是nnn维实数向量空间RnR^nRn,我们常使用欧式距离来衡量两个点的距离,但也可以是更一般的LpL_pLp距离:
Lp(xi,xj)=(∑i=1N(∣xi(l)−xj(l)∣p))1p L_p(x_i,x_j)=(\sum_{i=1}^{N}(|x_i^{(l)}-x_j^{(l)}|^p))^{\frac{1}{p}} Lp(xi,xj)=(i=1∑N(∣xi(l)−xj(l)∣p))p1
二、k值的选择
当选取的kkk值较小时,相当于用较小邻域的训练实例进行预测,更容易受噪声干扰(比如邻近的实例点恰好是噪声就会出错),即kkk越小则模型过拟合的风险越大。
当选取的kkk较大时,相当于用较小邻域的训练实例进行预测,这时候与输入实例较远(相似度较小)的训练实例也会对预测产生影响,从而降低模型准确率。
特别的,kkk等于1时相当于用离输入样例xxx最近的训练实例做预测;kkk等于NNN时无论输入实例是什么,都简单地用训练实例中样本数最多的类别作为预测类别。
在应用中,kkk值在比较小的数值范围内取,并且结合交叉验证方法确定最优kkk值。
三、分类决策规则
kkk近邻方法中的分类决策规则往往是多数表决,即由输入实例的kkk个邻近实例中的多数类作为预测类别。
套用监督学习中的损失函数和风险函数知识,多数表决规则等价于经验风险最小化,推导如下:
给定输入实例xxx,其邻近kkk个训练实例构成集合Nk(x)N_k(x)Nk(x),如果涵盖Nk(x)N_k(x)Nk(x)区域的类别是cjc_jcj,那么误分类率为:
1k∑xi∈Nk(x)I(yi!=cj)=1−1k∑xi∈Nk(x)I(yi=cj)
\frac{1}{k}\sum_{x_i\in N_k(x)}I(y_i!=c_j)=1-\frac{1}{k}\sum_{x_i\in N_k(x)}I(y_i=c_j)
k1xi∈Nk(x)∑I(yi!=cj)=1−k1xi∈Nk(x)∑I(yi=cj)
要令误分类率即经验风险最小,相当于最大化∑xi∈Nk(x)I(yi=cj)\sum_{x_i\in N_k(x)}I(y_i=c_j)∑xi∈Nk(x)I(yi=cj),也就是多数表决。因此在kkk近邻中多数表决规则等价于经验风险最小化。
kd树
当训练集很大时,计算输入实例和每一个训练实例的距离相当耗时。为了提高kkk近邻搜索的效率,我们使用特殊的结构存储训练数据来减少计算距离的次数,比如kdkdkd树方法。
kdkdkd树(k-dimension tree)是一种对kkk维空间中的实例点进行存储以便对其进行快速检索的二叉树形数据结构。构造kdkdkd树相当于不断用垂直于坐标轴的超平面将kkk维空间切分,构成一系列的kkk维超矩形区域,kdkdkd树上的每一个结点对应于一个kkk维超矩形区域。该超矩形区域垂直于当前划分维度的坐标轴,并在该维度上将空间划分为两部分。
一、构造kd树
输入: kkk维空间数据集T=x1,x2,...,xNT={x_1,x_2,...,x_N}T=x1,x2,...,xN,其中xi=(xi(1),xi(2),...,xi(k))Tx_i=(x_i^{(1)},x_i^{(2)},...,x_i^{(k)})^Txi=(xi(1),xi(2),...,xi(k))T
输出:kdkdkd树
- 构造对应包含TTT的kkk维空间的超矩形区域:以x(1)x^{(1)}x(1)为坐标轴,TTT中所有实例的x(1)x^{(1)}x(1)坐标的中位数为切分点将超矩形区域划分为两个子区域。此步生成深度为1的左、右结点:左子结点对应坐标x(1)x^{(1)}x(1)小于切分点的子区域,右子结点对应于坐标x(1)x^{(1)}x(1)大于切分点的子区域。正好落在划分超平面上的实例点保存在根结点。
- 同样地,对深度为jjj的结点,选择x(l)x^{(l)}x(l)为切分的坐标轴(l=j(modk)+1l=j(mod\quad k)+1l=j(modk)+1,因为可能存在对同个维度进行多次划分),以该结点的区域中所有实例的x(1)x^{(1)}x(1)坐标的中位数为切分点划分结点对应的超矩形区域。
- 直到两个子区域没有实例存在时停止
注意到没,kdkdkd树的思想和二分法很像,并且都能提高搜索的效率。
二、搜索kd树
注意kdkdkd树中的kkk指特征维度数,但kkk近邻算法中的kkk表示最邻近的kkk个点。
搜索方法如下:
输入: 已知的kdkdkd树,目标点xxx
输出: xxx的最近邻
- 先找到kdkdkd树中包含目标点xxx的叶结点(即包含输入样例的超矩形区域):从根结点出发,递归地向下访问直到子结点为叶结点
- 以该叶结点为“当前最近点”
- 在该叶子结点递归回退,在每个结点进行如下操作:
- 如果该结点保存的实例点比“当前最近点”更距离目标点更近,则以该实例点为“当前最近点”
- 当前最近点一定存在于该结点一个子结点对应的区域。检查该子结点的父结点的另一子结点对应的区域是否有更近的点。(即检查另一子结点对应的区域是否与该目标点为球心,以目标点与“当前最近点”间的距离为半径的超球体相交)
- 如果相交,可能在另一个子结点对应的区域内存在距目标点更近的点,移动到另一个子结点,接着,递归地进行最近邻搜索
- 如果不相交,向上回退
- 当回退到根结点时,搜索结束,最后的“当前最近点”即为xxx的最近邻点。
需要注意的点
- 如果实例点是随机分布的,那么kdkdkd树的平均计算复杂度是O(logN)O(logN)O(logN)
- kdkdkd树更适用于训练实例数远大于空间维数的kkk近邻搜索,当空间维数接近训练实例数时,它的效率会迅速下降,几乎接近于线性扫描(即挨个计算训练数据集每个点和输入样例的距离)
- kkk近邻算法既能用于分类,也能用于回归,比较简单的回归就是用kkk近邻点的平均值来预测输入样例的预测值。
- kkk近邻模型由三个因素决定:距离度量方法、kkk值选取和分类决策规则
参考
李航 《统计学习方法》