六游的博客小站
K最近邻算法
发布于: 2019-03-03 更新于: 2019-03-31 阅读次数: 

KNN算法的基本思想


之所以选择KNN算法作为我学习的第一个机器学期算法,是因为这个算法的思想很简单,我可以快速的入门机器学习,并且借此算法了解到许多在机器学习经常会出现的概念。

首先从一个小例子来了解KNN算法的基本思想。我们首先列出一组虚拟的数据,并且画出该组数据的散点图。

1.jpg

这组数据一共由两种类型八个数据组成,每个数据都是一个二维向量,散点图上的红蓝两种颜色的点就代表两种不同类型的数据。我们把这八个数据全部作为训练数据,此时又来了一个新数据(图中的绿点),我们需要预测该绿点属于那个类别。
让我们来看看KNN算法是怎么处理这个问题的,首先我们先假设K为3,那么KNN算法就会寻找距离该需要预测的点最近的三个训练数据。也就是图中的三个蓝点,然后统计这三个点的标签,进行投票,那个标签的数量最多,KNN就会认定该点属于哪一类别。怎么样KNN算法的思想是不是很简单,很易于理解。

KNN底层代码封装


我们实现KNN算法的基本思路就是当输入一个预测数据的时候,计算出训练数据集中每个点到预测数据点的距离,然后取出前k个数据,然后计算出该k个数据对应的标签数最多的那个,就是预测结果。为了我们使用方便以及统一格式我们将数据封装为类的形式。2.jpg

  • init用来初始化算法(一些超参数的设定)
  • fit中文翻译为拟合,是由训练数据得出预测模型的过程。然而在KNN中并没有模型这一概念,其实KNN也是少数的不用得出预测模型直接开始预测的机器算法之一。但是我们为了统一封装,所以给KNN也封装了拟合这一过程,在fit中做的仅仅是将训练数据传给对象使其保存起来。
  • predict由输入数据得出预测结果的过程。在scikit-learn中,predict的参数要是一个数据列表,输出结果也是一个结果列表

3.jpg

关于test-train-split


当我们需要用机器学习去解决一个实际问题的时候,我们需要为该场景挑选出最合适的机器学习算法,并且确定在这个场景下最合适的超参数。但是在真实场景下测试时间周期长,并且在真实场景下你很难拿到数据的真实的标签。
所以我们通常会将测试数据分成两份,一份作为训练数据,一份作为测试数据。用训练数据结合算法和特定的参数,配合训练数据我们可以很快的得出该算法在此场景下的预测准确率

4.jpg

该方法将传入的数据矩阵和标签向量分为训练与测试两份,在参数中可以指定测试数据在所有数据中所占的比例,默认为20%

5.jpg

然后将测试数据放进模型由模型预测,最后比较预测的结果与本身的标签向量我们可以得出在该问题场景下特定算法特定参数的准确率

关于KNN中的超参数

超参数:在执行机器学习算法之前就需要指定的参数,我们在机器学习中常说的调参中的参数指的就是超参数,超参数对于一个模型的准确率十分重要,我们接下来来讨论一下KNN最近邻算法中的一些常用超参数

  • k 取的最近距离点的个数
  • weight数 权重方式(uniform:无权重 distance:以连点距离的倒数作为该点的投票权重)

6.jpg

如图(k=3),训练数据与测试数据出现了类似这样的情形,如果按照原本的方式,与测试数据最近的三个点分别是两个蓝点和一个红点,蓝点胜出,所以预测结果会是蓝色。但是我们从图中可以很明显的看出,预测点与唯一的一个红色更近一些,也就是说预测点更偏向红色一些。这个时候我们可以给投票加权,以距离的倒数为权重。这样离预测点近的点的票权就重

  • P(计算距离的方式)

    首先我们来了解一些概念
    首先是最常见的欧拉距离以及其变形形式
    7.jpg
    8.jpg
    其次就是曼哈顿距离,曼哈顿距离得出的是两点在各个维度上的距离之和
    9.jpg
    由欧拉距离和曼哈顿距离公式我们可以进一步得出明可夫斯基距离
    10.jpg
    p值默认为2

关于Scaler

假如现在我们有一组数据,分别是肿瘤发现的时间和肿瘤的大小,我们要根据这两个数据预测出该肿瘤是否是恶性肿瘤。其中的某条数据为肿瘤发现时间211天,肿瘤大小2.1cm。到这里我们就很容易发现,两点之间的距离主要受了天数的影响,肿瘤大小的对点距离造成的影响很小。显然这不是我们想要看到的结果。
所以在拟合与预测之前需要先对样本数据与待预测数据做归一化处理,使所有数据都分布在同一量纲内。
这里先来介绍两种常用的归一化方法

11.jpg

从公式中我们可以看出来,这中归一化方法要求数据有很明显的边界,就是说要有明确的最大值与最小值。比如学生的分数(0-100)等,但面对一些边界并不明显的效果就不会很好了,比如股票价格、房价等。

12.jpg

面对那些没有明显边界的数据,我们可以使用均值方差归一化方法

关于KNN算法的更多思考

--- 本文结束 The End ---