课程导论:为什么需要系统学习打分函数?
说实话,我刚开始做机器学习那会儿,根本不把打分函数当回事。
模型能跑起来,准确率看着还行,就完事了。直到有一次,我做了一个信贷违约预测模型——准确率98%,领导很开心,结果上线第一天就崩了。模型把所有的违约客户都放过去了。嗯,那笔损失够我记一辈子。
从那以后,我再也不敢小看打分函数了。
打分函数到底是什么?
说白了,打分函数就是衡量模型好坏的尺子。你做了一个模型,它到底行不行?不能光靠感觉。分类有分类的尺子,回归有回归的尺子,聚类也有聚类的尺子。
选错了尺子,模型的真实效果就会被扭曲。我个人习惯是,拿到一个任务先问自己三个问题:
- 任务类型是什么? 分类、回归还是聚类?
- 业务关注什么? 是避免漏报,还是避免误报?
- 数据有什么特点? 是否不平衡?有没有异常值?
这三个问题想清楚了,打分函数的选择就已经完成了一半。
分类任务:选错指标真的会翻车
分类任务中最常见的就是准确率。但准确率有一个很大的陷阱——在类别不平衡的时候,它会骗人。
就像我刚才说的信贷违约例子,正样本只占5%,模型全预测成"正常",准确率照样95%。但这样的模型有什么用?它把所有的坏人全放过去了。
所以我们需要更精细的指标。每个指标都反映了模型的不同侧面:
| 指标 | 关注点 | 适用场景 |
|---|---|---|
| 准确率 | 整体预测正确率 | 类别均衡,错误代价相同 |
| 精确率 | 预测为正样本中有多少是真正的正样本 | 避免误报(如垃圾邮件过滤) |
| 召回率 | 真正的正样本中有多少被找出来了 | 避免漏报(如疾病筛查) |
| F1分数 | 精确率和召回率的调和平均 | 需要平衡精确率和召回率时 |
| AUC-ROC | 模型对正负样本的排序能力 | 排序场景,阈值不确定时 |
我建议你在做分类任务时,至少同时看精确率、召回率和F1。只盯一个指标,很容易被带偏。
举个例子,计算F1分数并不复杂:
from sklearn.metrics import f1_score
y_true = [0, 1, 0, 1, 1, 0]
y_pred = [0, 1, 0, 0, 1, 0]
f1 = f1_score(y_true, y_pred)
print(f"F1分数: {f1:.3f}")
回归任务:不只是看误差大小
回归任务最常用的打分函数是MSE和MAE。你想想看,这两个指标虽然都是算误差,但性格完全不同。
- MSE 对异常值极其敏感——误差平方会放大离群点的影响。
- MAE 更稳健,每个样本的贡献是线性的。
我记得有一次做房价预测,MSE一直降不下去。调了好多天参数都没用,后来把MSE和MAE同时打印出来一看——MSE很大,但MAE其实已经很小了。说明是少数几个极端值在拉扯MSE。换成MAE作为主要优化目标后,模型在大部分样本上的表现反而更好了。
from sklearn.metrics import mean_squared_error, mean_absolute_error
y_true = [3.0, 5.0, 2.5, 7.0, 12.0]
y_pred = [2.8, 5.2, 2.3, 6.5, 8.0]
mse = mean_squared_error(y_true, y_pred)
mae = mean_absolute_error(y_true, y_pred)
print(f"MSE: {mse:.4f}")
print(f"MAE: {mae:.4f}")
你看第5个样本,真实值12.0,预测值8.0,误差4.0。MSE里它贡献了16.0,而MAE只贡献了4.0。这就是MSE对异常值更敏感的原因。
聚类任务:没有标签怎么评?
聚类任务的评估就比较特殊了。没有真实标签,怎么知道聚类好不好?
常用的方法有轮廓系数、Davies-Bouldin指数、Calinski-Harabasz指数。这些指标都是通过计算样本之间的距离来评估聚类效果的。
| 指标 | 原理 | 说明 |
|---|---|---|
| 轮廓系数 | 样本与自身簇的紧密度 vs 与最近簇的分离度 | 范围[-1, 1],越大越好 |
| Davies-Bouldin | 簇内距离与簇间距离的比值 | 越小越好 |
| Calinski-Harabasz | 簇间离散度 vs 簇内离散度 | 越大越好 |
我曾经在一个用户分群项目中,只用轮廓系数调参。结果分出来的群在统计上很漂亮,但业务上根本解释不通——比如把高消费低频次和低消费高频次的用户混在一起。后来我学乖了,聚类评估一定要结合业务验证。
from sklearn.metrics import silhouette_score
from sklearn.cluster import KMeans
X = [[1, 2], [2, 3], [8, 9], [9, 10], [1.5, 2.5]]
labels = KMeans(n_clusters=2, random_state=42).fit_predict(X)
score = silhouette_score(X, labels)
print(f"轮廓系数: {score:.3f}")
课程框架:30章我们怎么学?
这门课分为四个模块,从基础到进阶,从理论到实战:
| 模块 | 章节 | 核心内容 |
|---|---|---|
| 基础篇 | 1 — 5 | 导论、分类/回归/聚类指标精讲、选择策略 |
| 进阶篇 | 6 — 15 | 各指标的参数配置、调优技巧、陷阱规避 |
| 实战篇 | 16 — 25 | 金融、医疗、推荐、NLP等场景的最佳实践 |
| 专题篇 | 26 — 30 | 多指标融合、自定义打分函数、前沿方法 |
下面这张图展示了打分函数的全景体系,也是整门课的知识骨架:
第一,打分函数不是死记硬背的公式,而是理解模型行为的窗口。
第二,没有万能指标,只有最适配业务目标的评估策略。
第三,30章走完,你会拥有一套自己的打分函数选型框架。