k近邻算法 (KNN)

k近邻算法

  • k近邻算法(KNN,K-NearestNeighbor)是一种基本分类和回归方法,监督学习算法,本质上是基于一种数据统计的方法;

  • 核心思想:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例的多数属于某个类(多数表决规则等价于经验风险最小化),就把该输入实例分类到这个类中(通俗说:一个新的输入实例,我们算出该实例与每一个训练点的距离,然后找到前k个,这k个哪个类别数最多,我们就判断新的输入实例就是哪类

  • k值选取:KNN算法唯一的超参数。一般选取一个较小的数值,通常采取交叉验证法来选取最优的k值(李航《统计学习方法》)

    • k太小(如k=1),模型复杂,学习噪声,导致过拟合;
    • k太大(如k=N, N为训练样本的个数),受到样本均衡问题,模型过于简单;
  • 距离函数: 闵可夫斯基距离,不是一种距离,而是一组距离的定义,是对多个距离公式的概括性表述;

    • 欧式距离

    • 曼哈顿距离

    • 切比雪夫距离
      d 12 = m a x ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) d_{12}=max(|x_1 - x_2|, |y_1 - y_2|) d12=max(x1x2,y1y2)

    • 标准化欧式距离(standardized EuclideanDistance)

      在计算中添加了标准差,对量纲数据进行处理

    • 余弦距离(Cosine Distance)

      余弦距离(余弦相似度): 用向量空间中两个向量夹角的余弦值 作为衡量两个个体间差异的大小的度量;
      c o s ( θ ) = ∑ k = 1 n x 1 k x 2 k ∑ k = 1 n x 1 k 2 ∑ k = 1 n x 2 k 2 cos(\theta) ={{\sum_{k=1}^nx_{1k}x_{2k}}\over \sqrt{\sum_{k=1}^n x_{1k}^2} \sqrt{\sum_{k=1}^n x_{2k}^2}} cos(θ)=k=1nx1k2 k=1nx2k2 k=1nx1kx2k

  • 算法优缺点:

    • 优点:

      1. KNN方法简单直观,易于实现!只要让预测点分别和训练数据求距离,挑选前k个即可,非常简单直观;既可以用来做分类也可以用来做回归

      2. 没有明显的训练过程(lazy learning),新数据可以直接加入数据集而不必进行重新训练

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

    • 缺点及改进:

      1. 样本不平衡时(比如一个类的样本容量很大,其他类的样本容量很小),输入一个样本的时候,K个邻近值大多数都是大样本容量的那个类,这时可能会导致分类错误。(改进方法:对K邻近点进行加权,也就是距离近的权值大,距离远的点权值小

      2. 计算量较大(复杂度为0(n)),每个待分类的样本都要计算它到全部点的距离,根据距离排序才能求得K个临近点。(改进方法:先对已知样本带你进行裁剪,事先去除分类作用不大的样本,采取kd树(k-dimension tree, 二叉树结构,先构建树,再近邻域搜索)、ballTree(解决KDTree在高维上效率低下的问题)以及其它高级搜索方法BBF等算法减少搜索时间。

  • 应用场景

    • 用户推荐:用KNN算法做到比较通用的现有用户产品推荐,基于用户的最近邻(长得最像的用户)买了什么产品来推荐,是一种基于电子商务和sns的精确营销,只需要定期维护更新最近邻表就可以
    • 文本分类
    • 回归问题
  • API

    class sklearn.neighbors.KNeighborsClassifier(n_neighbors=5, *, weights='uniform', algorithm='auto', leaf_size=30, p=2, metric='minkowski', metric_params=None, n_jobs=None)[source]
    
    [n_neighbors] 也就是K,默认参数为5[weights] str参数,为了降低k值的影响所设置的权重值,即每个拥有投票权的样本是按什么比重投票,'uniform'表示等比重投票,'distance'表示按距离 反比投票,[callable]表示自己定义的一个函数,这个函数接收一个距离数组,返回一个权值数组。默认参数为‘uniform’。
    
    [algorithm] str参数,即内部采用什么数据结构实现。有以下几种选择参:'ball_tree':球树、'kd_tree':kd树、'brute':暴力搜索、'auto':自动根据数据的类型和结构选择合适的算法。默认情况下是‘auto’。暴力搜索就不用说了大家都知道。具体前两种树型数据结构哪种好视情况而定。KD树是依次对K维坐标轴,以中值切分构造的树,每一个节点是一个超矩形,在维数小于20时效率最高。ball tree 是为了克服KD树高维失效而发明的,其构造过程是以质心C和半径r分割样本空间,每一个节点是一个超球体。一般低维数据用kd_tree速度快,用ball_tree相对较慢。超过20维之后的高维数据用kd_tree效果反而不佳,而ball_tree效果要好,具体构造过程及优劣势的理论大家有兴趣可以去具体学习。
    
    [leaf_size] int参数,基于以上介绍的算法,此参数给出了kd_tree或者ball_tree叶节点规模,叶节点的不同规模会影响数的构造和搜索速度,同样会影响用于储存树的内存的大小。具体最优规模是多少视情况而定。
    
    [matric] str或者距离度量对象,即怎样度量距离,前面有具体介绍。默认minkowski。
    
    [p] int参数,就是以上闵氏距离各种不同的距离参数,默认为2,即欧氏距离。p=1代表曼哈顿距离等等。
    
    [metric_params] 距离度量函数的额外关键字参数,一般不用管,默认为None[n_jobs] int参数,指并行计算的线程数量,默认为1表示一个线程,为-1的话表示为CPU的内核数,也可以指定为其他数量的线程,这里不是很追求速度的话不用管,需要用到的话去看看多线程。
    
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值