K近邻法的一些浅见
初次接触K近邻法,想对K近邻法的主要思想,k值选择,kd树(K近邻的实现)这些要点做一个整理,并写上自己的一些理解。若有错误,欢迎指正。
K近邻算法主要思想
K近邻算法主要步骤有二:
- 根据给定的距离度量(Lp,当p=2时为欧式距离,p=1时为曼哈顿距离,p为无穷时,是各个坐标距离的最大值),在训练集T中找出与特征向量x最邻近的k个点,得到x的邻域;
- 在邻域中根据分类决策规则(如多数表决argmax)决定x的类别y。
k值选择
k值较小,所分区域增多,模型会变得复杂,在训练集上的表现会很好,但容易过拟合,近似误差小,估计误差大。k值较大,在训练集上方差较大,收敛速度慢,但在测试时由于对于邻域内个别噪声数据不那么敏感,估计误差会比较小。
kd树
考虑到测试数据时,如果使用线性扫描来进行分类,也就是计算测试实例与每个训练实例之间的距离,再判断所属分类,会产生十分大的花费,我们可以选择更好的方法来分类测试实例,也就是kd树。为了提高效率,往往使用平衡kd树。
平衡kd树的思想与平衡树十分相像,实际上是通过不断切分特征空间来构建平衡树的。开始时,平衡树的根节点就是包含训练集的n维特征空间的超矩形区域。利用模型来表示高维空间较为抽象,我们姑且把它看作有n个维度的多维空间。以训练集向量中第一维的中位数进行切割,我们可以得到两个子区域。在这两个子区域中,根据各个区域中实例向量中第二维度的中位数分别进行切割,可以得到四个子区域。重复如上步骤,如果进行n维度切割后,仍有训练集中实例未被分割,则回归一维度切割,直至两个子区域中无实例存在。
kd树的搜索与普通二叉树的搜索一致,通过依次比较维度实现,可以根据kd树的层数与维度取余得到当前是根据第几维度切割的。在搜索得到叶子结点为当前最近点之后,使用回溯法不断更新当前最近点,回溯直至根节点结束。它的平均计算复杂度是O(logN),N为实例数,由此可见实例数相比空间维度较大时,对复杂度的影响很小,但若实例数与空间维度数接近时,则与线性扫描基本无异。
暂且就写这么多,日后有新的理解,会回来补充。