在第 2 章中,我们讨论了将数据划分为独立的训练集和测试集的重要性。现在,当我们专注于数据准备的实际步骤时,让我们再次看看如何进行这项必要的划分。请记住,目的是在数据的一部分(训练集)上训练我们的机器学习模型,然后在它从未见过的一个完全独立的部分(测试集)上评估其性能。这有助于我们了解模型对新的、未见过的数据泛化能力如何,而不是仅仅记住训练数据。为何要再次划分?评估泛化能力"想象一下为考试而学习。你使用练习题(训练数据)来学习材料。期末考试(测试数据)包含你以前没见过的题目。你在期末考试上的分数能说明你对知识的真实理解程度,而不仅仅是记住了练习题。同理,测试集能公正地评估你的模型在未来数据上的表现。"进行这种划分是一个标准步骤,它在初步数据清理(如处理缺失值)之后进行,但在你开始训练模型之前。使用库进行一致的划分虽然你可以手动切分数据,但更普遍和可靠的做法是使用机器学习库提供的函数。Python 的 scikit-learn 库提供了一个便捷的函数 train_test_split,正是为此目的。我们假设你的特征存储在变量 X 中(可能是 NumPy 数组或 Pandas DataFrame),而你对应的标签或目标值存储在变量 y 中。下面是你通常如何使用 train_test_split:# 首先,请确保已安装 scikit-learn # pip install scikit-learn # 导入函数 from sklearn.model_selection import train_test_split # 假设 X 包含特征,y 包含标签 # 例如: # X = dataframe[['feature1', 'feature2']] # y = dataframe['target_label'] # 划分数据:80% 用于训练,20% 用于测试 X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42 ) # 现在你有了: # X_train: 训练集的特征 # X_test: 测试集的特征 # y_train: 训练集的标签 # y_test: 测试集的标签我们来解析一下重要的参数:X, y: 这是你的输入特征和目标标签。该函数同时划分两者,确保特征和标签之间的对应关系在训练集和测试集中都得以保留。test_size: 这个参数决定了分配给测试集的数据集比例。值为 0.2 表示 20% 的数据将用于测试,剩余 80% 用于训练。你也可以指定 train_size。random_state: 这对可重现性很重要。机器学习常常涉及随机性(比如在划分前打乱数据)。将 random_state 设置为一个特定整数(例如 42,一个常用的任意选择),能确保每次运行代码时都得到完全相同的划分。这有助于调试、比较模型和分享结果。如果你省略 random_state,每次划分都会不同。digraph G { rankdir=LR; node [shape=box, style=filled, fillcolor="#e9ecef", fontname="Helvetica", margin=0.1]; edge [fontname="Helvetica"]; subgraph cluster_0 { style=filled; fillcolor="#f8f9fa"; label = "原始数据"; node [shape=record, fillcolor="#ced4da"]; Data [label="特征 (X) | 标签 (y)"]; } subgraph cluster_1 { style=filled; fillcolor="#f8f9fa"; label = "划分后的数据"; node [shape=record]; TrainData [label="训练特征 (X_train) | 训练标签 (y_train)", fillcolor="#a5d8ff"]; TestData [label="测试特征 (X_test) | 测试标签 (y_test)", fillcolor="#ffc9c9"]; } Data -> TrainData [label=" train_test_split\n (例如,80%)"]; Data -> TestData [label=" train_test_split\n (例如,20%)"]; }划分原始数据集(特征 X 和标签 y)为对应的训练集和测试集的一种视图,使用了像 train_test_split 这样的函数。分层划分用于分类设想一个分类问题,你在预测邮件是否是垃圾邮件。如果你的邮件中只有 5% 是垃圾邮件(一个不平衡数据集),纯粹的随机划分可能会意外地将几乎所有垃圾邮件都放入训练集,而测试集中却很少,反之亦然。这会给出模型在稀有类别上表现如何的误导性信息。为了处理这种情况,我们使用分层划分。分层划分确保原始数据集中每个类别的比例在训练集和测试集中都得以保留。在 scikit-learn 中,你可以通过向 train_test_split 添加 stratify 参数并将其设置为你的标签 y 来实现这一点:# 对于分类问题,特别是类别不平衡的情况: X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.2, random_state=42, stratify=y )通过添加 stratify=y,该函数将确保如果原始 y 标签中有 5% 是 'spam',那么 y_train 和 y_test 中也将有大约 5% 是 'spam'。这能带来更可靠的评估,尤其是在处理类别频率差异明显的数据集时。验证集:快速展望虽然训练-测试划分是基本步骤,但有时你需要另一个划分,称为验证集。这个集合在模型开发过程中使用,特别是在使用最终测试集之前调整模型设置(超参数)。我们在此不实现它,但了解更复杂的工作流程可能涉及将数据划分为三部分:训练、验证和测试,是很有用的。我们将在后续章节讨论模型调优时再次提到这个想法。目前,掌握训练-测试划分是必要的一步。它确保你在训练后评估模型时,能够公正地评估其处理新数据的能力,这是构建预测模型的最终目的。