本文仅供自己学习所用~
参考博客:http://t.csdn.cn/1IB1Z(什么是KNN算法?)
http://t.csdn.cn/sSN3U(鸢尾花数据集实现KNN算法)
前言
#杭电极客深度学习考核作业Ⅰ
菜鸡一枚,第一次写博客,由此开启我的博客之路!
一、KNN是什么?
KNN(K-Nearest Neighbor)算法是机器学习算法中最基础、最简单的算法之一。它既能用于分类,也能用于回归。KNN通过测量不同特征值之间的距离来进行分类。
KNN算法思想:(简单来说)当预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别
从图中我们容易知道,绿色点所在的内圆中有两红一蓝,那么根据KNN算法“物以类聚,人以群分”的思想来判断,绿点点应该被分为红色三角形一类。到这里,你就基本了解了著名的KNN算法是干什么用的了。
二、KNN用法分析
k近邻法三要素:距离度量、k值的选择和分类决策规则。
距离度量:
Lp(xi,xj)=(∑i=1n∣∣∣xi(i)−xj(l)∣∣∣p)p1
p=1 曼哈顿距离
p = 2 欧氏距离
p = ∞ 切比雪夫距离
常用欧氏距离
k值的选择:
k值小时,k近邻模型更复杂,容易发生过拟合;k值大时,k近邻模型更简单,又容易欠拟合。
在实践中,一般采用交叉验证的方式选取k值。
交叉验证的基本想法是重复地使用数据,把给定的数据进行切分,将切分的数据组合为训练集与测试集,在此基础上反复进行训练测试以及模型的选择。
交叉验证主要有三种方法:简单交叉验证(HoldOut检验)、k折交叉验证(k-fold交叉验证)、自助法。实现过程中用sklearn.model_selection.cross_val_score()实现交叉验证选取k值。
cross_val_score参数设置
# cross_val_score参数设置
sklearn.model_selection.cross_val_score(estimator, # 需要使用交叉验证的算法
X, # 输入样本数据
y=None, # 样本标签
groups=None, # 将数据集分割为训练/测试集时使用的样本的组标签(一般用不到)
scoring=None, # 交叉验证选择不同的评价方法
cv=’warn’, # 交叉验证折数或可迭代的次数
n_jobs=None, # 同时工作的cpu个数(-1代表全部)
verbose=0, # 详细程度
fit_params=None, # 传递给估计器(验证算法)的拟合方法的参数
pre_dispatch=‘2*n_jobs’, # 控制并行执行期间调度的作业数量
error_score=’raise-deprecating’) # 如果在估计器拟合中发生错误,要分配给该分数的值
cross_val_score的使用:(交叉验证发选取最佳k值的应用)
from sklearn.datasets import load_iris
from sklearn.model_selection import cross_val_score
import matplotlib.pyplot as plt
from sklearn.neighbors import KNeighborsClassifier
#加载鸢尾花数据集
iris = load_iris()
x = iris.data
y = iris.target
k_range = range(1, 31) # 设置循环次数
k_error = []
#循环,取k从1~30,查看误差效果
for k in k_range:
knn = KNeighborsClassifier(n_neighbors=k)
# KNeighborsClassifier是实现k近邻算法的一个类,n_neighbors:选取最近的点的个数为k
scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy')
# cv参数决定数据集划分比例,这里是按照5:1划分训练集和测试集
k_error.append(1 - scores.mean())
#画图,x轴为k值,y值为误差值,误差值越小越好
plt.plot(k_range, k_error)
plt.xlabel('Value of K in KNN')
plt.ylabel('Error')
plt.show()
结果如下:
由图知,该数据集在k=11时损失最小,因此接下来我们选择k=11进行训练
类决策规则:
分类决策规则往往是多数表决,即由输入实例的k kk个邻近输入实例中的多数类决定输入实例的类。
三、KNN实例
代码如下:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from sklearn import neighbors, datasets
n_neighbors = 11 # 由上面交叉验证得到的最佳k值
# 加载鸢尾花数据集
iris = datasets.load_iris()
# 选择其中的两个特征
X = iris.data[:, :2]
y = iris.target
h = .02 # 网格步长
# 创建色彩图, ListedColormap为mapplotlib.colors的一个类
cmap_light = ListedColormap(['LightPink', 'Lavender', 'Blue']) # 背景颜色(浅)
cmap_bold = ListedColormap(['DeepPink', 'BlueViolet', 'DeepSkyBlue']) # 点的颜色(深)
# 在两种权重下绘制图像
for weights in ['uniform', 'distance']:# 用于指定邻近样本的投票权重,“uniform”表示所有样本投票权重一致,如果为“distance”则表示投票权重与距离成反比
# 创建knn分类器实例, 并进行训练拟合
clf = neighbors.KNeighborsClassifier(n_neighbors, weights = weights)
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, h),
np.arange(y_min, y_max, h))
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) # clf.predict用训练好的分类器去预测, a.ravel()将数组维度拉成一维数组
Z = Z.reshape(xx.shape)
plt.figure()
plt.pcolormesh(xx, yy, Z, cmap = cmap_light) # 数据的分类显示(根据背景的三种颜色)
# 绘制训练点
plt.scatter(X[:, 0], X[:, 1], c = y, cmap = cmap_bold, edgecolor='k', s=20)
plt.xlim(xx.min(), xx.max())
plt.ylim(yy.min(), yy.max())
plt.title('3-Class classification (k = %i, weights = "%s")' % (n_neighbors, weights))
plt.show()
输出如下:
"uniform"表示所有样本投票权重一致
“distance”则表示投票权重与距离成反比
总结
KNN有着非常明显的优点和缺点:
优点:精度高、对异常值不敏感、无数据输入假定
缺点:计算复杂度高、空间复杂度高,对内存要求较高,因为该算法存储了所有训练数据
适用数据范围:数值型和标称型