K近邻

一、模型

1.1概念

 k-近邻算法是一种基本分类与回归方法,我们这里只讨论分类问题中的 k-近邻算法。k-近邻算法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,可以取多类。给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k的实例,这k个实例的多数属于某个类,就把该输入实例归为此类。k=1时,为最邻近算法。

由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。

1.2算法描述

训练集T={(x1,y1),(x2,y2),⋯,(xN,yN)}T={(x1,y1),(x2,y2),⋯,(xN,yN)},其类别yi∈{c1,c2⋯,cK},训练集中样本点数为N,类别数为K。输入待预测数据x,则预测类别y

其中,涵盖x的k邻域记作Nk(x),当yi=cj时指示函数I=1,否则I=0。

1.3k近邻法优缺点

优点:精度高、对异常值不敏感、无数据输入假定

缺点:计算复杂度高、空间复杂度好,适用数据范围:数值型和标称型

1.4KNN算法思想

1 计算已知类别中数据集的点与当前点的距离。[即计算所有样本点跟待分类样本之间的距离]

2 按照距离递增次序排序。[计算完样本距离进行排序]

选取与当前点距离最小的k个点。[选取距离样本最近的k个点]

4 确定前k个点所在类别的出现频率。[针对这k个点,统计下各个类别分别有多少个]

5 返回前k个点出现频率最高的类别作为当前点的预测分类。[k个点中某个类别最多,就将样本划归改点

二、三要素

K近邻法中,当训练集、距离度量、K值和分类决策规则确定后,对于任何一个新的输入实例,它所属的类唯一确定。

2.1距离度量

特征空间中两个实例点的距离是两个实例点相似程度的反映,K近邻模型的特征空间一般是n维实数向量空间,使用的距离为欧氏距离(P=2)。也可使用其他距离。

2.2K值的选择

    K值较小,近似误差会减小,但估计误差会增大,容易过拟合。K值较大则相反,但模型会变得简单,起不到预测作用。

    在应用中,K应该是一个比较小的值,通常采用交叉验证来选最优K值。

2.3分类决策规则

多数表决规则

三、算法

3.1线性扫描

计算耗时,方法不可行。

3.2kd树

kd树是二叉树,表示对k维空间的划分。构造kd树相当于不断用垂直于坐标轴的超平面将k维空间切分,构建一系列的k维超矩形区域,kd树的每个节点对应于一个超矩形区域。

3.2.1构建kd树

1、开始:构造根节点,对应于包含T的K维空间的超矩形区域。

2、选择为坐标轴,T中轴向坐标的中位数为切分点,将切分点对应的超平面将超矩形区域分为两个子区域。每个子区域为一个子节点。

3、重复

我们有二维数据集T={(6,5),(1,-3),(-6,-5),(),(),(),(),(),(),(),(),()}

将他们在坐标系中表示如下:

开始:选择x为坐标轴,中位数为6(这个6是先根据x坐标排序,一共13个点,取长度的中数,),即得到(6,5)为切分点,切分整个区域

再次划分区域

以为y坐标轴,选择中位数,可知左边区域为-3,右边区域为-12。所以左边区域切分点为(1,-3),右边区域切分点坐标为(17,-12)

再次对区域进行切分,同上步,我们可以得到切分点,切分结果如下:

最后分割的小区域内只剩下一个点或者没有点。我们得到最终的kd树如下图

3.2.2搜索kd树(最近邻搜索)

(p为将要查找分类的点,S为所查找的邻近点集合,)

1.根据p的x坐标和kd树的结点向下进行搜索(如果树的结点是以x=c 来切分的,那么如果p的坐标小于c,则走左子结点,否则走右子结点)。

2.到达叶子结点时,将其标记为已访问。如果S中不足k个点,则将该结点加入到S中;如果S不空且当前结点与p点的距离小于S中最长的距离,则用当前结点替换S中离p最远的点。

3.如果当前结点不是根节点,执行(a);否则,结束算法。

(a)回退到当前结点的父结点,此时的结点为当前结点(回退之后的结点)。将当前结点标记为已访问,执行(b)和(c);如果当前结点已经被访过,再次执行(a)。

(b)如果此时S中不足k个点,则将当前结点加入到S中;如果S中已有k个点,且当前结点与p点的距离小于S中最长距离,则用当前结点替换S中距离最远的点。

(c)计算p点和当前结点切分线的距离。如果该距离大于等于S中距离p最远的距离并且S中已有k个点,执行3;如果该距离小于S中最远的距离或S中没有k个点,从当前结点的另一子节点开始执行1;如果当前结点没有另一子结点,执行3。

我们来举个例子:假设在上述建立好的kd树中查找p(-1,-5)的3个邻近点。

我们来举个例子:假设在上述建立好的kd树中查找p(-1,-5)的3个邻近点。

图中红点为p(-1,-5)

执行算法中的1。

 ·p点的-1与结点A的x轴坐标6比较,-1<6,向左走。

 ·p点的-5与结点B的y轴坐标-3比较,较小,往左走。

·因为结点C只有一个子结点,所以不需要进行比较,直接走到结点H。

进行算法中的2,标记结点H已访问,将结点H加入到S中。

此时S={H}

绿点为H(-4,-10)

执行算法中的3,当前结点H不是根结点

·执行(a),回退到父结点C,我们将结点C标记为已访问

·执行(b),S中不足3个点,将结点C加入到S中

·执行(c)计算p点和结点C切分线的距离,可是结点C没有另一个分支,我们开始执行算法中的3。

S={H,C}

当前结点C不是根结点

·执行(a),回退到父结点B,我们将结点B标记为已访问

·执行(b),S中不足3个点,将结点B加入到S中

·执行(c)计算p点和结点B切分线的距离,两者距离为 |(-3)-(-5)|=2,小于S中的最大距离。(S中的三个点与p的距离分别为

)。所以我们需要从结点B的另一子节点D开始算法中的1。此时S={H,C,B}

从结点D开始算法中的1

·p点的-1与结点D的x轴坐标-2比较,-1 >  -2,向右走。

·找到了叶子结点J,标记为已访问。

开始算法中的2

·S不空,计算当前结点J与p点的距离,为18.2,大于S中的最长距离

·所以我们不将结点J放入S中

此时集合S中仍为{H,C,B}

从结点I开始算法中的1,结点I已经是叶子结点

直接进行到算法中的2

标记结点I为已访问

计算当前结点I和p点的距离为17.464,大于S中最长距离,不进行替换。

S={D,C,B}

执行算法中的3.

当前结点I不是根结点

·执行(a),回退到父结点D,但当前结点D已经被访问过。

·再次执行(a),回退到结点D的父结点B,也标记为访问过

·再次执行(a),回退到结点B的父结点A,结点A未被访问过,标记为已访问。

·执行(b),结点A和p点的距离为12.207,大于S中的最长距离,不进行替换

·执行(c),p点和结点A切分线的距离为7,大于S中的最长距离,不进行替换

S={D,C,B}

执行算法中的3,发现当前结点A是根结点,结束算法。

得到p点的3个邻近点,为(-6,-5)、(1,-3)、(-2,-1)

你可能感兴趣的:(K近邻)