第三章 K最近邻算法-近朱者赤,近墨者黑
3.1 kNN原理
- 在分类上, 原理是取最近的k个点, 按这些点的类标签来决定未知点的类型.
- 在回归上, 取最近k个点的y值取平均作为预测值.
- 默认的k是5, 根据经验可以调5, 10. 参数最好要优化.
-
metric
和p
可以改变距离的测量. weights可以改变各特征的权重(默认均等).
TODO: 如果分类时, k个点最多的类有2甚至3种, 是根据最近原则来确定类么?
3.2 kNN的用法
这里作者用了一个自建数据集和红酒数据集做测试, 针对分类和回归的应用都做了展示.
-
neighbors.KNeighborsClassifier
能用于kNN分类. -
neighbors.KNeighborsRegressor
能用于kNN回归 (取邻近的k个点的y值平均) - 一般习惯地,
clf
代表分类器,reg
代表回归器.
3.2.1 kNN在简单分类的应用
sklearn.datasets
子模块是针对数据集的一个模块, 内含几个toy datasets, 另外, 也可以下载更大的数据集, 或者自己产生数据集. 这章书使用make_blobs
来产生分类点, 使用make_regression
来产生回归使用的点.
make_blobs 产生数据集
使用datasets.make_blobs
可以产生分类的数据点, 见下面例子.
-
make_blobs
: 产生各同向性Gaussian blobs用于聚类. 返回(features, labels)
的两个数组.-
n_samples=100
: 产生点数. 如果给的是数组, 数组中每个元素是每个类的点数. -
n_features=2
: 特征数. -
centers=None
: 产生分类数(标签). 如果给定了n_samples, 而centers为None, 则会产生三个中心 -
cluster_std=1.0
: 类的标准差. -
center_box=(-10.0, 10.0)
: 一个类的边界,(min,max)
-
shuffle=True
: 对样本洗牌. -
random_state=None
: 随机状态.
-
# 导入数据集, 分类器, 画图工具, 数据集拆分工具
from sklearn.datasets import make_blobs
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
# 生成样本数200, 分类为2类的数据集,
data = make_blobs(n_samples=200, n_features=2, 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产生二分类的数据集
- 该例子产生的是两个类, 为了便于可视化, 使用2个特征.
- 产生的返回值是
(features, labels)
两个数组, 分别给了X和y.- 一般地, 大写X是多维数据(矩阵), 特征时用; y是一维数组(向量), 一般标签用.
scatter
作散点图, 前两个是X轴和Y轴坐标(用的是特征1和特征2), c=y是指定颜色对应的是标签(0/1)
创建kNN分类模型
- 使用
neighbors.KNeighborsClassifier
可以创建分类模型, 有很多参数可调, 最常用n_neighbors
指定k值. - 创建的对象就是一个分类器. 或者说是模型. 使用
fit(X,y)
方法可以进行训练, 使用predict(X)
可以进行预测(返回相应标签y). - 模型训练使用训练集, 训练一次后即可进行多次的预测.
- 下面的例子使用上面的测试集进行训练(整个集作为训练集). 一般要将数据分割成训练集和测试集来测试.
- 为可视化表征模型, 作者创建了网格(
np.meshgrid
, 格点距离0.02, 范围覆盖坐标), 并用网格的坐标利用模型进行预测(这步很费时), 预测值就是网格对应的类, 再结合plt.pcolormesh
将坐标内根据类标签用不同颜色表示. -
array.ravel()
可以将多维数组一维化.np.c_[A, B]
可以将后面的slice中给定的数组连结为2D数组.
# 拟合
import numpy as np
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, 0.02),
np.arange(y_min, y_max, 0.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, edgecolor='k')
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title("Classifier:KNN")
plt.show()
建立kNN模型并可视化
预测新点的分类
输入一个数据点的特征([[6.75,4.82]]
,注意两层中括号, 一层是元素, 一层是特征), 肉眼可见再灰色一类(类1). 进行预测, 其结果和观察一致.
# 加入新数据点, 并五星标记
plt.scatter(6.75, 4.82, marker='*', c='red', s=200)
plt.show()
# 对新点进行预测, 并显示其分类
print('新数据点的分类是:',clf.predict([[6.75,4.82]]))
新数据点显示和预测
新数据点的分类是: [1]
未完, 待续
网友评论