mirror of
https://github.com/apachecn/ailearning.git
synced 2026-05-08 23:12:06 +08:00
更新 knn 目录结构和项目实战
This commit is contained in:
107
docs/2.k-近邻算法.md
107
docs/2.k-近邻算法.md
@@ -3,38 +3,38 @@
|
||||
|
||||

|
||||
|
||||
众说周知,电影可以按照题材分类;而我们却知道每部电影在风格上的确可能和同题材的电影相近。
|
||||
那么动作片具有哪些共有特征,使得动作片之间非常相似,而与爱情片存在着明显的差别呢?<br/>
|
||||
例如: 1.打斗次数 2.亲吻次数<br/>
|
||||
动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们不能单纯依靠是否存在打斗或者亲吻镜头来判断影片的类型。但是爱情片中的亲吻镜头更多,动作片中的打斗场景也更频繁,基于此类场景在某部电影中出现的次数可以用来进行电影分类。<br/>
|
||||
基于电影中出现的亲吻、打斗出现的次数,使用 k-近邻算法构造程序,自动划分电影的题材类型。
|
||||
## KNN 概述
|
||||
|
||||
## k-近邻分类算法
|
||||
`k-近邻(kNN, k-NearestNeighbor)算法主要是用来进行分类的.`
|
||||
|
||||
> k-近邻(kNN,k-NearestNeighbor)算法的工作原理
|
||||
## KNN 场景
|
||||
|
||||
```
|
||||
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据与所属分类的对应关系。
|
||||
输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本中特征最相似数据(最近邻)的分类
|
||||
标签。一般来说,我们只选择样本数据集中前 k 个最相似的数据,这就是 k-近邻算法中 k 的来历。通常 k 是一个不大于 20 的整数。
|
||||
最后,选择 k 个最相似数据中出现次数最多的分类,作为新数据的分类。
|
||||
```
|
||||
|
||||
```
|
||||
回想上面我们提到的电影分类的例子,使用 k-近邻算法 分类爱情片和动作片。下图显示了6部电影的打斗和接吻镜头数。
|
||||
假如有一部未看过的电影,如何确定它是爱情片还是动作片呢?接下来,我们使用 kNN 来解决这个问题。
|
||||
```
|
||||
电影可以按照题材分类,那么如何区分 `动作片` 和 `爱情片` 呢?<br/>
|
||||
1. 动作片:打斗次数更多
|
||||
2. 爱情片:亲吻次数更多
|
||||
|
||||
基于电影中的亲吻、打斗出现的次数,使用 k-近邻算法构造程序,就可以自动划分电影的题材类型。
|
||||
|
||||

|
||||
|
||||
```
|
||||
现在根据上面我们得到的样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到 k 个距离最近的电影。
|
||||
假定 k=3,则三个最靠近的电影依次是, He's Not Really into Dudes 、 Beautiful Woman 和 California Man。
|
||||
k-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。
|
||||
现在根据上面我们得到的样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到 k 个距离最近的电影。
|
||||
假定 k=3,则三个最靠近的电影依次是, He's Not Really into Dudes 、 Beautiful Woman 和 California Man。
|
||||
knn 算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。
|
||||
```
|
||||
|
||||
> k-近邻算法的一般流程
|
||||
## KNN 原理
|
||||
|
||||
> KNN 工作原理
|
||||
|
||||
1. 假设有一个带有标签的样本数据集(训练样本集),其中包含每条数据与所属分类的对应关系。
|
||||
2. 输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较。
|
||||
1. 计算新数据与样本数据集中每条数据的距离。
|
||||
2. 对求得的所有距离进行排序(从小到大,越小表示越相似)。
|
||||
3. 取前 k (k 一般小于等于 20 )个样本数据对应的分类标签。
|
||||
3. 求 k 个数据中出现次数最多的分类标签作为新数据的分类。
|
||||
|
||||
> KNN 一般流程
|
||||
|
||||
```
|
||||
收集数据:任何方法
|
||||
@@ -45,18 +45,7 @@
|
||||
使用算法:输入样本数据和结构化的输出结果,然后运行 k-近邻算法判断输入数据分类属于哪个分类,最后对计算出的分类执行后续处理
|
||||
```
|
||||
|
||||
> kNN算法伪代码
|
||||
|
||||
```
|
||||
对未知类别属性的数据集中的每个点依次执行以下操作:
|
||||
(1)计算已知类别数据集中的点与当前点之间的距离
|
||||
(2)按照距离递增次序排序
|
||||
(3)选取与当前点距离最小的 k 个点
|
||||
(4)确定前 k 个点所在类别的出现频率
|
||||
(5)返回前 k 个点出现频率最高的类别作为当前点的预测分类
|
||||
```
|
||||
|
||||
> k-近邻算法的特点
|
||||
> KNN 算法特点
|
||||
|
||||
```
|
||||
优点:精度高、对异常值不敏感、无数据输入假定
|
||||
@@ -64,22 +53,31 @@
|
||||
适用数据范围:数值型和标称型
|
||||
```
|
||||
|
||||
## 从文本文件中解析和导入数据
|
||||
## KNN 项目实战
|
||||
|
||||
描述:海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她并不是喜欢每一个人.经过一番总结,她发现曾交往过三种类型的人:
|
||||
### 项目实战1: 优化约会网站的配对效果
|
||||
|
||||
> 概述:
|
||||
|
||||
海伦使用约会网站寻找约会对象。经过一段时间之后,她发现曾交往过三种类型的人:
|
||||
* 不喜欢的人
|
||||
* 魅力一般的人
|
||||
* 极具魅力的人
|
||||
|
||||
尽管发现了上述规律,但是海伦依然无法将约会网站推荐的匹配对象归入恰当的类别。她觉得可以在周一到周五约会那些魅力一般的人,而周末则更喜欢与那些极具魅力的人为伴。海伦希望我们的分类软件可以更好地帮助她将匹配对象划分到确切的分类中。此外海伦还收集了一些约会网站未曾记录的数据信息。她认为这些数据更有助于匹配对象的归类。
|
||||
她希望:
|
||||
1. 工作日与魅力一般的人约会
|
||||
2. 周末与极具魅力的人约会
|
||||
3. 不喜欢的人则直接排除掉
|
||||
|
||||
海伦收集约会数据已经有一段时间,她把这些数据存放在文本文件 datingTestSet2.txt 文件中,每个样本数据占据一行,总共有 1000 行。海伦的样本主要包含以下 3 种特征:
|
||||
现在她收集到了一些约会网站未曾记录的数据信息,这更有助于匹配对象的归类。
|
||||
|
||||
海伦把这些约会对象的数据存放在文本文件 [datingTestSet2.txt](https://github.com/apachecn/MachineLearning/blob/master/input/2.KNN/datingTestSet2.txt) 中,总共有 1000 行。海伦约会的对象主要包含以下 3 种特征:
|
||||
|
||||
* 每年获得的飞行常客里程数
|
||||
* 玩视频游戏所耗时间百分比
|
||||
* 每周消费的冰淇淋公升数
|
||||
|
||||
> 示例:使用 k-近邻算法改进约会网站的配对效果
|
||||
> 使用 KNN 改进约会网站的配对效果
|
||||
|
||||
```
|
||||
收集数据:提供文本文件
|
||||
@@ -92,9 +90,9 @@
|
||||
使用算法:产生简单的命令行程序,然后海伦可以输入一些特征数据以判断对方是否为自己喜欢的类型。
|
||||
```
|
||||
|
||||
> 将文本记录转换为 NumPy 的解析程序
|
||||
* 将文本记录转换为 NumPy 的解析程序:
|
||||
|
||||
```Python
|
||||
```Python
|
||||
def file2matrix(filename):
|
||||
fr = open(filename)
|
||||
arrayOLines = fr.readlines()
|
||||
@@ -111,15 +109,7 @@ def file2matrix(filename):
|
||||
return returnMat,classLabelVector
|
||||
```
|
||||
|
||||
> NumPy 数组和 Python 数组
|
||||
|
||||
```
|
||||
本教程以后将大量使用 NumPy 数组,你既可以直接在 Python 命令行环境中输入 from numpy import array 将其导入,
|
||||
也可以通过直接导入所有 NumPy 库内容来将其导入。由于 NumPy 库提供的数组操作并不支持 Python 自带的数组类型,因此在编写代码时要注意不要使用错误的数组类型。
|
||||
```
|
||||
|
||||
|
||||
## 使用 Matplotlib 创建扩散图
|
||||
* 使用 Matplotlib 创建散点图
|
||||
|
||||
```Python
|
||||
import matplotlib
|
||||
@@ -130,22 +120,13 @@ ax.scatter(datingDataMat[:, 1], datingDataMat[:, 2])
|
||||
plt.show()
|
||||
```
|
||||
|
||||
## 归一化数值(将数值转化到:0~1之间)
|
||||
[完整代码地址](https://github.com/apachecn/MachineLearning/blob/master/src/python/10.kmeans/kMeans.py): <https://github.com/apachecn/MachineLearning/blob/master/src/python/10.kmeans/kMeans.py>
|
||||
|
||||
样本 3 和样本 4 的距离:
|
||||
$$\sqrt{(0-67)^2 + (20000-32000)^2 + (1.1-0.1)^2 }$$
|
||||
> 优化点
|
||||
|
||||
我们很容易发现: 上面方程中数字差值最大的属性对计算结果的影响最大。所以我们进行归一化处理是必不可少的。<br>
|
||||
归一化是一个让权重变为统一的过程,更多细节请参考: https://www.zhihu.com/question/19951858
|
||||
|
||||

|
||||
|
||||
## 总结
|
||||
|
||||
* k-近邻算法其实就是根据空间两个向量距离来判断类别,关键的是引入 k 值,保证了一定的稳定性,很明显的缺点就是每次都要与所有样本数据进行对比。
|
||||
* 文中处理约会数据时,归一化的方法是对于消除影响十分重要的
|
||||
* 阅读本章之前建议阅读一下 numpy 的文档
|
||||
* [numpy 英文文档](https://docs.scipy.org/doc/numpy-dev/user/quickstart.html "NumPy 英文文档")
|
||||
* [numpy 中文文档](http://old.sebug.net/paper/books/scipydoc/numpy_intro.html "NumPy 中文文档")
|
||||
### 项目实战2: 手写数字识别系统
|
||||
|
||||
* * *
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 268 KiB |
Reference in New Issue
Block a user