CategoryResourceRepost/极客时间专栏/数据分析实战45讲/第二模块:数据分析算法篇/24丨KNN(上):如何根据打斗和接吻次数来划分电影类型?.md
louzefeng d3828a7aee mod
2024-07-11 05:50:32 +00:00

130 lines
9.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<audio id="audio" title="24丨KNN如何根据打斗和接吻次数来划分电影类型" controls="" preload="none"><source id="mp3" src="https://static001.geekbang.org/resource/audio/4c/22/4c6cb0d4b941254d064f275d496e1122.mp3"></audio>
今天我来带你进行KNN的学习KNN的英文叫K-Nearest Neighbor应该算是数据挖掘算法中最简单的一种。
我们先用一个例子体会下。
假设,我们想对电影的类型进行分类,统计了电影中打斗次数、接吻次数,当然还有其他的指标也可以被统计到,如下表所示。
<img src="https://static001.geekbang.org/resource/image/6d/87/6dac3a9961e69aa86d80de32bdc00987.png" alt=""><br>
我们很容易理解《战狼》《红海行动》《碟中谍6》是动作片《前任3》《春娇救志明》《泰坦尼克号》是爱情片但是有没有一种方法让机器也可以掌握这个分类的规则当有一部新电影的时候也可以对它的类型自动分类呢
我们可以把打斗次数看成X轴接吻次数看成Y轴然后在二维的坐标轴上对这几部电影进行标记如下图所示。对于未知的电影A坐标为(x,y)我们需要看下离电影A最近的都有哪些电影这些电影中的大多数属于哪个分类那么电影A就属于哪个分类。实际操作中我们还需要确定一个K值也就是我们要观察离电影A最近的电影有多少个。
<img src="https://static001.geekbang.org/resource/image/fa/cc/fa0aa02dae219b21de5984371950c3cc.png" alt="">
## KNN的工作原理
“近朱者赤近墨者黑”可以说是KNN的工作原理。整个计算过程分为三步
<li>
计算待分类物体与其他物体之间的距离;
</li>
<li>
统计距离最近的K个邻居
</li>
<li>
对于K个最近的邻居它们属于哪个分类最多待分类物体就属于哪一类。
</li>
**K值如何选择**
你能看出整个KNN的分类过程K值的选择还是很重要的。那么问题来了K值选择多少是适合的呢
如果 K 值比较小就相当于未分类物体与它的邻居非常接近才行。这样产生的一个问题就是如果邻居点是个噪声点那么未分类物体的分类也会产生误差这样KNN分类就会产生过拟合。
如果K值比较大相当于距离过远的点也会对未知物体的分类产生影响虽然这种情况的好处是鲁棒性强但是不足也很明显会产生欠拟合情况也就是没有把未分类物体真正分类出来。
所以K值应该是个实践出来的结果并不是我们事先而定的。在工程上我们一般采用交叉验证的方式选取 K 值。
交叉验证的思路就是把样本集中的大部分样本作为训练集剩余的小部分样本用于预测来验证分类模型的准确性。所以在KNN算法中我们一般会把K值选取在较小的范围内同时在验证集上准确率最高的那一个最终确定作为K值。
**距离如何计算**
在KNN算法中还有一个重要的计算就是关于距离的度量。两个样本点之间的距离代表了这两个样本之间的相似度。距离越大差异性越大距离越小相似度越大。
关于距离的计算方式有下面五种方式:
<li>
欧氏距离;
</li>
<li>
曼哈顿距离;
</li>
<li>
闵可夫斯基距离;
</li>
<li>
切比雪夫距离;
</li>
<li>
余弦距离。
</li>
其中前三种距离是KNN中最常用的距离我给你分别讲解下。
**欧氏距离**是我们最常用的距离公式,也叫做欧几里得距离。在二维空间中,两点的欧式距离就是:
<img src="https://static001.geekbang.org/resource/image/f8/80/f8d4fe58ec9580a4ffad5cee263b1b80.png" alt=""><br>
同理我们也可以求得两点在n维空间中的距离
<img src="https://static001.geekbang.org/resource/image/40/6a/40efe7cb4a2571e55438b55f8d37366a.png" alt=""><br>
**曼哈顿距离**在几何空间中用的比较多。以下图为例,绿色的直线代表两点之间的欧式距离,而红色和黄色的线为两点的曼哈顿距离。所以曼哈顿距离等于两个点在坐标系上绝对轴距总和。用公式表示就是:
<img src="https://static001.geekbang.org/resource/image/bd/aa/bda520e8ee34ea19df8dbad3da85faaa.png" alt="">
<img src="https://static001.geekbang.org/resource/image/dd/43/dd19ca4f0be3f60b526e9ea0b7d13543.jpg" alt=""><br>
**闵可夫斯基距离**不是一个距离而是一组距离的定义。对于n维空间中的两个点 x(x1,x2,…,xn) 和 y(y1,y2,…,yn) x 和 y 两点之间的闵可夫斯基距离为:
<img src="https://static001.geekbang.org/resource/image/4d/c5/4d614c3d6722c02e4ea03cb1e6653dc5.png" alt=""><br>
其中p代表空间的维数当p=1时就是曼哈顿距离当p=2时就是欧氏距离当p→∞时就是切比雪夫距离。
**那么切比雪夫距离**怎么计算呢二个点之间的切比雪夫距离就是这两个点坐标数值差的绝对值的最大值用数学表示就是max(|x1-y1|,|x2-y2|)。
**余弦距离**实际上计算的是两个向量的夹角,是在方向上计算两者之间的差异,对绝对数值不敏感。在兴趣相关性比较上,角度关系比距离的绝对值更重要,因此余弦距离可以用于衡量用户对内容兴趣的区分度。比如我们用搜索引擎搜索某个关键词,它还会给你推荐其他的相关搜索,这些推荐的关键词就是采用余弦距离计算得出的。
## KD树
其实从上文你也能看出来KNN的计算过程是大量计算样本点之间的距离。为了减少计算距离次数提升KNN的搜索效率人们提出了KD树K-Dimensional的缩写。KD树是对数据点在K维空间中划分的一种数据结构。在KD树的构造中每个节点都是k维数值点的二叉树。既然是二叉树就可以采用二叉树的增删改查操作这样就大大提升了搜索效率。
在这里我们不需要对KD树的数学原理了解太多你只需要知道它是一个二叉树的数据结构方便存储K维空间的数据就可以了。而且在sklearn中我们直接可以调用KD树很方便。
## 用KNN做回归
KNN不仅可以做分类还可以做回归。首先讲下什么是回归。在开头电影这个案例中如果想要对未知电影进行类型划分这是一个分类问题。首先看一下要分类的未知电影离它最近的K部电影大多数属于哪个分类这部电影就属于哪个分类。
如果是一部新电影,已知它是爱情片,想要知道它的打斗次数、接吻次数可能是多少,这就是一个回归问题。
那么KNN如何做回归呢
对于一个新电影X我们要预测它的某个属性值比如打斗次数具体特征属性和数值如下所示。此时我们会先计算待测点新电影X到已知点的距离选择距离最近的K个点。假设K=3此时最近的3个点电影分别是《战狼》《红海行动》和《碟中谍6》那么它的打斗次数就是这3个点的该属性值的平均值即(100+95+105)/3=100次。
<img src="https://static001.geekbang.org/resource/image/35/16/35dc8cc7d781c94b0fbaa0b53c01f716.png" alt="">
## 总结
今天我给你讲了KNN的原理以及KNN中的几个关键因素。比如针对K值的选择我们一般采用交叉验证的方式得出。针对样本点之间的距离的定义常用的有5种表达方式你也可以自己来定义两个样本之间的距离公式。不同的定义适用的场景不同。比如在搜索关键词推荐中余弦距离是更为常用的。
另外你也可以用KNN进行回归通过K个邻居对新的点的属性进行值的预测。
KNN的理论简单直接针对KNN中的搜索也有相应的KD树这个数据结构。KNN的理论成熟可以应用到线性和非线性的分类问题中也可以用于回归分析。
不过KNN需要计算测试点与样本点之间的距离当数据量大的时候计算量是非常庞大的需要大量的存储空间和计算时间。另外如果样本分类不均衡比如有些分类的样本非常少那么该类别的分类准确率就会低很多。
当然在实际工作中,我们需要考虑到各种可能存在的情况,比如针对某类样本少的情况,可以增加该类别的权重。
同样KNN也可以用于推荐算法虽然现在很多推荐系统的算法会使用TD-IDF、协同过滤、Apriori算法不过针对数据量不大的情况下采用KNN作为推荐算法也是可行的。
<img src="https://static001.geekbang.org/resource/image/d6/0f/d67073bef9247e1ca7a58ae7869f390f.png" alt=""><br>
最后我给你留几道思考题吧KNN的算法原理和工作流程是怎么样的KNN中的K值又是如何选择的
## 上一篇文章思考题的代码
我在上篇文章里留了一道思考题,你可以在[GitHub](http://github.com/cystanford/breast_cancer_data)上看到我写的关于这道题的代码(完整代码和文章案例代码差别不大),供你借鉴。
<img src="https://static001.geekbang.org/resource/image/fa/44/fa09558150152cdb250e715ae9047544.png" alt="">
欢迎你在评论区与我分享你的答案,也欢迎点击“请朋友读”,把这篇文章分享给你的朋友或者同事。