购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

3.2 学习Scikit-Learn的第一步
——训练感知机

第2章介绍了感知机规则和Adaline两个机器学习分类算法,并用Python和NumPy代码实现了这两种算法。现在看下Scikit-Learn API。如前所述,Scikit-Learn API提供了一个统一且用户友好的界面和多种高度优化的机器学习算法。Scikit-Learn库不仅提供了大量的机器学习算法,还提供了许多函数,用于数据预处理、模型微调、模型评估等任务。第4章和第5章将更加详细地讨论这些话题以及相关的基本概念。

作为开始使用Scikit-Learn库的起点,我们将重新训练第2章介绍的感知机模型。为了简单起见,以后各节将继续使用已经熟悉的鸢尾花数据集。鸢尾花数据集是一个简单常用的数据集,经常用于检验和测试算法。Scikit-Learn库也提供鸢尾花数据集。与前一章类似,为了方便可视化,本章将仅使用鸢尾花数据集中的两个特征。

把150个鸢尾花样本的花瓣长度和花瓣宽度存入矩阵X中,把相应的鸢尾花品种存入向量y中:

np.unique(y)函数返回存储在iris.target中的三种类别标签。类别标签0、1、2分别代表鸢尾花的三个种类,即山鸢尾、变色鸢尾和弗吉尼亚鸢尾。虽然Scikit-Learn中的许多函数和方法使用字符串表示类别标签,但是建议使用整数表示类别标签,因为这样不但可以避免技术故障,而且由于整型数据占用内存较小从而可以提高算法的计算性能。此外,将类别标签编码为整数是大多数机器学习库常见的做法。

为了评估训练好的模型在新的未知数据上的预测能力,进一步将数据集拆分为训练数据集和测试数据集。第6章将更详细地讨论模型的评估。使用Scikit-Learn库model_selection模块中的train_test_split函数将X和y随机拆分为两部分,30%作为测试数据(45个样本),70%作为训练数据(105个样本):

请注意,train_test_split函数在分割数据集之前已经在内部对训练数据集进行乱序操作。否则,由于原始数据集中的样本按类别标签为0、1、2顺序存储,类别标签为0和类别标签为1的样本都被分到训练数据集中,而类别标签为2的45个样本被分到测试数据集中。通过设置random_state参数,为内部伪随机数生成器提供了一个固定的随机种子(random_state=1)。在拆分数据之前,内部伪随机数生成器生成的随机数用于对数据集进行乱序。使用这种固定的random_state参数可以确保结果可复现。

最后,通过设置stratify=y获得内置分层支持。在这种情况下,分层意味着train_test_split方法返回的训练数据集和测试数据集内的类别标签比例与输入数据集相同。可以使用NumPy的bincount函数计算每个数据集中各类标签出现的次数,以验证情况是否如上所述:

正如第2章梯度下降例子中看到的那样,许多机器学习和优化算法需要特征缩放以获得最佳性能。使用Scikit-Learn中preprocessing模块中的StandardScaler类标准化这些特征:

在上述代码中,从preprocessing模块加载了StandardScaler类,并初始化了一个新的StandardScaler对象,即对象sc。使用fit方法,StandardScaler估计了训练数据中每个特征的参数 μ (样本均值)和 σ (标准差)。调用transform方法,使用估计的参数 μ σ 对训练数据进行标准化处理。请注意,要使用相同的缩放参数来标准化测试数据集,这样才能使训练数据集和测试数据集具有可比性。

在标准化了训练数据之后,可以训练感知机模型。通过使用一对多(One-versus-Rest,OvR)方法使感知机模型可以完成多类分类任务。Scikit-Learn中大多数分类算法都默认使用一对多方法实现多类分类。将三种鸢尾花数据输入到感知机,代码如下:

Scikit-Learn的代码界面会让我们回想起第2章中的Perceptron代码实现。在上述代码中,首先从linear_model模块加载Perceptron类;然后,初始化一个新的Perceptron对象ppn;最后,调用fit方法训练模型。这里,模型参数eta0相当于第2章实现感知机中使用的学习率eta。

正如在第2章中所学习到的,找到一个大小合适的学习率需要一些经验。如果学习率过大,则梯度下降算法会越过损失函数全局最小值;如果学习率太小,则梯度下降算法收敛将需要更多的时间,从而降低学习速度,这在使用大型数据集时影响尤其明显。此外,在每次epoch开始时设置random_state参数对训练数据进行乱序,这样保证了实验的可重复性。

与第2章实现感知机一样,使用Scikit-Learn训练了一个模型后,可以运行predict方法进行预测,具体代码如下:

运行上述代码后,可以看到感知机在预测45个花朵样本中出现了1次错误分类。因此,测试数据集的分类错误率约为0.022,或2.2%(1/45≈0.022)。

分类错误率与准确率

许多机器学习实践者报告模型的分类准确率,而不是分类错误率。上述分类器的准确率为

1-错误率=0.978或者97.8%

采用分类错误率还是准确率纯粹属于个人喜好。

请注意,Scikit-Learn的metrics模块有大量衡量模型性能的指标。例如,可以在测试数据集上计算感知机的分类准确率,如下所示:

这里,y_test是真实的类别标签,y_pred是模型预测的类别标签。另外,Scikit-Learn中的每个分类器都有一个score方法,该方法通过调用predict方法与accuracy_score方法计算分类器的预测准确率,如下所示:

过拟合

请注意本章使用测试数据集评估模型的性能。第6章将介绍许多用于检测和防止过拟合的方法,如基于学习曲线的图像分析方法。过拟合意味着虽然模型捕捉到了训练数据中的模式,但是不能很好地泛化到未见过的新数据上。本章的后续部分将详细讨论过拟合问题。

最后,可以使用第2章中的plot_decision_regions函数绘制训练好的感知机模型决策区域,并以可视化方式展示模型如何分离不同类别的花朵样本。稍微修改以下代码,用小圆圈显示来自测试数据集的数据实例:

稍微修改plot_decision_regions函数,可以在结果图上通过索引标记感兴趣的样本。代码如下:

如图3.1所示,三种花不能被线性决策边界完全分开。

图3.1 使用鸢尾花数据集训练的多类感知机模型的决策边界

在第2章中我们学习到,如果训练数据线性不可分,那么感知机算法将永远不会收敛。这就是为什么在实践中通常不建议使用感知机算法。接下来的几节将研究更强大的线性分类器,即使训练数据不是完全线性可分的,这些分类器也会收敛到损失函数局部最小值。

设置感知机的其他参数

Perceptron以及Scikit-Learn中的其他函数和类通常会存在一些我们不清楚的参数。可以使用Python的help函数(例如help(Perceptron))获取关于这些参数的更多描述,或者还可以学习Scikit-Learn在线官方文档(http://scikit-learn.org/stable/)。 68eVC5RMZYNwqYOeqUadPkdtppSEacvcVJLA8R3B3jI7iNDXoA1ui8bRJrN8B/m1

点击中间区域
呼出菜单
上一章
目录
下一章
×