02-16 k近邻算法

[TOC] 更新、更全的《机器学习》的更新网站,更有python、go、数据结构与算法、爬虫、人工智能教学等着你:http://www.javashuo.com/article/p-vozphyqp-cm.htmlhtml

k近邻算法

k近邻算法(k-nearest neighbors,KNN)是一种基本的分类和回归方法,本文只探讨分类问题中的k近邻算法,回归问题一般是得出最近的$k$个实例的标记值,而后取这$k$实例标记值的平均数或中位数。python

k近邻算法常常被人们应用于生活当中,好比傅玄曾说过“近朱者赤近墨者黑”,还有人曾说过“若是要判断一我的的品性,只须要看看他身边朋友的品性便可”,这些都是用了k近邻算法的思想。算法

本文主要介绍k近邻算法的基本理论以及k近邻的扩展——限定半径最近邻算法和最近质心算法,以后会使用k近邻算法对鸢尾花数据进行分类,并讲解scikit-learn库中k近邻算法各个参数的使用。为了解决k近邻算法须要大量计算的问题在这以后会讲解kd树(KDTree)。数据结构

1、k近邻算法学习目标

  1. k近邻算法三要素
  2. 维数诅咒
  3. k近邻算法流程
  4. k近邻算法优缺点

2、k近邻算法引入

不知道同窗们在看电影的时候有没有思考过你是如何判断一部电影是爱情片仍是动做片的,你能够停下来想一想这个问题再往下看看个人想法。机器学习

我说说我是如何判断一部电影是爱情片仍是动做片的,首先绝对不是靠那些预告片,毕竟预告片过短了,爱情片的预告多是动做片,动做片的预告多是爱情片也说不定。学习

相比较预告片我用了一个很愚蠢很繁琐但颇有效的方法。首先我用一部电影的接吻镜头的次数做为$x$轴,打斗的场景次数做为$y$轴生成了一个二维空间,即平面图,以下图所示。(注:如下电影的接吻镜头次数和打斗场景次数都是假设的)测试

# k近邻算法引入图例
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
%matplotlib inline
font = FontProperties(fname='/Library/Fonts/Heiti.ttc')

# 动做片
plt.scatter(2, 10, marker='o', c='r', s=50)
plt.text(2, 9, s='《战狼2》(2,10)', fontproperties=font, ha='center')
plt.scatter(4, 12, marker='o', c='r', s=50)
plt.text(4, 11, s='《复仇者联盟2》(4,12)', fontproperties=font, ha='center')
plt.scatter(2, 15, marker='o', c='r', s=50)
plt.text(2, 14, s='《猩球崛起》(2,15)', fontproperties=font, ha='center')

# 爱情片
plt.scatter(10, 4, marker='x', c='g', s=50)
plt.text(10, 3, s='《泰坦尼克号》(10,4)', fontproperties=font, ha='center')
plt.scatter(12, 2, marker='x', c='g', s=50)
plt.text(12, 1, s='《致咱们终将逝去的青春》(12,2)', fontproperties=font, ha='center')
plt.scatter(15, 5, marker='x', c='g', s=50)
plt.text(15, 4, s='《谁的青春不迷茫》(15,5)', fontproperties=font, ha='center')

# 测试点
plt.scatter(5, 6, marker='s', c='k', s=50)
plt.text(5, 5, s='《未知类型的电影》(5,6)', fontproperties=font, ha='center')


plt.xlim(0, 18)
plt.ylim(0, 18)
plt.xlabel('接吻镜头(次)', fontproperties=font)
plt.ylabel('打斗场景(次)', fontproperties=font)
plt.title('k近邻算法引入图例', fontproperties=font, fontsize=20)
plt.show()

![png](http://www.chenyoude.com/ml/02-16 k近邻算法_6_0.png?x-oss-process=style/watermark)网站

经过上图咱们能够发现动做片《战狼2》的打斗场景次数明显多于接吻镜头,而爱情片《泰坦尼克号》的接吻镜头明显多于打斗场景,而且其余的动做片和爱情片都有这样的规律,所以我作了一个总结:爱情片的接吻镜头次数会明显比打斗的场景次数多,而动做片反之。人工智能

经过上述的总结,若是我再去看一部新电影的时候,我会在内心默数这部电影的接吻镜头的次数和打斗场景,而后再去判断。这种方法看起来无懈可击,可是若是碰到了上述黑点《未知类型的电影》所在的位置,即当接吻镜头次数和打斗场景次数差很少的时候,每每很难判断它是爱情片仍是动做片。spa

这个时候咱们的主角k近邻算法就应该出场了,由于使用k近邻算法能够很好的解决《未知类型的电影》这种尴尬的情形。

  1. 假设咱们把平面图中的每个电影当作一个点,例如《战狼2》是$(2,10)\(、《未知类型的电影》是\)(5,6)\(、《泰坦尼克号》是\)(10,4)$……
  2. 咱们使用k近邻的思想,经过欧几里得距离公式计算出每一部电影在平面图中到《未知类型的电影》的距离
  3. 而后假设$k=4$,即获取离《未知类型的电影》最近的$4$部电影
  4. 若是这$4$部电影中爱情片类型的电影多,则《未知类型的电影》是爱情片;若是动做片类型的电影多,则《未知类型的电影》是动做片;若是两种类型的电影数量同样多,则另选$k$值

上述整个过程其实就是k近邻算法实现的一个过程,接下来将从理论层面抽象的讲解k近邻算法。

3、k近邻算法详解

k近邻算法简而言之就是给定一个有$m$个实例的数据集$T={(x_1,y_1),(x_2,y_2),\cdots,(x_m,y_m)}$,计算出将来新样本到每一个实例的距离,而后找到与将来新数据最近的$k$个实例,这$k$个实例哪一个类别的实例多,则将来新样本属于哪一个类别,基于这个解释能够给出k近邻算法的三个基本要素。

3.1 k近邻算法三要素

k近邻算法的三个基本要素分别是$k$值的选择、距离度量的方式和分类决策的规则,只要这三点肯定了,则k近邻算法也就肯定了。

3.1.1 k值的选择

k近邻算法对于$k$值的选择,通常没有一个固定的选择,对于不一样的问题一般可能有不一样的$k$值。可是须要注意的是若是$k$值取的越大,则离将来新样本的实例会愈来愈多,即较远的实例也会对结果形成影响,从而使得模型欠拟合,可是模型会变得简单;反之只有较少的实例会对结果形成影响,模型会变得复杂,同时会使得模型容易发生过拟合现象。而且须要注意的是$k$值通常小于20。

例如当$k$值取$m$的时候,模型会简单到不管将来新样本输入什么,预测结果都是训练集中实例最多的类。

3.1.2 最近邻算法

当$k=1$的时候,称为最近邻算法,即对于将来新样本,最近邻算法将训练集中与将来新样本最邻近点的类别做为将来新样本的类别。

3.1.3 距离度量的方式

k近邻算法对于距离度量的方式,有不少种方法能够选择,通常选择咱们电影分类例子中讲到的欧几里得距离,也称做欧氏距离。同时还可能会使用曼哈顿距离或闵可夫斯基距离,这里统一给出它们的公式。

假设$n$维空间中有两个点$x_i$和$x_j$,其中$x_i = (x_i^{(1)},x_i^{(2)},\cdots,x_i^{(n)})$,\(x_j = (x_j^{(1)},x_j^{(2)},\cdots,x_j^{(n)})\)

欧氏距离为

\[ d(x_i,x_j) = \sqrt{\sum_{l=1}^n(x_i^{(l)}-x_j^{(l)})^2} \]

曼哈顿距离为

\[ d(x_i,x_j) = \sum_{l=1}^n|x_i^{(l)}-x_j^{(l)}| \]

闵可夫斯基距离为

\[ d(x_i,x_j) = \sqrt[p]{\sum_{l=1}^n(|x_i^{(l)}-x_j^{(l)}|)^p} \]

其中曼哈顿距离是闵可夫斯基距离$p=2$时的特例,而欧氏距离是闵可夫斯基距离$p=1$时的特例。

3.1.4 分类决策规则

k近邻算法对于分类决策规则,通常选择电影分类例子中讲到的多数表决法,即$k$个实例中拥有最多实例的类别即为将来新样本的类别。例如假设获得距离《未知类型的电影》最近的$10$部电影中,有$3$部属于$c_1$类;有$3$部属于$c_2$类;有$4$部是$c_3$类,则能够判断《未知类型的电影》属于$c_3$类。

值得注意的是使用k近邻算法解决回归问题时,分类决策的规则一般是对$k$个实例的标记值取平均值或中位数。例如距离将来新样本的最近的$3$个实例的标记值分别为${2.3,2.7,1.0}\(,则能够获得将来新样本的标记值为\){\frac{2.3+2.7+1.0}{3}}=2$。

3.2 维数诅咒

维数诅咒的意思是:当训练集特征维度愈来愈大的时候,特征空间愈来愈稀疏,经过距离度量的方式能够发现即便是最近的邻居在高维空间的距离也很远,以致于很难估计样本之间的距离。

通常状况下可使用特征选择和降维等方法避免维数诅咒。

4、k近邻算法的拓展

4.1 限定半径k近邻算法

限定半径k近邻算法顾名思义就是限定一个距离范围搜索$k$个近邻,经过限定距离范围能够解决数据集中实例太少甚至少于$k$的问题,这样就不会把距离目标点较远的实例也划入$k$个实例当中。

4.2 最近质心算法

最近质心算法是将全部实例按照类别归类,归类后对$c_k$类的全部实例的$n$维特征的每一维特征求平均值,而后由每一维特征的平均值造成一个质心点,对于样本中的全部类别都会对应得到一个质心点。

每当将来新样本被输入时,则计算将来新样本到每个类别对应质心点的距离,距离最近的则为该将来新样本的类别。

5、k近邻算法流程

5.1 输入

有$m$个实例$n$维特征的数据集

\[ T=\{(x_1,y_1),(x_2,y_2),\cdots,(x_m,y_m)\} \]

其中$x_i$是实例的特征向量即$({(1)},{(2)},\cdots,^{(n)})$,$y_i$是实例的类别,数据集有${c_1,c_2,\cdots,c_j}$共$j$个类别。

5.2 输出

将来新样本$(x_i,y_i), \quad (i=1,2,\cdots,m)$的类别$c_l, \quad (l=1,2,\cdots,j)$。

5.3 流程

  1. 根据给定的距离度量方式,计算出训练集$T$中与将来新样本$(x_i,y_i)$最邻近的$k$个实例
  2. 使用分类决策规则(如多数表决法)决定将来新样本$(x_i,y_i)$的类别为$c_l$;若是是回归问题,取$𝑘$个近邻点的标记值的平均数或中位数便可。

6、k近邻算法优缺点

6.1 优势

  1. k近邻算法简单易懂,容易实现,能够作分类也能够作回归
  2. k近邻算法基于实例学习,对数据没有假设,不须要经过模型训练得到参数

6.2 缺点

  1. 计算复杂度高、空间复杂度高,例如当训练集有10000个样本的时候,须要计算5000万次,再加上实例的特征维度有时候也是极高的,这种计算量对于计算机而言也是很庞大的(若是样本数量过多则可能须要换算法换模型,若是特征过多可使用降维算法)
  2. 不管哪种距离度量方式都须要使用到特征值之间的差值,若是某些特征值之间的差值过大会掩盖差值较小特征对预测值的影响(通常使用数据预处理中的归一化方法处理特征值)
  3. 相比较决策树,解释型不强(客户真的想要解释性强的模型换个决策树试一试)

7、小结

除了咱们讲的第一个古老的机器学习算法感知机,k近邻算法应该是目前工业上还会使用最为简单的算法,而且使用起来也很简单、方便,可是有个前提是数据量不能过大,更不能使用有维数诅咒的数据集。

k近邻遇到数据量大的数据集计算量是一个很难解决的问题,那么有没有什么好的方法能稍微减轻这个问题呢?有是必定有的,即下一篇——kd树。

相关文章
相关标签/搜索