4.3 把数据集划分为独立的训练数据集和测试数据集

在第1章和第3章中,我们简要地介绍了把数据集划分成独立的训练数据集和测试数据集的概念。记住,比较预测值与测试数据集的真值,可以理解为对模型所做的无偏置性能评估,然后再将其放到现实世界。本节将创建一个新数据集,即葡萄酒(Wine)数据集。在对数据集进行预处理后,我们再进一步探索用于数据集降维的不同特征选择技术。

葡萄酒数据集是另一个开源数据集,读者可以从UCI的机器学习资源库(https://archive.ics.uci.edu/ml/datasets/Wine)获得;该数据集包含了有13个特征的178个葡萄酒样本,从不同角度对各个化学特性进行了描述。

008-01

获取葡萄酒数据集

读者可以在本书的代码包(https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data)中找到葡萄酒数据集(以及本书用到的其他数据集),以备在脱机工作或者UCI服务器暂时不可用时使用,如果要从本地目录加载葡萄酒数据集,可以将下面这行

093-01

替换为:

093-02

可以直接用pandas库从UCI的机器学习资源库读入开源的葡萄酒数据集:

093-03

表4-1中列出了葡萄酒数据集的13个特征,描述178个葡萄酒样本的化学性质。

表4-1 葡萄酒数据集的13个化学特征

093-04

这些样本来自123类葡萄酒,分别对应意大利同一地区种植的三种不同品种的葡萄,如数据集摘要中所描述的那样(https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.names)。

把数据集随机划分成独立的训练数据集和测试数据集的一个便捷方法是,从scikit-learn的model_selection子模块调用train_test_split函数:

094-01

首先把NumPy数组的1~13特征列赋予变量X;把第一列的分类标签赋予变量y。调用train_test_split函数把xy随机划分成独立的训练数据集和测试数据集。通过设置test_size = 0.3,把30%的葡萄酒样本分配给X_testy_test,把余下70%的样本分配给X_trainy_train。把分类标签数组y作为参数提供给stratify,确保训练数据集和测试数据集拥有与原始数据集相同的分类比例。

008-01

选择划分训练数据集和测试数据集的合适比例

把数据集分为训练数据集和测试数据集的目的是要确保机器学习算法可以从中获得有价值的信息。因此没必要将太多信息分配给测试数据集。然而,测试数据集越小,泛化误差的估计就越不准确。将数据集分为训练数据集和测试数据集就是对两者的平衡。在实践中,根据初始数据集的规模,最常用的划分比例为60:40、70:30或80:20。然而,对于大规模数据集,把训练数据集和测试数据集的划分比例定为90:10或99:1也是常见和适当的做法。例如,如果数据集包含超过100000个训练样本,则可以仅保留10000个样本进行测试,以获得对泛化性能的良好估计。更多的信息和图示可以查阅我写的“Model evaluation, model selection, and algorithm selection in machine learning”,该文章可从https://arxiv.org/pdf/1811.12808.pdf免费获得。

此外,在模型训练和评估后,通常不会丢弃分配的测试数据。普遍的做法是在整个数据集上保留一个分类器,以提高模型的预测性能。虽然我们通常推荐这种方法,但是它有可能会导致较差的泛化性能,例如当数据集的规模很小而且测试数据集中包含异常值的时候。此外,在整个数据集上重新拟合模型后,我们将没有任何独立的数据来评估性能。