KNN原理

  KNN是一种即可用于分类又可用于回归的机器学习算法。对于给定测试样本,基于距离度量找出训练集中与其最靠近的K个训练样本,然后基于这K个“邻居”的信息来进行预测。常用于文本分类、模式识别、多分类等领域。
  在分类任务中可使用投票法,选择这K个样本中出现最多的类别标记作为预测结果;在回归任务中可使用平均法,将这K个样本的实值输出标记的平均值作为预测结果。当然还可以基于距离远近程度进行加权平均等方法。
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客

 KNN算法三要素

1、距离度量

闵可夫斯基距离(minkowski):
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客
欧氏距离(euclidean,p=2):
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客
曼哈顿距离(manhattan,p=1):
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客
切比雪夫距离(chebyshev,p= ∞infty∞):
 
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客
……常用的主要有这些。

2、k值的选择

下面分析k值过大和过小造成的影响:

k值较小,就相当于用较小的领域中的训练实例进行预测,训练误差近似误差小(偏差小),泛化误差会增大(方差大),换句话说,K值较小就意味着整体模型变得复杂,容易发生过拟合;

k值较大,就相当于用较大领域中的训练实例进行预测,泛化误差小(方差小),但缺点是近似误差大(偏差大),换句话说,K值较大就意味着整体模型变得简单,容易发生欠拟合;一个极端是k等于样本数m,则完全没有分类,此时无论输入实例是什么,都只是简单的预测它属于在训练实例中最多的类,模型过于简单。

        对于k值的选择,没有一个固定的经验(sklearn默认为5),一般根据样本的分布,选择一个较小的值,可以通过交叉验证选择一个合适的k值。
 

3、分类决策规则

KNN 算法一般是用多数表决方法,即由输入实例的K个邻近的多数类决定输入实例的类。这也是经验风险最小化的结果。
 
我们定义训练误差率是K近邻训练样本标记与输入标记不一致的比例,误差率表示为:
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客
 
目的是K近邻的标记值尽可能的与输入标记一致,所以最小化
KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客KNN算法(K近邻,k-NearestNeighbor)的理解及原理-风君雪科技博客
 

KNN优缺点

KNN 优点:

理论成熟,思想简单,既可以用来做分类也可以用来做回归
可用于非线性分类
训练时间复杂度比支持向量机之类的算法低,仅为O(n)
和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感
由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合
该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分

KNN 缺点:

计算量大,尤其是特征数非常多的时候
样本不平衡的时候,对稀有类别的预测准确率低
KD树,球树之类的模型建立需要大量的内存
使用懒散学习方法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢
相比决策树模型,KNN模型可解释性不强

KNN算法实现

1、线性扫描

  线性扫描也叫“暴力搜索”,是计算输入实例与每一个训练实例的距离,并选择前k个最近邻的样本来多数表决。这种实现方法简单,但是当训练集或特征维度很大时(我们经常碰到样本的特征数有上千以上,样本量有几十万以上),如果我们这要去预测少量的测试集样本,算法的时间效率很成问题,计算非常耗时,故这种暴力实现原理是不可行的 。
 

2、kd 树实现

  kd 树是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,构造kd树相当于不断用垂直于坐标轴的超平面将k维空间进行划分,构成一系列的k维超矩形区域,kd树省去了对大部分数据的搜索,大大的较少了计算量。
 
  注意这里的k和KNN中的k的意思不同。KNN中的k代表最近的k个样本,kd树中的k代表样本特征的维数。
 
  KD树算法包括三步,第一步是建树,第二部是搜索最近邻,最后一步是预测。
 
        kd 树的建立。kd树实质是二叉树,其划分思想与CART树一致,切分使样本复杂度降低最多的特征。kd树分别计算k个特征的方差,认为特征方差越大,则该特征的复杂度亦越大,优先对该特征进行切分 ,切分点是所有实例在该特征的中位数。重复该切分步骤,直到切分后无样本则终止切分,终止时的样本为叶节点,形成kd树。
 
        kd树搜索最近邻。生成kd树以后,对于一个目标点以目标点为圆心,以目标点到叶子节点样本实例的距离为半径,得到一个超球体,最近邻的点一定在这个超球体内部。然后返回叶子节点的父节点,检查另一个子节点包含的超矩形体是否和超球体相交,如果相交就到这个子节点寻找是否有更加近的近邻,有的话就更新最近邻。如果不相交直接返回父节点的父节点,在另一个子树继续搜索最近邻。依次下去,当回溯到根节点时,算法结束,此时保存的最近邻节点就是最终的最近邻。
 
对于kd树来说,划分后可以大大减少无效的最近邻搜索,很多样本点由于所在的超矩形体和超球体不相交,根本不需要计算距离。大大节省了计算时间。
 
        kd树预测。分类:每一次搜寻与输入样本最近的样本节点,然后忽略该节点,重复同样步骤K次,找到与输入样本最近邻的K个样本 ,投票法确定输出结果。回归:用K个最近样本的输出的平均值作为回归预测值。
 

3、球树实现

  kd树算法虽然提高了KNN搜索的效率,但是在某些时候效率并不高,比如当处理不均匀分布的数据集时,不管是近似方形,还是矩形,甚至正方形,都不是最好的使用形状,因为他们都有角。为了优化超矩形体导致的搜索效率的问题,从而提出了球树实现的方法。其基本思想和kd树类似,就是每个分割块都是超球体,而不是KD树里面的超矩形体。