首页 » python机器学习 » python机器学习全文在线阅读

《python机器学习》3.2 初涉scikit-learn的使用

关灯直达底部

在第2章中,我们学习了两种相关的分类算法:感知器规则算法和Adaline算法,我们使用Python自行实现了这两种算法。现在,了解一下scikit-learn的API,它在实现几种高度优化的分类算法的同时,还提供了一个用户友好的接口。不过,scikit-learn库不仅提供了大量的学习算法,还包含许多用于对数据进行预处理、调优和对模型评估的功能。第4章和第5章会讨论这些问题和相关概念。

使用scikit-learn训练感知器

首先,我们使用scikit-learn训练一个感知器模型,此模型与第2章中实现的感知器模型类似。为了简单起见,我们将在本章后续几节中使用我们已经熟悉的鸢尾花数据集。由于鸢尾花数据集是一个简单、流行的数据集,它经常用于算法实验与测试,因此它已经默认包含在scikit-learn库中。同样,出于可视化应用的考虑,我们仍旧只使用鸢尾花数据集中的两个特征。

提取150个花朵样本中的花瓣长度和花瓣宽度两个特征的值,并由此构建特征矩阵X,同时将对应花朵所属类型的类标赋值给向量y:

如果执行np.unique(y)返回存储在iris.target中的各类花朵的类标,可以看到:scikit-learn已分别将Iris-Sentosa、Iris-Versicolor和Iris-Virginia的类名另存为整数(0,1,2),对许多机器学习库来说,这是针对性能优化一种推荐的做法。

为了评估训练得到的模型在未知数据上的表现,我们进一步将数据集划分为训练数据集和测试数据集。第5章会更加详细地讨论关于模型验证的操作细节。

使用scikit-learn中cross_validation模块中的train_test_split函数,随机将数据矩阵X与类标向量y按照3:7的比例划分为测试数据集(45个样本)和训练数据集(105个样本)。

第2章关于梯度下降的例子已经提到:为了优化性能,许多机器学习和优化算法都要求对数据做特征缩放。在此,我们将使用scikit-learn的preprocessing模块中的StandardScaler类对特征进行标准化处理。

在上面的代码中,从preprocessing模块中加载了StandardScaler类,并实例化了一个StandardScaler对象,用变量sc作为对它的引用。使用StandardScaler中的fit方法,可以计算训练数据中每个特征的μ(样本均值)和σ(标准差)。通过调用transform方法,可以使用前面计算得到的μ和σ来对训练数据做标准化处理。需注意的是,我们要使用相同的缩放参数分别处理训练和测试数据集,以保证它们的值是彼此相当的。

在对训练数据做了标准化处理后,我们现在可以训练感知器模型了。scikit-learn中的大多数算法本身就使用一对多(One-vs-Rest,OvR)方法来支持多类别分类,因此,我们可以将三种鸢尾花的数据同时输入到感知器中。代码如下:

对于使用scikit-learn的接口训练感知器,其流程与我们在第2章中实现的感知器的流程类似:在加载了linear_model模块中的Perceptron类后,我们实例化了一个新的Perceptron对象,并通过fit方法训练模型。此模型中的参数eta0与我们自行实现的感知器中的学习速率eta等价,而参数n_iter定义了迭代的次数(遍历训练数据集的次数)。第2章提到:合适的学习速率需要通过实验来获取。如果学习速率太大,算法可能会跳过全局最优点;如果学习速率太小,算法将需要更多次的迭代以达到收敛,这将导致训练速度变慢——尤其是面临巨大的数据集时。此外,我们使用random_state参数在每次迭代后初始化重排训练数据集。

与第2章中实现的感知器一样,使用scikit-learn完成模型的训练后,就可以在测试数据集上使用predict方法进行预测了,代码如下:

执行上述代码后,可以看到,在感知器对45朵花的分类结果中,有4个是错误的。也就是在测试数据集上的错误率为0.089或者说是8.9%(4/45约等于0.089)。

许多机器学习从业者通常使用准确率而不是误分类率来评判一个模型,它们之间的关系如下:

1-误分类率=0.911或91.1%

在metrics模块中,scikit-learn还实现了许多不同的性能矩阵。例如,可以通过下列代码计算感知器在测试数据集上的分类准确率:

此处,y_test是真实的类标,而y_pred是通过前面预测得到的类标。

本章我们使用测试集评估模型的性能。在第5章中,读者将学到使用诸如学习曲线等图形分析工具来检测并预防过拟合(overfitting)。过拟合意味着模型很好地捕获到了训练数据集中的模式,但是却无法泛化到未知的新数据上。

最后,可以使用在第2章中实现的plot_decision_regions函数来绘制刚刚训练过的模型的决策区域,并观察不同花朵样本的分类效果。不过,我们做少许修改:使用小圆圈来高亮显示来自测试数据集的样本:

对plot_decision_regions函数稍做修改后(前面代码中加重显示的部分),可以在结果呈现的图像中区分出哪些是我们需要预测的样本。代码如下:

从结果呈现的图像中我们可以看到,无法通过一个线性决策边界完美区分三类样本。

回忆一下第2章讨论过的内容:对于无法完美线性可分的数据集,感知器算法将永远无法收敛,这也是在实践中一般不推荐使用感知器算法的原因。后续几节,我们将着眼于更加先进的线性分类器算法,即使是面对无法完美线性可分的数据集,这些算法也可以在一定程度上收敛。

Perceptron以及scikit-learn中其他的一些函数和类都包含许多额外的参数,为了清晰起见,我们忽略了这些参数。读者可以通过Python中的help函数(如help(Perceptron)),或者通过scikit-learn的在线文档(http://scikit-learn.org/stable/)来了解这些参数的相关信息。