《深入浅出Python机器学习》读书笔记 第三章 K近邻算法

《深入浅出Python机器学习》读书笔记,第三章 K近邻算法

一、K近邻算法的原理

如果一个样本周围最近的K个样本都属于某一个类别,那么这个样本也属于这个类别。

二、K近邻算法的用法

1 K近邻算法在分类任务中的应用

1.1 生成训练集数据

生成一些数据,一类是紫色,一类是黄色

案例:

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
# 为聚类生成数据集,n_samples指定生成数据集的长度,centers是聚类中心点的个数(聚类后类别的个数),random_state设置种子,让数据可重现
data = make_blobs(n_samples=200, centers=2, random_state=8)
X,y = data
# 输出生成的数据
plt.scatter(X[:,0], X[:,1], c=y, cmap=plt.cm.spring, edgecolor='k')
plt.show()

打开Jupyter Notebook输入案例代码,点击运行,输出如下
在这里插入图片描述

1.2 用训练数据训练模型

这两类点数据可以看做是已知的两种类别,这里的输出结果是训练数据的一个可视化结果,接下来用生成的数据训练一个模型


案例:

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import numpy as np

data = make_blobs(n_samples=200, centers=2, random_state=8)
X,y = data

#创建一个K近邻分类器对象
clf = KNeighborsClassifier()
# 使用X作为训练数据,y作为目标值(类似于标签)来拟合模型
clf.fit(X,y)
# 取第1个维度组成的列表里的最小值加-1和第1个维度组成的列表里的最大值加+1
x_min, x_max = X[:,0].min() - 1, X[:,0].max() + 1
# 取第2个维度组成的列表里的最小值加-1和第2个维度组成的列表里的最大值加+1
y_min, y_max = X[:,1].min() - 1, X[:,1].max() + 1
# 生成一个足以覆盖所有点的坐标矩阵
xx,yy = np.meshgrid(np.arange(x_min, x_max, .02), np.arange(y_min, y_max, .02))

# 用训练好的模型预测;ravel()方法作用是将多维数组转化为1维数组
Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
# reshape()方法作用是重新组织数据
Z = Z.reshape(xx.shape)
# 绘制分类图
plt.pcolormesh(xx, yy, Z, cmap=plt.cm.Pastel1)
plt.scatter(X[:,0], X[:,1], c=y, cmap=plt.cm.spring, edgecolor='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Classifier : KNN")
plt.show()

输入案例代码,点击运行,输出如下
在这里插入图片描述
这里基于训练集训练出一个分类模型,粉色部分是一个类别,灰色部分是一个类别。如果有新的数据输入,模型会自动将数据分到对应的分类。


1.3 测试模型

测试集两个特征分别是6.75,和4.82,测试一下模型能否正确分类

plt.show()前加入如下代码

plt.scatter(6.75,4.82,marker='*',c='red',s=200)

输入案例代码,点击运行,输出如下
在这里插入图片描述
这里报了个警告 :

e:\soft\py3\lib\site-packages\ipykernel_launcher.py:19: MatplotlibDeprecationWarning: 
shading='flat' when X and Y have the same dimensions as C is deprecated since 3.3. 
Either specify the corners of the quadrilaterals with X and Y, or pass shading='auto',
'nearest' or 'gouraud', or set rcParams['pcolor.shading'].  This will become an error
two minor releases later.

报警告的原因是:

当X和Y的维度与C相同时,shading='flat'从3.3开始就不推荐使用。
使用X和Y指定四边形的角点,或传递shading='auto'、'nearest'或'gouraud',
或设置rcParams['pcolor.着色']. 

根据提示,修改案例代码为如下警告消失:

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import numpy as np

data = make_blobs(n_samples=200, centers=2, random_state=8)
X,y = data

clf = KNeighborsClassifier()
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, .02), np.arange(y_min, y_max, .02))

Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, shading='auto', cmap=plt.cm.Pastel1)
plt.scatter(X[:,0], X[:,1], c=y, cmap=plt.cm.spring, edgecolor='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Classifier : KNN")
plt.scatter(6.75,4.82,marker='*',c='red',s=200)
plt.show()

再次验证预测结果

案例:

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import numpy as np

data = make_blobs(n_samples=200, centers=2, random_state=8)
X,y = data

clf = KNeighborsClassifier()
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, .02), np.arange(y_min, y_max, .02))

Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, shading='auto', cmap=plt.cm.Pastel1)
plt.scatter(X[:,0], X[:,1], c=y, cmap=plt.cm.spring, edgecolor='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Classifier : KNN")
plt.scatter(6.75,4.82,marker='*',c='red',s=200)
# plt.show()
print('代码运行结果:')
print('新数据点的分类是:',clf.predict([[6.75, 4.82]]))

输入案例代码,点击运行,输出如下
在这里插入图片描述
可以看到模型把测试点分类到1类(位于灰色区域,和黄色点为同一类。0代表粉色分类,1 代表灰色分类),预测结果正确

2 K近邻算法处理多元任务分类

2.1 生成训练集数据

生成用于多远分类任务所用的训练集,把数据类型增加到5个,把样本量增加到500个

案例:

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import numpy as np
# 生成测试数据,n_samples指定总样本数为500,centers指定类别个数,random_state保证数据可重现
data2 = make_blobs(n_samples=500, centers=5, random_state=8)
X2,y2 = data2
plt.scatter(X2[:,0], X2[:,1], c=y2, cmap=plt.cm.spring, edgecolor='k')
plt.show()

输入案例代码,点击运行,输出如下
在这里插入图片描述
可以看到生成了5种类别的训练数据集,值得注意的是有两类数据重叠,难度会大一些

2.2 用训练数据集训练模型

用训练数据集训练模型

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
import numpy as np

data2 = make_blobs(n_samples=500, centers=5, random_state=8)
X2,y2 = data2

clf = KNeighborsClassifier()
clf.fit(X2, y2)
x_min, x_max = X2[:,0].min()-1, X2[:,0].max()+1
y_min, y_max = X2[:,1].min()-1, X2[:,1].max()+1
xx, yy = np.meshgrid(np.arange(x_min, x_max,.02),np.arange(y_min, y_max,.02))

Z = clf.predict(np.c_[xx.ravel(),yy.ravel()])
Z = Z.reshape(xx.shape)
plt.pcolormesh(xx, yy, Z, shading='auto', cmap=plt.cm.Pastel1)
plt.scatter(X2[:,0],X2[:,1], c=y2, cmap=plt.cm.spring, edgecolor='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Classifier:KNN")
plt.show()

输入案例代码,点击运行,输出如下
在这里插入图片描述

可以看到,大部分已经分到正确的区域,少部分重合部分的数据未分到正确的类别

2.3 验证正确率

案例:

print('模型正确率:{:.2f}'.format(clf.score(X2,y2)))

输入案例代码,点击运行,输出如下
在这里插入图片描述
可以看到模型的正确率为0.96

3 K近邻算法用于回归分析

3.1 生成训练集数据

案例

from sklearn.datasets import make_regression
import matplotlib.pyplot as plt

X, y = make_regression(n_features=1, n_informative=1, noise=50, random_state=8)
plt.scatter(X, y, c='orange', edgecolor='k')
plt.show()

输入案例代码,点击运行,输出如下
在这里插入图片描述
训练集的数据如图所示

3.2 训练模型

使用上面生成的数据训练一个模型

案例:

from sklearn.neighbors import KNeighborsRegressor
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt

X, y = make_regression(n_features=1, n_informative=1, noise=50, random_state=8)
reg = KNeighborsRegressor()

reg.fit(X, y)
z = np.linspace(-3, 3, 200).reshape(-1, 1)
plt.scatter(X, y, c='orange', edgecolor='k')
plt.plot(z, reg.predict(z), c='k', linewidth=3)
plt.title('KNN Regressor')
plt.show()

输入案例代码,点击运行,输出如下
在这里插入图片描述
从图上来看,拟合的不算好

3.3 查看分数

案例:

print('模型评分:{:.2f}'.format(reg.score(X, y)))

输入案例代码,点击运行,输出如下
在这里插入图片描述
评分只有0.77,默认情况下k=5,尝试减少k的数量到2

3.4 调整参数

案例:

from sklearn.neighbors import KNeighborsRegressor
from sklearn.datasets import make_regression
import matplotlib.pyplot as plt

X, y = make_regression(n_features=1, n_informative=1, noise=50, random_state=8)
reg = KNeighborsRegressor(n_neighbors=2)

reg.fit(X, y)
z = np.linspace(-3, 3, 200).reshape(-1, 1)
plt.scatter(X, y, c='orange', edgecolor='k')
plt.plot(z, reg.predict(z), c='k', linewidth=3)
plt.title('KNN Regressor')
plt.show()

输入案例代码,点击运行,输出如下
在这里插入图片描述
对比之前的曲线,发现稍微好一些了

3.5 查看调整后模型的评分

案例:

print('模型评分:{:.2f}'.format(reg.score(X, y)))

输入案例代码,点击运行,输出如下
在这里插入图片描述
看结果,调整k=2后拟合结果比之前高了一些

4 K最近邻算法项目实战——酒的分类

使用scikit-learn内置的酒数据集来进行学习,在Jupyter Notebook中新建一个Python3

4.1 准备数据集

案例:

from sklearn.datasets import load_wine
wine_dataset = load_wine()
print("红酒数据集中的键:{}".format(wine_dataset.keys()))

输入案例代码,点击运行,输出如下
在这里插入图片描述
数据集包括数据、目标分类、目标分类名称、数据描述、特征名称

4.2 查看数据集的概况

案例:

print('数据概况:{}'.format(wine_dataset['data'].shape))

输入案例代码,点击运行,输出如下
在这里插入图片描述
共有178个样本,每个样本有13个特征

4.3 查看数据集的描述

案例:

print('数据描述:{}'.format(wine_dataset['DESCR']))

输入案例代码,点击运行,输出如下
在这里插入图片描述
在这里插入图片描述
178份数据分为3类,从1~3类分别有59、71、48份数据
13个特征分别是酒精含量、苹果酸、灰烬含量、碱含量、镁含量、总酚含量、黄酮素含量、非黄酮酚含量、原花青素含量、色彩强度、色调、稀释葡萄酒的OD280/OD315、脯氨酸

4.4 分成训练集和测试集

使用scikit-learn的train_test_split函数,将数据集75%作为训练集25%作为测试集

案例:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(wine_dataset['data'], wine_dataset['target'], random_state=0)
print('X_train : {}'.format(X_train.shape))
print('X_test : {}'.format(X_test.shape))
print('y_train : {}'.format(y_train.shape))
print('y_test : {}'.format(y_test.shape))

输入案例代码,点击运行,输出如下
在这里插入图片描述
数据已经分为训练集和测试集。训练集样本数和标签的数量为133,测试集样本数和标签的数量为45

4.5 使用K近邻算法进行建模

案例:

from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors = 1)
knn.fit(X_train, y_train)
print('测试数据集得分:{:.2f}'.format(knn.score(X_test, y_test)))

输入案例代码,点击运行,输出如下
在这里插入图片描述
这里看到训练出的模型得分为0.76

4.6 使用模型对新样本的分类进行预测

新样本的13个特征值如下
在这里插入图片描述
案例:

import numpy as np
X_new = np.array([[13.2, 2.77, 2.51, 18.5, 96.6, 1.04, 2.55, 0.57, 1.47, 6.2, 1.05, 3.33, 820]])
prediction = knn.predict(X_new)
print('预测红酒的分类为:{}'.format(wine_dataset['target_names'][prediction]))

输入案例代码,点击运行,输出如下
在这里插入图片描述

5 小结

K近邻算法的劣势:

  1. 需要预处理数据
  2. 超大规模的数据集拟合的时间较长
  3. 对高维数据拟合欠佳
  4. 对于稀疏数据集束手无策

当前的应用场景中,K近邻算法很少使用,用的较多的是广义线性模型。

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值