KNN算法

    KNN做回归和分类的主要区别在于最后预测的时候决策方式不同。KNN做分类预测时,一般是选择多数表决法,即训练集里和预测的样本特征最近的K个样本,预测为里面有最多类别数的类别。而KNN做回归时,一般是选择平均法,即最近的K个样本的样本输出的平均值作为回归预测值。由于两者区别不大,虽然本人主要是讲解KNN的分类方法,但思想对KNN的回归方法也适用。

1.KNN算法三要素

    KNN算法我们主要考虑三个重要的元素,对于固定的训练集,只要这三点确定了,算法的预测方式也就决定了。这三个最终的要素是K值的选取,距离度量的方式和分类决策规则

    对于分类决策规则,一般都是使用前面提到的多数表决法。所以我们的重点是关注与K值的选择和距离的度量方式。

    对于K值的选择,没有一个固定的经验,一般根据样本的分布,选择一个较小的值,可以通过交叉验证选择一个合适的K值(一般是3-10)。选择较小的值,就相当于用较小的领域中的训练实例进行预测,训练误差会减小,只有与输入实例较近或相似的训练实例才会对预测结果起作用,与此同时带来的问题是泛化误差会增大,换句话说,K值的减小就意味着整体模型变的复杂,容易发生过拟合

    选择较大的K值,就相当于用较大领域中的训练实例进行预测,其优点是可以减少泛化误差,但缺点是训练误差会增大。这时候,与输入实例较远(不相似的)训练实例也会对预测器作用,使预测发生错误,且K值的增大就意味着整体的模型变得简单。

    一个极端是K等于样本数m,则完全没有分类,此时无论输入什么实例,都只是简单的预测它属于在训练实例中最多的类,模型过于简单。

3.sklearn中KNN算法参数

     KNeighborsClassifier类:最经典的KNN分类算法。

    KNeighborsRegressor类:利用KNN算法解决回归问题。

    RadiusNeighborsClassifier类:基于固定半径来查找最近邻的分类算法。

    NearestNeighbors类:基于无监督学习实现KNN算法。

    KDTree类:无监督学习下基于 KDTree来查找最近邻的分类算法。

    BallTree类:无监督学习下基于 BallTree来查找最近邻的分类算法。

(1)n_neighbors:这个值就是指KNN中的"K"。前面说过,通过调整K值,算法会有不同的效果。

(2)weight(权重):最普遍的KNN算法无论距离如何,权重都一样,但有时候我们想搞点特殊化,比如距离更近的点让它更加重要。这个时候就需要weight这个参数了,这个参数有三个可选参数的值,决定了如何分配权重。参数选项如下:

    "uniform":不管远近权重都一样,就是最普通的KNN算法的形式。

    ”distance“:权重和距离成反比,距离预测目标越近具有越高的权重。

    "自定义函数":自定义一个函数,根据输入的坐标值返回对应的权重,达到自定义权重的目的。

    "algorithm":在sklearn中吗,要构建KNN模型有三种构建方式:

    1)暴力法:就是直接计算距离存储比较的那种方式。

    2)使用Kd树构建KNN模型。

    3)使用球树构建。

其中暴力法适合数据较小的方式,否则效率会比较低。如果数据量比较大一般会选择用Kd树构建KNN模型,而当Kd树比较慢的时候,则可以试试球树来构建KNN。参数选项如下:

    'brute':蛮力实现。

    "kd_tree": KD树实现KNN。

    "ball_tree":球树实现KNN;

    "auto":默认参数,自动选择合适的方法构建模型。

不过当数据较小或比较稀疏时,无论选择哪个最后都会使用'brute'

    "leaf_size":如果选择蛮力实现,那么这个值是可以忽略的。当使用Kd树或球树,它就是停止建子树的叶子节点数量的阈值。默认30,但如果数据量增多这个参数需要增大,否则速度过慢不说,还容易过拟合。

    "p":和metric结合使用,当metric参数是"minkowski"的时候,p=1为曼哈顿距离,p=2为欧式距离。默认为p=2。

    "metric":指定距离度量方法,一般都是使用欧式距离。

                "euclidean":欧式距离;

                "manhattan":曼哈顿距离;

                "chebyshey":切比雪夫距离;

                "minkowski": 闵可夫斯基距离,默认参数。

        n_jobs:指定多少个cpu进行运算,默认是-1,也就是全部都算。

常用方法:

knn.score(X,y,sample_weight=None):返回给定测试数据和标签的平均精度。

knn.r2_score(y_true,y_pred,sample_weight=None,multioutput='uniform_average'):返回r2

4.算法特点

    KNN是一种非参的、惰性的算法模型。那么什么是非参,什么是惰性呢?

    非参:并不是说这个算法不需要参数,而是意味着这个模型不会对数据做出任何的假设,与之相对的是线性回归(我们总会假设线性回归是一条直线)。也就是说KNN建立的模型结果是根据数据来决定的,这个也比价符合现实的情况,毕竟在现实中的情况往往与理论上的假设是不相符合的。

    惰性:同样是分类算法,逻辑回归需要先对数据进行大量训练,最后才会得到一个算法模型。而KNN算法却不需要,它没有明确的训练数据的过程,或者说这个过程很快。

5.算法优缺点

    优点:

   (1)模型训练时间快(因为KNN算法是惰性的)。时间复杂度为O(n)。

    (2)可用于非线性分类。

    (3)和朴素贝叶斯之类的算法比,对数据没有假设,准确度高,对异常点不敏感。

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

    (5)该算法比较适用于样本容量比较大的类域的自动分类,而那些样本容量较小的类域采用这种算法比较容易产生误分。适合对稀有事件进行分类(例如:客户流失预测);特别适合于多分类问题(根据基因特征来判断其功能分类),KNN比SVM的表现要好。

     缺点:
    (1)计算量大,尤其是特征数非常多的时候。

    (2)样本平衡的时候,对稀有类别的预测准确率低。

    (3)KD树,球树之类的模型建立需要大量的内存。对内存要求较高,因为该算法存储了所有训练数据。

    (4)使用惰性算法,基本上不学习,导致预测时速度比起逻辑回归之类的算法慢。

6.KNN和K-Means比较

    前面说到过,KNN和K-Means听起来有些像,但本质是有区别的,在这里我们比较一下两者的异同。

相同点:

(1)K值都是重点。

(2)都需要计算平面中点的距离。

相异点:

KNN和K-Means的核心都是通过计算空间中点的距离来实现目的,只是他们的目的是不同的。KNN的最终目的是分类,而K-Means的目的是给所有距离相近的点分配一个类别,也就是聚类。简单说,就是画一个圈,KNN是让进来圈子里的人变成自己人,K-Means是让原本圈内的人归为一类人。

适用场景:当需要使用分类算法,且数据比较大的时候就可以尝试使用KNN算法进行分类。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容