#%% md
# K-近邻算法(KNN)
#%% md
K nearest neighbour
#%% md
## 0、导引
#%% md
### 如何进行电影分类 众所周知,电影可以按照题材分类,然而题材本身是如何定义的?由谁来判定某部电影属于哪 个题材?也就是说同一题材的电影具有哪些公共特征?这些都是在进行电影分类时必须要考虑的问 题。没有哪个电影人会说自己制作的电影和以前的某部电影类似,但我们确实知道每部电影在风格 上的确有可能会和同题材的电影相近。那么动作片具有哪些共有特征,使得动作片之间非常类似, 而与爱情片存在着明显的差别呢?动作片中也会存在接吻镜头,爱情片中也会存在打斗场景,我们 不能单纯依靠是否存在打斗或者亲吻来判断影片的类型。但是爱情片中的亲吻镜头更多,动作片中 的打斗场景也更频繁,基于此类场景在某部电影中出现的次数可以用来进行电影分类。
#%% md
## 1、k-近邻算法原理
#%% md
简单地说,K-近邻算法采用测量不同特征值之间的距离方法进行分类。
#%% md
- 优点:精度高、对异常值不敏感、无数据输入假定。 - 缺点:时间复杂度高、空间复杂度高。 - 适用数据范围:数值型和标称型。
#%% md
### 工作原理
#%% md
存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据 与所属分类的对应关系。输人没有标签的新数据后,将新数据的每个特征与样本集中数据对应的 特征进行比较,然后算法提取样本集中特征最相似数据(最近邻)的分类标签。一般来说,我们 只选择样本数据集中前K个最相似的数据,这就是K-近邻算法中K的出处,通常*K是不大于20的整数。 最后 ,选择K个最相似数据中出现次数最多的分类,作为新数据的分类*。
#%% md
回到前面电影分类的例子,使用K-近邻算法分类爱情片和动作片。有人曾经统计过很多电影的打斗镜头和接吻镜头,下图显示了6部电影的打斗和接吻次数。假如有一部未看过的电影,如何确定它是爱情片还是动作片呢?我们可以使用K-近邻算法来解决这个问题。
![1.PNG](attachment:1.PNG)
#%% md
首先我们需要知道这个未知电影存在多少个打斗镜头和接吻镜头,上图中问号位置是该未知电影出现的镜头数图形化展示,具体数字参见下表。
![2.PNG](attachment:2.PNG)
#%% md
即使不知道未知电影属于哪种类型,我们也可以通过某种方法计算出来。首先计算未知电影与样本集中其他电影的距离,如图所示。
![3.PNG](attachment:3.PNG)
#%% md
现在我们得到了样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到K个距 离最近的电影。假定k=3,则三个最靠近的电影依次是California Man、He's Not Really into Dudes、Beautiful Woman。K-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。
#%% md
### 欧几里得距离(Euclidean Distance)
#%% md
欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:
![4.png](attachment:4.png)
#%% md
## 2、在scikit-learn库中使用k-近邻算法
#%% md
- 分类问题:from sklearn.neighbors import KNeighborsClassifier
- 回归问题:from sklearn.neighbors import KNeighborsRegressor
#%% md
### 0)一个最简单的例子
#%% md
身高、体重、鞋子尺码数据对应性别
#%%
import numpy as np
#%%
from sklearn.neighbors import KNeighborsClassifier
#%%
X_train = np.array([[175,65,43],[160,50,37],[180,75,44],[175,55,40],[165,65,41]])
y_labels = ['男','女','男','女','男']
knn = KNeighborsClassifier()
#%%
knn.fit(X_train,y_labels)
#%%
#进行预测 x_test = np.array([[172,68,42]])
knn.predict(x_test)
#%% md
### 1)用于分类
#%% md
导包,机器学习的算法KNN、数据蓝蝴蝶
#%%
import sklearn.datasets as datasets
#%%
iris = datasets.load_iris() iris
#%%
#获取数据
data = iris.data target = iris.target
#%%
#导入拆分的工具 from sklearn.model_selection import train_test_split #让计算机学习一部分数据,另一部分,计算机没有接触过
#让计算机预测没有接触的数据,分类,识别这些数据
#%%
X_train,x_test,y_train,y_test = train_test_split(data,target,test_size = 0.1)
#%%
#训练 knn = KNeighborsClassifier(n_neighbors= 10) knn.fit(X_train,y_train)
#%%
#预测数据 knn.predict(x_test)
#%%
#真实的结果 y_test
#%%
x_test.shape
#%%
knn.score(x_test,y_test)
#%%
knn.score(data,target)
#%% md
获取训练样本
#%%
data.shape
#%%
data = iris.data
#%%
data = data[:,:2] data
#%% md
绘制图形
#%%
import matplotlib.pyplot as plt %matplotlib inline
#%%
target
#%%
#c = target 代表分类 plt.scatter(data[:,0],data[:,1],c = target,cmap = 'rainbow')
#%% md
定义KNN分类器
#%%
knn = KNeighborsClassifier(10)
#%% md
第一步,训练数据
#%%
# 训练处理之后的数据data
knn.fit(data,target)
#%% md
第二步预测数据:,所预测的数据,自己创造,就是上面所显示图片的背景点
生成预测数据
#%%
#提取x,y轴的范围 x_min,x_max = data[:,0].min(),data[:,0].max()
y_min,y_max = data[:,1].min(),data[:,1].max()
x = np.linspace(x_min,x_max,1000) y = np.linspace(y_min,y_max,650)
#np.meshgrid X,Y = np.meshgrid(x,y)
#%%
display(X.shape,Y.shape)
#%%
# X Y 就是图像中所有的点,交叉融合 #np.c_[]
a = [1,2,3] b = [-1,-2,-5] # np.c_[a,b]
#%%
c = np.array([[4.3,4.4,4.5,4.6],[4.3,4.4,4.5,4.6],[4.3,4.4,4.5,4.6]])
d = np.array([[2,2,2,2],[2.1,2.1,2.1,2.1],[2.2,2.2,2.2,2.2]]) #展开,变成1维 cc = c.ravel()
dd = d.ravel()
np.c_[cc,dd]
#%%
xy_test = np.c_[X.ravel(),Y.ravel()]
#%%
xy_test.shape
#%% md
对数据进行预测
#%%
y_ = knn.predict(xy_test)
#%% md
显示数据
#%%
plt.scatter(data[:,0],data[:,1],c = target)
#%%
plt.pcolormesh(X,Y,y_.reshape(X.shape))
plt.scatter(data[:,0],data[:,1],c = target,cmap = 'rainbow')
#%% md
### 2)用于回归 回归用于对趋势的预测
#%% md
导包
#%%
#%% md
生成样本数据
#%%
#%% md
生成测试数据的结果
#%%
#%% md
第一步:生成模型,并训练数据
#%%
#%% md
第二步:使用模型,预测数据
#%%
#%% md
绘图显示数据
#%%
#%%
#%% md
### 练习 人类动作识别 步行,上楼,下楼,坐着,站立和躺着 ![](stand-sit-run.jpg) 数据采集每个人在腰部穿着智能手机,进行了六个活动(步行,上楼,下楼,坐着,站立和躺着)。采用嵌入式加速度计和陀螺仪,以50Hz的恒定速度捕获3轴线性加速度和3轴角速度,来获取数据
#%% md
导入数据
#%%
#%% md
获取数据
#%%
#%% md
绘制
#%% md
## 3、作业
#%% md
#### 1、预测年收入是否大于50K美元
#%% md
读取adult.txt文件,最后一列是年收入,并使用KNN算法训练模型,然后使用模型预测一个人的年收入是否大于50
#%%
#%% md
获取年龄、教育程度、职位、每周工作时间作为机器学习数据 获取薪水作为对应结果
#%%
#%% md
数据转换,将String类型数据转换为int
#%% md
【知识点】map方法,进行数据转换
#%%
#%% md
切片:训练数据和预测数据
#%%
#%% md
生成算法
#%%
#%% md
第一步:训练数据
#%%
#%% md
第二步:预测数据
#%%
#%% md
保存训练模型 from sklearn.externals import joblib
#%%
#%% md
#### 2、小麦种类预测
#%% md
读取seeds.tsv文件,最后一列是小麦品种,其他列是小麦特征
#%% md
#### 3、改进约会网站的匹配效果
#%% md
读取datingTestSet.txt文件,最后一列是喜欢程度。模型:根据前几列的信息,预测喜欢程度