K-邻近算法(KNN)


分类解决离散问题,回归解决连续问题

导引:
如何进行电影分类
众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪 个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问 题。没有哪个电影人会说自己制作的电影和以前的某部电影类似,但我们确实知道每部电影在风格 上的确有可能会和同题材的电影相近。那么动作片具有哪些共有特征,使得动作片之间非常类似, 而与爱情片存在着明显的差别呢?动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们 不能单纯依靠是否存在打斗或者亲吻来判断影片的类型。但是爱情片中的亲吻镜头更多,动作片中 的打斗场景也更频繁,基于此类场景在某部电影中出现的次数可以用来进行电影分类。
本章介绍第一个机器学习算法:K-近邻算法,它非常有效而且易于掌握。


1 K-近邻算法原理
简单地说,K-近邻算法采用测量不同特征之间的距离方法进行分类。
优点:精度高·对异常值不敏感、无数据输入假定
缺点:时间复杂度高、空间复杂度高
适用数据范围:数值型和标称型

工作原理
存在一个样本数据集合,也成作训练本集,并且样本集中每个数据都存在标签
,即我们知道样本集中每一数据 与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的 特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们 只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常K是不大于20的整数。 最后 ,选择K个最相似数据中出现次数最多的分类,作为新数据的分类。

回到前面电影分类的例子,使用K-近邻算法分类爱情片和动作片。有人曾经统计过很多电影的打斗镜头和接吻镜头,下图显示了6部电影的打斗和接吻次数。假如有一部未看过的电影,如何确定它是爱情片还是动作片呢?我们可以使用K-近邻算法来解决这个问题。
1.PNG
首先我们需要知道这个未知电影存在多少个打斗镜头和接吻镜头,上图中问号位置是该未知电影出现的镜头数图形化展示,具体数字参见下表。
2.PNG
即使不知道未知电影属于哪种类型,我们也可以通过某种方法计算出来。首先计算未知电影与样本集中其他电影的距离,如图所示。
3.PNG
现在我们得到了样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到K个距 离最近的电影。假定k=3,则三个最靠近的电影依次是California Man、He's Not Really into Dudes、Beautiful Woman。K-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。
欧几里得距离(Euclidean Distance)
欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:
4.png
2、在scikit-learn库中使用k-近邻算法
分类问题:from sklearn.neighbors import KNeighborsClassifier
回归问题:from sklearn.neighbors import KNeighborsRegressor


K-近邻算法的一般流程
(1)收集数据 : 可以使用任何放大
(2)准备数据:距离计算所需要的数值,最好是结构化的数据格式。
(3)分析数据:可以使用任何方法
(4)训练算法:此步骤不适用于K-近邻算法
(5)测试算法:计算错误率
(6)使用算法:首先需要输入样本数据和机构化的输出结果,然后运行K-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理

一个最简单的例子

from sklearn.neighbors import KNeighborsClassifier #导入头文件

neigh = KNeighborsClassifier(n_neighbors=3)

X = [[181,80,44],[177,70,43],[160,60,38],[154,54,37],
[166,65,40],[190,90,47],[175,64,39],[177,70,40],
[159,55,37],[171,75,42],[181,85,43]]

Y = ['male','male','female','female','male','male','female','female','female','male','male']

# 第1步:训练数据
neigh.fit(X,Y)

# 第2步:预测数据
Z = neigh.predict([190,70,43])

display(Z)


用于分类

# 导入库:KNeighborsClassifier
import numpy as np
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap

# 导入sklearn自带数据集
from sklearn import datasets

# 得到训练样本
iris = datasets.load_iris()
X = iris.data[:,:2]
y = iris.target

# 设置K
K = 15

# 设置图片x,y轴的步长
h = 0.02

# 设置图片显示
cmap_light = ListedColormap(['#FFAAAA','#AAFFAA','#AAAAFF'])
cmap_bold = ListedColormap(['#FF0000','#00FF00','#0000FF'])

# 定义一个分类器
clf = KNeighborsClassifier(n_neighbors=K)

# 第1步:训练分类器
clf.fit(X,y)

# 图片的显示范围
x_min, x_max = X[:,0].min()-1, X[:,0].max()+1
y_min, y_max = X[:,1].min()-1, X[:,1].max()+1

# 图片的背景显示坐标
xx,yy = np.meshgrid(np.arange(x_min,x_max,h),
np.arange(y_min,y_max,h))

# 第2步:预测
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])

z = Z.reshape(xx.shape)

#plt.figure()
# 显示背景的颜色
plt.pcolormesh(xx,yy,z,cmap=cmap_light)

# 显示点的颜色
plt.scatter(X[:,0],X[:,1],c = y,cmap=cmap_bold)
plt.xlim(xx.min(),xx.max())
plt.ylim(yy.min(),yy.max())
plt.title('3-class classification')

plt.show()


用于回归
先生成样本数据

import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsRegressor

%matplotlib inline

# 设置随机种子,确保每次运行得到相同结果
np.random.seed(0)

X = np.sort(5*np.random.rand(40,1),axis = 0)
T = np.linspace(0,5,100)[:,np.newaxis]

y = np.sin(X).ravel()

y[::5] += 1*(0.5 - np.random.rand(8))

K = 5

# 定义一个KNN回归模型
knn = KNeighborsRegressor(n_neighbors=K)

# 第一步:训练数据
knn.fit(X,y)

# 第二步:预测数据
y_ = knn.predict(T)

# 画图
plt.scatter(X,y,c='k',label = 'data')
plt.plot(T,y_,c='g',label = 'prediction')
plt.axis('tight')
plt.legend()

yy = knn.predict(2)
display(yy)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值