春节前的一篇文章给大家介绍了kNN算法,算法有助于大家理解运行机制,方便对参数调优。成熟的算法,自然已经有现成的模块可以使用。
scikit-learn包是Python的一个机器学习组件,其中实现了kNN,支持向量机,k均值聚类等一系列机器学习算法。
安装scikit-learn包需要下面三个命令:
pip/pip3 install numpy
pip/pip3 install scipy
pip/pip3 install sklearn
本篇文章看看如何使用scikit-learn包实现kNN。scikit-learn本身自带了很多经典的数据集,如分类中经常使用的鸢尾花数据集。
数据集的准备
>>> from sklearn import datasets
>>> import numpy as np
>>> iris=datasets.load_iris()
>>> iris_x=iris.data
>>> iris_y=iris.target
上面的代码,首先导入了鸢尾花数据集,然后分离了鸢尾花数据集的特征数据和标签。我们可以先观察一下数据。
>>> np.shape(iris_x)
(150, 4)
>>> np.shape(iris_y)
(150,)
数据总共有150条,有四个特征,如果了解鸢尾花数据集,应该知道,这四个特征是花萼长度,花萼宽度,花瓣长度,花瓣宽度。
>>> np.unique(iris_y)
array([0, 1, 2])
标签(也就是数据集的种类)包括三种,分别为Iris Setosa(山鸢尾)、Iris Versicolour(杂色鸢尾),以及Iris Virginica(维吉尼亚鸢尾)。
>>> print(iris_y)
[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]
可以看到,标签是按0-2顺序排列的,这样的数据集不利于我们使用,所以,我们要对数据集进行随机打乱,然后划分训练集和测试集。
>>> indices = np.random.permutation(len(iris_x))
>>> iris_x_train = iris_x[indices[:-10]]
>>> iris_y_train = iris_y[indices[:-10]]
>>> iris_x_test = iris_x[indices[-10:]]
>>> iris_y_test = iris_y[indices[-10:]]
我们先随机生成0-149的数组下标,然后基于数组下标,选取140条数据作为训练集,10条数据作为测试集。
>>> print(iris_y_train)
[2 0 1 1 1 0 2 2 0 0 2 2 2 1 1 1 0 2 1 1 2 2 2 1 2 0 1 1 0 0 2 2 1 0 1 0 2
1 1 0 0 1 2 2 1 2 0 1 0 0 2 0 1 0 1 0 2 1 1 0 1 2 2 2 2 2 0 1 2 1 0 0 2 2
1 0 1 2 1 0 0 2 2 1 1 2 2 1 1 2 2 0 2 1 0 2 0 0 0 2 1 0 1 0 0 0 0 0 2 1 1
2 2 0 0 1 2 1 1 1 2 0 1 1 2 2 1 0 2 0 2 1 0 1 1 2 1 0 0 0]
这次,我们的类别被打乱了,更适合训练。由于随机选取,你的结果可能和我上面的结果不同。这样,数据就准备好了。
kNN算法的使用
>>> from sklearn.neighbors import KNeighborsClassifier
>>> knn = KNeighborsClassifier(n_neighbors=3)
导入KNeighborsClassifier,构造kNN分类器,传入了参数n_neighbors,就是我们的k值。构造函数还有其他一些参数,可以参照官方文档介绍。
>>> knn.fit(iris_x_train, iris_y_train)
对knn进行训练,由上一篇文章对算法的介绍应该能想到,这里所谓的训练,只是scikit-learn为了接口统一,实际kNN不需要训练模型,所以这个接口只是保存了样本集数据。
>>> iris_y_predict = knn.predict(iris_x_test)
>>> print(iris_y_predict)
[0 2 0 0 0 0 2 1 1 2]
进行预测,得到预测结果,看看有没有预测不匹配的
>>> error_index = np.nonzero(iris_y_test - iris_y_predict)[0]
>>> print(error_index)
[2]
发现index为2的数据预测错误,计算一下错误率
>>> len(error_index) / len(iris_y_test)
0.1
可以看到,使用scikit-learn我们不再需要自己编写算法,可以更加简单方便的解决问题。关于scikit-learn的kNN相关的详细介绍,可以看看官方文档。