1.引言

   俗话说:“物以类聚,人以群分”,在我看来KNN(K-Nearest-Neighbor)算法就是这句话经典的诠释,KNN算法是一种“多分类”算法,也是最简单的易懂的机器学习算法(没有之一),同时KNN算法没有明显的训练模型的过程,它是“懒惰学习”的著名代表。在一般的机器学习算法中,都会经历两个阶段:训练阶段,预测阶段,但是在,在KNN算法中,在训练阶段仅仅是将样本数据保留起来,训练时间开销为零,等接收到测试数据(或叫做预测数据)在进行处理。那些训练阶段就需要学习的模型的算法被成为“急切学习”(比如决策树算法,SVM算法等)

2.算法原理

   前面我们说到:“物以类聚,人以群分”,如何理解这句话呢?首先我们看下面这张图片:

这里写图片描述

   上图时一个KNN分类器的一个示意图,其中绿色图形是待分类数据,红色图形和蓝色图形是已知数据。我们如何将绿色图形分类呢?我们就要根据K来判断,K是什么呢?K代表距离待预测数据(在这里是绿色区域)的元素的个数,假设我们令 k=3 <script type="math/tex" id="MathJax-Element-1">k=3</script>(即实线圆圈),我们可以看到区域内部有2个红色图形,有1个蓝色图形,因此我们将绿色区域分类为红色,假设我们令 k=5 <script type="math/tex" id="MathJax-Element-2">k=5</script>(即虚线圆圈),我们可以看到区域内部有2个红色图形,有3个蓝色图形,因此我们将绿色区域分类为蓝色。通过上面的描述我们可以看到,在KNN算法当中K的取值是十分重要的,然后KNN算法中并没有一个标准告诉我们K应该取多少合适。所以在实际应用中K的取值将是一个难点。

3.数学实例

   上一小结我们简单的介绍了一下KNN算法的原理,或许还是不太够直观,所以我们使用一个简单的数学例子加深对KNN算法的理解。我们的数据如下表所示:

电影名称 打斗次数 接吻次数 电影类型
我的野蛮女友 3 104 爱情电影
怦然心动 2 100 爱情电影
初恋这件小事 1 81 爱情电影
黑夜传说3:狼族再起 101 10 动作电影
终结者 99 5 动作电影
勇闯夺命岛 98 2 动作电影
我爱你 18 90 未知电影类型

   在上面表格中拥有7个电影的评价,其中我们将打斗次数接吻次数看成评价电影的特征,前6个电影我们已经知道了电影的类型,那么我想通过第7个电影的接吻次数打斗次数去预测第7部电影的类型。那么如何通过KNN算法预测第七部电影的类型呢?首先我们将上面的表格做如下处理:

电影名称 x1 <script type="math/tex" id="MathJax-Element-3">x1</script> x2 <script type="math/tex" id="MathJax-Element-4">x2</script> label <script type="math/tex" id="MathJax-Element-5">label</script>
A 3 104 1
B 2 100 1
C 1 81 1
D 101 10 2
E 99 5 2
F 98 2 2
J 18 90 ?

   如何计算未知电影J与与其他电影的距离呢?为了简单,我首先使用欧式距离(为了方便,我没有开根号)即:

d2=Δx12+Δx22
<script type="math/tex; mode=display" id="MathJax-Element-6">d^2=\Delta x1^2+\Delta x2^2</script>

   计算结果如下表所示:

电影名称 x1 <script type="math/tex" id="MathJax-Element-7">x1</script> x2 <script type="math/tex" id="MathJax-Element-8">x2</script> label <script type="math/tex" id="MathJax-Element-9">label</script> d2 <script type="math/tex" id="MathJax-Element-10">d^2</script> 距离排名
A 3 104 1 152+142=421 <script type="math/tex" id="MathJax-Element-11">15^2+14^2=421</script> 3
B 2 100 1 162+102=356 <script type="math/tex" id="MathJax-Element-12">16^2+10^2=356</script> 1
C 1 81 1 172+92=370 <script type="math/tex" id="MathJax-Element-13">17^2+9^2=370</script> 2
D 101 10 2 832+802=13289 <script type="math/tex" id="MathJax-Element-14">83^2+80^2=13289</script> 4
E 99 5 2 812+852=13786 <script type="math/tex" id="MathJax-Element-15">81^2+85^2=13786</script> 5
F 98 2 2 802+882=14144 <script type="math/tex" id="MathJax-Element-16">80^2+88^2=14144</script> 6
J 18 90 ?

   首先我们主观认为,第七部电影应该属于爱情电影(因为接吻次数比较多),通过我们的计算结果,假设当 k=3 <script type="math/tex" id="MathJax-Element-17">k=3</script>,我们计算的结果也是将第七部电影分为爱情电影(因为距离的前三名都是爱情电影,根据“物以类聚,人以群分”的准则)。但是万事总有意外,万一别人将k设为6应该怎么办呢?这也是这个算法的缺点。等一会我们将再一次解答这个问题。

4.算法优缺点

   通过上面的一个简单的例子,我们又对KNN算法加深了理解,那么KNN算法有哪些优缺点呢?我们首先总结一下:

4.1算法优点

  • 简单
  • 易于理解
  • 容易实现

4.2算法缺点

   关于KNN算法的缺点是我们应该着重关注的部分,因为只有知道了KNN的缺点,我们才会知道如何去改进算法,首先我们看下图:

这里写图片描述

   从图中我们可以看出来,在KNN算法中,K的取值时至关重要的,它将直接影响到预测的结果,是什么造成了这个原因呢?以上面的电影为例,假设我们令 k=5 <script type="math/tex" id="MathJax-Element-18">k=5</script>,那么距离未知电影最近的5个电影,3个是爱情电影,2个是动作电影,因此爱情电影的比例是 35 <script type="math/tex" id="MathJax-Element-19">\frac{3}{5}</script>,因此我们将第7个电影预测为爱情电影,假设我们令 k=6 <script type="math/tex" id="MathJax-Element-20">k=6</script>之后,预测结果就完全不同了,结果似乎不准了,是什么造成了这个原因呢?是因为我们认为表格中的6部电影对第7部电影造成的影响是相等的,即都为1,所以当k=6时,我们的计算过程为 1+1+16 <script type="math/tex" id="MathJax-Element-21">\frac{1+1+1}{6}</script>,计算之后发现,爱情电影和动作电影都是 12 <script type="math/tex" id="MathJax-Element-22">\frac{1}{2}</script>,所以我们就不知道如何预测了。
   上述我们知道了KNN算法的一个非常大的缺点,我们应该如何降低这个缺点呢?回到我们前面说的:”物以类聚,人以群分”。其实从生活经验中我们可以发现距离预测点越近的数据将会对预测点产生更大的影响,这句话如何理解呢?举个例子:通过刚刚的数学计算我们可以知道距离第7个电影最近的是B电影,其次是A电影。因此我们认为B电影对未知电影的影响 > <script type="math/tex" id="MathJax-Element-23">></script>电影A对未知电影的影响,这句话如何用数学表达出来呢?最简单的方式是:1d<script type="math/tex" id="MathJax-Element-24">\frac{1}{d}</script>(并不一定非要用距离的倒数,只是提供一种解决方案)。如果使用 1d <script type="math/tex" id="MathJax-Element-25">\frac{1}{d}</script>作为权重,当我们取 k=6 <script type="math/tex" id="MathJax-Element-26">k=6</script>时,首先选择距离前6的电影,然后计算权重:

=1421+1356+1370
<script type="math/tex; mode=display" id="MathJax-Element-41">\mbox{爱情电影的权重} =\frac{1}{421}+\frac{1}{356}+\frac{1}{370}</script>
=113289+113786+114144
<script type="math/tex; mode=display" id="MathJax-Element-42">\mbox{动作电影的权重} =\frac{1}{13289}+\frac{1}{13786}+\frac{1}{14144}</script>

   通过计算权重,根据爱情电影的权重大,所以我们还是预测为爱情电影,注意使用 1d <script type="math/tex" id="MathJax-Element-43">\frac{1}{d}</script>作为权重并不能消除误差,当动作电影足够多时,我们还是存在可能将未知电影预测为动作电影,我们使用 1d <script type="math/tex" id="MathJax-Element-44">\frac{1}{d}</script>只是降低了这种可能性。(当其样本分布不平衡时,比如其中一类样本过大(实例数量过多)占主导的时候,同时K的取值过大时,新的未知实例容易被归类为这个主导样本,因为这类样本实例的数量过大,但这个新的未知实例实际并未接近目标样本)

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐