模型跑完了,训练集和测试集的分数都挺高,模型文件用 pickle 一存,高高兴兴准备上线。结果线上效果惨不忍睹——这是不少机器学习项目的真实写照。我把这类问题统称为“评估失效”:不是模型本身不行,而是评估方式掩盖了模型的真实水平,让你误以为一切正常。
使用 Scikit-learn 做机器学习模型评估,工具本身并不复杂:train_test_split、cross_val_score、各种 metrics 函数,API 清晰,初学者半天就能上手。但真正难的不是调用 API,而是理解每个工具背后的假设和适用场景。这篇文章从数据划分讲起,覆盖分类和回归的常用评估指标,最后聊聊我在实际项目中踩过的评估相关的坑,希望能帮你少走一些弯路。无论你是刚开始接触机器学习的入门者,还是已经做了一两个项目的工程同学,这篇文章都值得花十几分钟完整看完。
1. 模型评估为何会成为项目分水岭
1.1 评估的核心命题:泛化能力
模型评估回答的问题只有一个:训练好的模型,在面对从来没见过的数据时,能不能给出可靠的预测?
这就像学生考试。平时作业做了无数遍,就算全对也不能说明知识真的掌握了;只有拿到一道全新的题,还能正确解出来,才算真正学会了。机器学习模型也是一样——训练数据是“平时作业”,测试数据是“期末考试”。Scikit-learn 把数据集拆成训练集和测试集,本质就是在模拟这场考试。
如果评估环节出了问题,后果可能非常隐蔽。模型在测试集上分数很高,你以为万事大吉,实际上模型可能只是“背题”背得好,并没有学到背后的规律。等到上线面对真实数据,各种没见过的分布漂移、噪声、边界情况涌过来,模型的真实水平一下就暴露了。这个落差感,做过的朋友应该都懂。
所以模型评估不是一个走过场的环节,它是项目能否从实验状态走向生产环境的关键判断依据。评估做对了,你能清楚知道模型的能力边界;评估做错了,你连自己模型到底行不行都不知道,后面的所有决策都建立在错误的地基上。
1.2 一次失败上线带给我的教训
我自己的第一次“评估翻车”发生在两年前的一个分类项目上。当时我负责做一个用户流失预警模型,正负样本比例大概 1:19,也就是约 5% 的用户会流失。模型训练完之后,我看了一下准确率,95%,当时心里还挺满意,觉得这个模型效果不错。结果上线之后,业务方反馈:模型几乎没预警出几个真正会流失的用户,完全没法用。
排查之后我才明白问题出在哪。因为正样本只占 5%,模型只要把所有用户都预测成“不流失”,准确率自然就是 95%。也就是说,模型根本没有学到任何有效模式,只是靠瞎猜加数据倾斜“躺赢”了。这个案例给我留下了非常深的印象——准确率这个指标,在类别不平衡的场景下,不仅没有参考价值,还会产生强烈的误导。
也是从那次之后,我开始认真梳理评估指标、数据划分策略、交叉验证的用法,并且把“先看数据分布,再选评估指标”写进了自己的项目检查清单。后面做的几个项目,每次评估前都会先问自己三个问题:数据怎么切、指标怎么选、有没有泄漏。看似简单的三个问题,实际上能避开绝大多数评估陷阱。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 数据划分的层次与方法:从简单切分到交叉验证
2.1 train_test_split 的参数,尤其是 stratify
Scikit-learn 里最基础的数据划分函数是 train_test_split。它看起来简单,但几个参数如果不理解清楚,很容易给自己埋雷。
python复制from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
X, y,
test_size=0.2,
random_state=42,
stratify=y
)
test_size 控制测试集占比。数据量大的时候,比例可以稍微调低到 0.15 到 0.2;数据量小的时候,建议保留 0.25 到 0.3 做测试,否则测试集样本太少,评估结果随机波动会非常大。
random_state 是随机种子。如果你不设置它,每次运行划分结果都不同,模型评估结果无法复现。今天跑出来准确率 0.92,明天再跑变成 0.88,你没法判断到底是模型问题还是数据划分偶然性太大。设一个固定值,是保证实验可复现最基本的一步。
stratify 是分层抽样参数。很多人在初学阶段会忽略它,但对于分类任务来说,这个参数的重要性不亚于模型本身。它的作用是让训练集和测试集中的类别比例与原始数据保持一致。
用一个场景来说明:假设原始数据中 A 类占 80%,B 类占 20%。如果不加 stratify,随机划分有可能让测试集里 A 类占到了 90%,B 类只剩 10%。这会导致测试集不能代表真实数据分布,评估结果失真。传入 stratify
