别让训练集和测试集的低级错误毁掉你的机器学习模型评估
很多刚上手数据分析的朋友在跑模型时会遇到一个诡异的现象:在训练集上跑出来的准确率高达 98%,结果模型一上线或者换个数据集测试,性能直接崩到 60%。这种典型的“过拟合”或“评估失真”,绝大多数时候不是算法选错了,而是最基础的 Train-Test Split(训练集-测试集分割)环节出了问题。
很多人习惯性地直接调用 sklearn.model_selection 里的 train_test_split 函数,认为只要把数据分成了 8:2 就算完成了。但实际上,如果你不处理好两个核心参数,你的评估指标可能完全是在误导你。
第一个深坑是 random_state。在机器学习的实验过程中,“可复现性”是至关重要的。如果你在调用函数时不设置随机种子,每次运行代码时,数据集的切分结果都是随机的。这意味着你今天调优出的一个参数,可能仅仅是因为这次随机分到的测试集刚好比较“简单”,而不是模型真的变强了。在实际工程中,我们通常将其固定为 random_state=42(这是一个社区惯例),确保每次运行脚本时,训练集和测试集的样本索引完全一致,这样你才能在同一基准线上对比不同模型的性能。
第二个更致命的坑是类别不平衡导致的抽样偏差。想象一个金融反欺诈数据集,正常交易占 99%,欺诈交易只占 1%。如果你采用纯随机分割,极有可能出现测试集里根本没有欺诈样本,或者样本量少到无法支撑统计学意义上的评估。这时候,stratify 参数就成了救命稻草。通过设置 stratify=y(y 为目标标签列),train_test_split 会执行分层抽样,强制让训练集和测试集中的类别比例与原始数据集保持一致。
在实际操作中,我建议大家建立一套严格的校验流程,而不是相信函数的默认输出。一个标准的实操代码结构应该是:
from sklearn.model_selection import train_test_split
import pandas as pd
# X 为特征矩阵,y 为目标变量
X = df.drop('target', axis=1)
y = df['target']
# test_size=0.2 表示 20% 数据用于测试,stratify 确保类别分布一致
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y
)
为了确保分割逻辑没有出差错,在进入模型训练之前,必须执行两步强制检查。首先是维度检查,直接运行 X_train.shape 和 X_test.shape,确认样本量是否严格按照 8:2 分配,防止在数据预处理阶段不小心删除了行导致数量对不上。
其次是分布校验,这是最关键的一步。对于分类任务,建议立即运行 y_train.value_counts(normalize=True) 和 y_test.value_counts(normalize=True)。通过对比这两个结果,如果两者的比例差异超过 1%,且你本意是要做分层抽样,那么说明你的 stratify 参数没有生效,或者数据在分割前就已经被破坏了。
这套数据分割逻辑是所有机器学习项目的基石。无论你是准备构建复杂的 AI Agent,还是在尝试对大模型进行微调(SFT),如果最前端的数据切分就存在偏差,那么后续所有的 Loss 曲线和准确率指标都将失去参考价值。

没设随机种子的后果太惨了,每次跑结果都随机,被老板骂到怀疑人生。