鸢尾花分类是《Python机器学习基础教程》中的第一个应用,是一个监督学习问题,概述了使用scikit-learn库进行监督学习的基本流程:
获取数据→数据集拆分→观察数据→构建模型→评估模型→预测
博主使用的编程环境:
Sublime Text 3 + Jupyter Notebook + Anaconda 3
默认导入库:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn#博主使用的Anaconda 3并未默认安装mglearn,需要打开anaconda prompt输入pip install mglearn进行安装
鸢尾花(Iris)数据集是机器学习和统计学中的一个经典数据集,包含于scikit-learn的datasets模块中,可调用load_iris()来导入:
from sklearn.datasets import load_iris
iris_dataset = load_iris()
load_iris()返回的是一个Bunch对象,有五个键:
①target_names: 鸢尾花的三个品种
②feature_names: 鸢尾花的四个特征
③DESCR: 对数据集的简要说明
④data: 鸢尾花四个特征的具体数据
⑤target: 鸢尾花的品种,由0,1,2来表示
通常我们将数据用大写的X来表示(因为数据是个二维数组),而标签用小写的y来表示
然后利用scikit-learn的train_test_split()将导入的数据集分为训练集(用于构建机器学习模型)与测试集(用于评估模型性能),通常采用3:1的随机分配方法。train_test_split()的随机种子每次执行都会改变,为了使结果可以验证,我们可以通过random_state设置固定的随机种子。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0)
在构建模型之前,最好检查一下数据。数据可视化的一种方法是绘制散点图,这适合二维的数据。然而,鸢尾花数据集中的数据是四维的,于是我们采用散点图矩阵,绘制四个维度两两之间的散点图。
由于书中采用的pd.scatter_matrix()似乎已停止更新,故此采用Jupyter Notebook推荐的pd.plotting.scatter_matrix进行绘图
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)
grr = pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o',
hist_kwds={"bins": 20}, s=60, alpha=.8, cmap=mglearn.cm3)
介绍一下scatter_matrix()各参数的含义
pandas.plotting.scatter_matrix(frame, alpha=0.5, figsize=None, ax=None, grid=False, diagonal='hist', marker='.', density_kwds=None, hist_kwds=None, range_padding=0.05, **kwds)
frame : 所要展示的pandas的DataFrame对象
alpha : 透明度,一般取(0, 1]
figsize : 以英寸为单位的图像尺寸,以(width, height)的形式设置
ax : 一般为none
grid : 布尔型,控制网格的显示
diagonal : 须在{'hist', 'kde'}中选取一个作为参数,'hist'表示直方图,'kde'表示核密度估计
marker : 散点标记的类型,可选'.'或 ','或'o',默认为'.'
hist_kwds : 与hist相关的可变参数
density_kwds : 与kde相关的可变参数
range_padding : 图像在x轴、y轴附近的留白,默认为0.05
kwds : 其他可变参数
还有一些代码中用到的可变参数:
c : 将相同的值划分为相同的颜色
cmap : 配色方案,代码中采用了mglearn中的方案
s : 散点标记的大小
输出的散点图矩阵:
采用算法:k近邻算法
k近邻算法在sklearn的neighbors模块中的KNeighboursClassifier类中实现。KNeighboursClassifier最重要的参数就是k,k指的是考虑训练集中与新数据点最近的任意k个邻居,这里我们设为1
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
knn对象对算法进行了封装,包含了模型构建算法与预测算法,故可直接调用knn的fit方法来训练模型
knn.fit(X_train, y_train)
训练完成后,我们可以通过调用knn的predict方法来进行预测
X_new = np.array([[5, 2.9, 1, 0.2]])
prediction = knn.predict(X_new)
print("Prediction: {}".format(prediction))
print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
输出为:
Prediction: [0]
Predicted target name: ['setosa']
要想得知训练后的模型是否可靠,我们需要计算模型的精度,即测试集中的数据的预测准确度
我们可以通过比较测试集中模型预测的品种与实际的品种,得到一个01数组,求这些01的平均值,即为模型的精度
更方便的,我们可以直接调用knn的score方法来计算精度
y_pred = knn.predict(X_test)
print("Test set score: {:.2f}".format(np.mean(y_pred == y_test)))
print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))
输出为:
Test set score: 0.97
Test set score: 0.97
这意味着,对于一组新的鸢尾花数据,可以认为我们的模型预测结果有97%是正确的
核心步骤是:数据集拆分→选取模型→训练模型→评估模型
核心代码:
X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0)
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train, y_train)
print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))
完整代码:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import mglearn
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
iris_dataset = load_iris() #鸢尾花数据集
X_train, X_test, y_train, y_test = train_test_split(iris_dataset['data'], iris_dataset['target'], random_state=0)
#数据拆分,最佳比例是数据集:测试集 = 3:1
iris_dataframe = pd.DataFrame(X_train, columns=iris_dataset.feature_names)
grr = pd.plotting.scatter_matrix(iris_dataframe, c=y_train, figsize=(15, 15), marker='o',
hist_kwds={"bins": 20}, s=60, alpha=.8, cmap=mglearn.cm3) #展示散点图矩阵
knn = KNeighborsClassifier(n_neighbors=1) #knn对算法进行了封装,包含了模型构建算法与预测算法
knn.fit(X_train, y_train) #构建模型
X_new = np.array([[5, 2.9, 1, 0.2]])
prediction = knn.predict(X_new)
print("Prediction: {}".format(prediction))
print("Predicted target name: {}".format(iris_dataset['target_names'][prediction]))
y_pred = knn.predict(X_test)
print("Test set predictions:\n {}".format(y_pred))
print("Test set score: {:.2f}".format(np.mean(y_pred == y_test)))
print("Test set score: {:.2f}".format(knn.score(X_test, y_test)))