美文网首页
Python机器学习之K最近邻算法

Python机器学习之K最近邻算法

作者: 一只怂货小脑斧 | 来源:发表于2020-09-10 15:21 被阅读0次

一、K最近邻算法的原理

原理部分直接看我另一篇《KNN是什么东东?》,本文主要针对如何应用。
K这个字母的含义就是最近邻的个数。在scikit-learn中,K最近邻算法的K值是通过 n_neighbors 参数来调节的,默认值是 5。
 K最近邻算法也可以用于回归。当使用K最近邻回归计算某个数据点的预测值时,模型会选择离该数据点最近的若干个训练数据集中的点,并且将他们的 y 值取平均值,并把该平均值作为新数据点的预测值。

二、K最近邻算法在二分类任务中的应用

 首先,使用 scikit-learn 的 make_blobs 函数来生成一个样本数量为 200,分类数为 2 的数据集,并赋值给 X 和 y,并使用 matplotlib 绘制出数据集图形。

from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #导入 KNN 分类器
import matplotlib.pyplot as plt # 导入画图工具
from sklearn.model_selection import train_test_split # 导入数据集拆分工具

#生成样本数为 200,分类为 2 的数据集;n_features默认为2,即2个特征
data = make_blobs(n_samples=200, centers=2, random_state=8)
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, edgecolors='k')
plt.show()

执行结果为:


使用 make_blobs 生成的数据集.png

注释1:

sklearn.datasets.make_blobs

函数原型:sklearn.datasets.make_blobs(n_samples=100, n_features=2, centers=None, cluster_std=1.0, center_box=(-10.0, 10.0), shuffle=True, random_state=None)

参数解释
 n_samples(int/array): 如果参数为int,代表总样本数;如果参数为array-like,数组中的每个数代表每一簇的样本数。
 n_features(int): 样本点的维度。
 centers(int): 样本中心数。如果样本数为int且centers=None,生成三个样本中心;如果样本数(n_samples)为数组,则centers 要么为None,要么为数组的长度。
 cluster_std(float/sequence of floats): 样本中,簇的标准差。
 center_box(pair of floats (min, max)): 每个簇的上下限。
 shuffle(boolean): 是否将样本打乱。
 random_state(int/RandomState instance /None): 指定随机数种子,每个种子生成的序列相同,与minecraft地图种子同理。

返回类型:X : 样本数组 [n_samples, n_features]
      产生的样本
     y : array of shape [n_samples]
      每个簇的标签

注释2:

matplotlib.pyplot.scatter

用来绘制散点图
参考:《Python中scatter函数参数详解》

 接下来,用 K最近邻算法来拟合数据

import numpy as np
clf = KNeighborsClassifier() #KNN
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, cmap=plt.cm.Pastel1)
#将生成的样本数据可视化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐标轴范围限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#绘图标题
plt.title("Claccifier:KNN")

plt.show()

执行结果为:

预测结果为:
==========================
新数据的分类是: [1]
knn_two_classify.png

注释1:

meshgrid()

meshgrid函数用两个坐标轴上的点在平面上画网格,即从坐标向量中返回坐标矩阵
可以参考以下两篇文章:《3分钟理解np.meshgrid()》《Numpy中Meshgrid函数介绍及2种应用场景》

注释2:

numpy.ravel()

将多维数组将为一维数组
参考:《numpy 辨异 (五)—— numpy.ravel() vs numpy.flatten()》

注释3:

pcolormesh()

绘制分类图
函数原型: matplotlib.pyplot.pcolormesh(*args, alpha=None, norm=None, cmap=None, vmin=None, vmax=None, shading='flat', antialiased=False, data=None, **kwargs) 创建一个带有不规则矩形网格的伪彩色图

具体的参数解释参见 :pcolormesh参数

具体使用方法参考:利用plt.pcolormesh绘制分类图

 最后,附上二分类任务的完整代码

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #导入 KNN 分类器
import matplotlib.pyplot as plt # 导入画图工具
from sklearn.model_selection import train_test_split # 导入数据集拆分工具

#生成样本数为 200,分类为 2 的数据集,n_features默认为2,即2个特征
data = make_blobs(n_samples=200, centers=2, random_state=8)
X, y= data

clf = KNeighborsClassifier() #KNN
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, cmap=plt.cm.Pastel1)
#将生成的样本数据可视化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐标轴范围限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#绘图标题
plt.title("Claccifier:KNN")

#对特征值为 6.75 和4.82 的新数据点分类进行预测
print('预测结果为:')
print('==========================')
print('新数据的分类是:', clf.predict([[6.75, 4.82]]))
#可视化的数据分类
plt.scatter(6.75, 4.82, marker='*', c='red',s=200)
plt.show()

三、K最近邻算法在多元分类任务中的应用

 首先,使用 scikit-learn 的 make_blobs 函数来生成一个样本数量为 500,分类数为 5 的数据集,并赋值给 X 和 y,与二分类构造数类似,不再赘述样本绘图部分

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #导入 KNN 分类器
import matplotlib.pyplot as plt # 导入画图工具

#生成样本数为 500,分类为 5 的数据集,n_features默认为2,即2个特征
data = make_blobs(n_samples=500, centers=5, random_state=8)
X, y= data

clf = KNeighborsClassifier() #KNN
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, cmap=plt.cm.Pastel1)
#将生成的样本数据可视化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐标轴范围限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#绘图标题
plt.title("Claccifier:KNN")

#模型评分
print('==========================')
print('模型评分:{:.2f}'.format(clf.score(X, y)))
plt.show()

执行结果为:

==========================
模型评分:0.96
knn_multi_classify.png

四、K最近邻算法用于回归分析

 首先,使用 scikit-learn 的 make_regression 函数来生成一个特征数量为 1,标准差为 50 的noise 的数据集,并赋值给 X 和 y,并使用 matplotlib 绘制出数据集图形。

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',edgecolors='k')
plt.show()

执行结果如下,横轴代表样本特征的数值,纵轴代表样本的测定值:


knn_regression_data.png

注释:

sklearn.datasets.make_regression

函数原型:sklearn.datasets.make_regression(_samples=100, n_features=100, n_informative=10,
n_targets=1, bias=0.0, effective_rank=None,
tail_strength=0.5, noise=0.0, shuffle=True, coef=False,
random_state=None)

关键参数解释
 n_samples(生成样本数)
 n_features(样本特征数)
 noise(样本随机噪音)
 coef(是否返回回归系数)

返回类型
 X为样本特征
 y为样本输出
 coef为回归系数

 然后,使用K最近邻算法来进行回归分析,并输出模型评分

import numpy as np
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier #导入 KNN 分类器
import matplotlib.pyplot as plt # 导入画图工具

#生成样本数为 500,分类为 5 的数据集,n_features默认为2,即2个特征
data = make_blobs(n_samples=500, centers=5, random_state=8)
X, y= data

clf = KNeighborsClassifier() #KNN
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, cmap=plt.cm.Pastel1)
#将生成的样本数据可视化
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.spring, edgecolors='k')
#坐标轴范围限定
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
#绘图标题
plt.title("Claccifier:KNN")

#模型评分

print('==========================')
print('模型评分:{:.2f}'.format(clf.score(X, y)))
plt.show()

执行结果如下图所示,拟合效果不是很好


knn_regression_5neighbors.png
==========================
模型评分:0.77

n_neighbors 参数默认值是 5,调节该参数,这是为2 ,再执行

reg = KNeighborsRegressor(n_neighbors=2) 

执行结果如下图所示,拟合效果有改善,评分也有提高


knn_regression_2neighbors.png
==========================
模型评分:0.86

 最后,附上完整代码

import numpy as np
from sklearn.datasets import make_regression #回归分析数据生成器
from sklearn.neighbors import KNeighborsRegressor #用于回归分析的KNN模型
import matplotlib.pyplot as plt # 导入画图工具
X, y = make_regression(n_features=1, n_informative=1, noise=50, random_state=8)

#n_neighbors 默认是5
#reg = KNeighborsRegressor()
#调节n_neighbors为 2
reg = KNeighborsRegressor(n_neighbors=2) #KNN
reg.fit(X, y) #拟合数据

#预测结果可视化
z = np.linspace(-3, 3, 200).reshape(-1, 1) #范围由生成的回顾分析数据确定
#用散点图将数据可视化
plt.scatter(X, y, c='orange',edgecolors='k')
plt.plot(z, reg.predict(z), c='k', linewidth=3)
#添加标题
plt.title('KNN Regression')

#模型评分

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

相关文章

网友评论

      本文标题:Python机器学习之K最近邻算法

      本文链接:https://www.haomeiwen.com/subject/cgqpektx.html