Python高级--K-近邻算法(KNN)

文中数据下载

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

这里写图片描述

一、K-近邻算法(KNN)举例

这里写图片描述

1)工作原理

存在一个样本数据集合,也称作训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一数据

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

2)算法实例

回到前面电影分类的例子,使用K-近邻算法分类爱情片和动作片。有人曾经统计过很多电影的打斗镜头和接吻镜头,下图显示了6部电影的打斗和接吻次数。假如有一部未看过的电影,如何确定它是爱情片还是动作片呢?我们可以使用K-近邻算法来解决这个问题。
这里写图片描述

首先我们需要知道这个未知电影存在多少个打斗镜头和接吻镜头,上图中问号位置是该未知电影出现的镜头数图形化展示,具体数字参见下表。

这里写图片描述

即使不知道未知电影属于哪种类型,我们也可以通过某种方法计算出来。首先计算未知电影与样本集中其他电影的距离,如图所示。这里写图片描述

现在我们得到了样本集中所有电影与未知电影的距离,按照距离递增排序,可以找到K个距
离最近的电影。假定k=3,则三个最靠近的电影依次是California Man、He’s Not Really into Dudes、Beautiful Woman。K-近邻算法按照距离最近的三部电影的类型,决定未知电影的类型,而这三部电影全是爱情片,因此我们判定未知电影是爱情片。

3)欧几里得距离(Euclidean Distance)

欧氏距离是最常见的距离度量,衡量的是多维空间中各个点之间的绝对距离。公式如下:
这里写图片描述

二、在scikit-learn库中使用k-近邻算法

  • 分类问题:from sklearn.neighbors import KNeighborsClassifier

  • 回归问题:from sklearn.neighbors import KNeighborsRegressor

三、简单示例(分类)

给出一组数据(身高、体重、鞋子尺码)判断性别

分析:这是一个使用K-临近算法(KNN)的分类问题

1)创建训练数据(特征和结果)

1.训练样本的特征

注意:这里的特征需要和结果一一对应

'''
X_train:训练样本的特征(一列值)
y_train:训练样本的结果(标签)
'''
# 传入训练数据  
#  身高,体重, 鞋码
X_train = np.array([
    [177,73,42],
    [150,44,36],
    [177,63,41],
    [160,52,35],
    [165,70,40],
    [179,80,44],
    [156,40,36],
    [155,50,36]
])
# 一一传入训练数据的样本结果
y_train = np.array(['male','female','male','female','male','male','female','female'])

2)创建 获取分类的模型

KNeighborsClassifier(n_neighbors=5)
功能:实现k近邻投票的分类器。

# n_neighbors:获取最近的几个  默认是5个
knn_c = KNeighborsClassifier(n_neighbors=5)

3)模型训练

knn.fit(X, y)
功能:将训练数据的特征和结果传入进行训练
以X为训练数据,y为目标值 拟合模型

'''
参数 X 是训练数据的特征
参数 y 是训练数据的结果(标签)
'''
knn_c.fit(X_train,y_train)

4)模型测试

knn.predict(X)
功能:通过训练好的模型将测试数据传入,返回测试结果
为提供的数据预测类标签

knn_c.predict([
    [190,100,45],
    [150,35,32]
])

array(['male', 'female'], dtype='<U6')

5)得出结果

返回测试结果与实际数据符合实际情况,这就是K-近邻算法(KNN)处理分类问题

四、机器学习–鸢尾花(分类)

机器学习常用库sklearn

scikit-learning 提供数据样本,可以供我们研究机器学习模型

# 机器学习里面包含的数据集
from sklearn import datasets

1)获取训练数据(特征和结果)

使用load方法加载数据可以加载很多可供我们使用的数据
这里我们使用鸢尾花数据

iris_data = datasets.load_iris()
iris_data

#这里返回数据较多,我们拿出部分分析
# data:鸢尾花样本,该样本有四个特征,表示 花萼长度 花萼宽度 花瓣长度 花瓣宽度
# target:表示鸢尾花的种类 0(setosa) 1(versicolor) 2(virginica)
{'data': array([[5.1, 3.5, 1.4, 0.2],
        [4.9, 3. , 1.4, 0.2],
        [4.7, 3.2, 1.3, 0.2],
        [4.6, 3.1, 1.5, 0.2],
        。。。
        [6.5, 3. , 5.2, 2. ],
        [6.2, 3.4, 5.4, 2.3],
        [5.9, 3. , 5.1, 1.8]]),
 'target': array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]),}
        #还有一些描述的信息

我们获取的iris_data是一个字典类型的数据

1. 获取训练样本特征

data = iris_data.data        #训练样本的值
feature = iris_data.feature_names  #训练样本的值对应的名称

2. 获取训练样本结果

target = iris_data.target  # 所有样本的目标值
target_names = iris_data.target_names  # 目标值对应的名称

3. 将得到的数据绘制图形

DataFrame(data).plot()

这里写图片描述


画图研究前两个特征和分类之间的关系

(二维散点图只能展示两个维度)

1、这里截取前两个特征来展示

X_train = data[:,0:2]  # 训练样本的特征
y_train = target  # 训练样本的结果
#目前取得样本特征和结果依旧是一一对应的关系

2、展示特征和结果之间的关系

花萼长度为x, 花萼宽度为y 对所有样本进行定位

我们使用点的颜色对其进行分类,散点图参数c可以传入一个数组,数组我们可以用样本的值使传入的x, y对应的点得颜色与值一一对应,这样就将图中的点分为三类区分开

plt.scatter(X_train[:,0],X_train[:,1],c=y_train)
plt.xlabel('sepal length')  #设置x轴的标签
plt.ylabel('sepal width')  #设置y轴的标签

这里写图片描述

2)创建 获取分类的模型

创建分类模型

knn_c = KNeighborsClassifier(n_neighbors=5)

3)模型训练

将训练数据样本特征和结果放入模型训练

knn_c.fit(X_train,y_train)

4)模型测试

将测试数据传入训练模型,返回训练结果

knn_c.predict([
    [4.5,4.0],
    [7.5,3.0],
    [5.25,2.25]
])

array([0, 2, 1])

4)测试结果分析

测试数据的预测结果与实际结果相同

5)创造测试数据,测试模型结果

1、创造测试数据

先取到x轴线的范围和y轴的范围取到

# 为了全面,将数据的范围稍微扩大一点
xmin = X_train[:,0].min()-0.5   
xmax = X_train[:,0].max()+0.5
ymin = X_train[:,1].min()-0.5
ymax = X_train[:,1].max()+0.5

将x轴的数据和y轴的数据每隔 0.01 取一份

# x轴范围内要取遍
x = np.arange(xmin,xmax,0.01)
# y轴范围内也要取遍
y = np.arange(ymin,ymax,0.01)
#我们拿到坐标轴的数据之后,我们要拿到每个点的坐标

拿到每个点对应的x,y坐标

xx,yy = np.meshgrid(x,y)     # 将画布上所有的点取遍

这里写图片描述

xx.flatten(),yy.flatten()    # 将矩阵扁平化

(array([3.8 , 3.81, 3.82, ..., 8.38, 8.39, 8.4 ]),
 array([1.5, 1.5, 1.5, ..., 4.9, 4.9, 4.9]))

这里写图片描述

# 把对应位置的两个内容取出来 变成新的列表
X_test = np.c_[xx.flatten(),yy.flatten()] # 将平面上所有的点取遍 并 用来作为测试数据

array([[3.8 , 1.5 ],
       [3.81, 1.5 ],
       [3.82, 1.5 ],
       ...,
       [8.38, 4.9 ],
       [8.39, 4.9 ],
       [8.4 , 4.9 ]])

这里写图片描述

2、使用刚刚训练好的模型进行预测

y_ = knn_c.predict(X_test)  #预测后返回预测结果值

3、绘制测试结果图形

根据特征绘制样本的两个特征 X_test[:,0],X_test[:,1]
根据模型预测的结果 y_
绘制样本的颜色


plt.scatter(X_test[:,0],X_test[:,1],c=y_) 

这里写图片描述

4、将训练数据和自己创建的测试数据作比较

把真实的训练数据也画到图上

plt.scatter(X_test[:,0],X_test[:,1],c=y_)
plt.scatter(X_train[:,0],X_train[:,1],c=y_train,cmap=cmap0) #这里的cmap给color设置颜色

这里写图片描述

5、为图像制定颜色

需要导入

from matplotlib.colors import ListedColormap
cmap0 = ListedColormap(['red','green','blue'])
# 将cmap0传入上面的图的效果

五、预测趋势(回归)

导包

from sklearn.neighbors import KNeighborsRegressor

1)生成训练样本数据

1、种子生成器

功能:固定随机数,多次执行,产生相同的随机数
np.random.seed(0)

np.random.seed(0)
np.random.random()
nd = np.random.rand(40,1)  #  样本 40行1列
nd

2、对生成的训练数据排序np.sort

np.sort() 默认对最内层的数据进行排序 现在要对每一行进行排序 让样本从小到大排列
设置 np.sort(nd,axis=0)

对nd进行排序 然后放大5倍数

X_train = 5*np.sort(nd,axis=0)

3、训练数据值

结果集 是一个一维数组,所以在这里要将他改变

y_train = np.sin(X_train).flatten()

2)绘制训练数据

plt.scatter(X_train,y_train)

这里写图片描述

3)添加噪声

给y_train添加一些噪声 让x和y的关系不要那么明确

我们的训练数据为 40 行一列的数据,我们每隔4个给加一个随机噪声

1、制造噪声

noise = np.random.random(size=10)/2
noise

array([0.2343256 , 0.48838054, 0.30242276, 0.36963179, 0.0195939 ,
       0.14140348, 0.06009828, 0.1480701 , 0.05936386, 0.15899159])

2、添加噪声

每隔4个加一个噪声

y_train[::4] += noise

2、添加噪声后的图形

plt.scatter(X_train,y_train)

这里写图片描述

4)生成模型

from sklearn.neighbors import KNeighborsRegressor
# 获取模型
knn = KNeighborsRegressor(n_neighbors=30)

5)训练数据

把训练数据传入模型,
x:训练样本特征
y:训练样本值

'''
# X_train是多行数据 有几个样本就有几行 有几个特征就有几列
# y_train 是一个一维的数组 里面直接装着结果值
'''
knn.fit(X_train,y_train)

6)创建测试数据

把x范围内的值取遍 然后用机器学习模型获取y_
这里的样本数据为一列,所以绘图时不用调整坐标(相对于上面鸢尾花来说)。

xmin = X_train.min()
xmax = X_train.max()
X_test = np.arange(xmin,xmax,0.01)

7)测试样本值

注意,有一个特征,传入的样本值应该为n行1列

y_ = knn.predict(X_test.reshape(-1,1))

8)绘图显示数据

plt.plot(X_test,y_,color='green',label='predict')  #设置颜色和图标
plt.scatter(X_train,y_train,label='real',color='k')
plt.legend()  #显示图标

这里写图片描述

六、人类动作识别

1) 数据保存np.save(保存路径, 数据)

1)保存*.npy数据文件np.save

nd = np.array([1,2,3])
nd
# np.save方法可以把数据保存到本地 参数 1.是路径 2.是数据
np.save('./test',nd)  #这里可以不输入文件后缀

2)加载*.npy数据文件np.load(”文件路径”)

np.load('./test.npy') 

array([1, 2, 3])

2) 导入训练集和测试集

1、导入数据

X_train = np.load('./data/x_train.npy')
y_train = np.load('./data/y_train.npy')

2、查看数据信息

X_train.shape

(7352, 561)  #数据有 7352行,561列
y_train.size

7352
Series(y_train).unique()

array([5, 4, 6, 1, 3, 2], dtype=int64)
'''
这里训练结果集代表的运动类型
    1:'walking',              #走
    2:'walking upstairs',     #上楼
    3:'walking downstairs',   #下楼
    4:'sitting',              #坐着
    5:'standing',             #站着
    6:'laying'                #躺着
'''

3、画图查看各个特征的图形

我们随机抽查 第100,200,300,400,500,600个样本查看训练样本的结果

n = 100
y_train[n]
labels[y_train[n]]

'walking'
------------------------
n = 200
y_train[n]
labels[y_train[n]]

'standing'
------------------------
n = 300
y_train[n]
labels[y_train[n]]

'walking downstairs'
------------------------
n = 400
y_train[n]
labels[y_train[n]]

'sitting'
------------------------
n = 500
y_train[n]
labels[y_train[n]]

'walking upstairs'
------------------------
n = 600
y_train[n]
labels[y_train[n]]

'laying'

我们可以看出抽取的这 6 个数据将全部类型的取出来,我们将这6个训练样本绘图展示观察

plt.figure(figsize=(20,10))  #设置画布大小
for i in [1,2,3,4,5,6]:
    axes = plt.subplot(3,2,i)  #创建子画布
    axes.plot(X_train[i*100],color=colors[i-1])  #在子画布上画图
    axes.set_title(labels[y_train[i*100]])  设置子画布的标题

这里写图片描述

3) 训练模型

1、创建训练模型

knn = KNeighborsClassifier(n_neighbors=5)

2、训练数据

传入训练数据与训练结果

knn.fit(X_train,y_train)

3、

4、

4) 模型预测

y_ = knn.predict(X_test)

array([5, 5, 5, ..., 2, 2, 1], dtype=int64)

5) 预测准确率

1、自己计算

将预测值与测试值相等,得出预测正确的个数

y_ == y_test  # 获取的是布尔值的序列 相等的是True 不想等是False

array([ True,  True,  True, ...,  True,  True, False])

测试结果个数与预测结果个数

(y_ == y_test).sum()

2657

y_test.size

2947

两者相乘

(y_ == y_test).sum() / y_test.size

0.9066847641669494

2、KNN自带方法

机器学习模型 给我们提供了 打分的方法

# 参数 1.是测试集的特征数据 2.是测试集的真实结果
# 把测试集的特征数据传入后 机器学习模型 会 计算得到预测结果y_
# 然后和传入的真是结果 y_test 对比 返回准确率
knn.score(X_test,y_test)

猜你喜欢

转载自blog.csdn.net/PyRookie/article/details/81710173
今日推荐