机器学习不平衡分类:精确率、召回率与F1分数详解
1. 不平衡分类问题的评估挑战
在机器学习实践中,我们常常会遇到类别分布严重不均衡的数据集。比如在医疗诊断中,健康人群样本可能占99%,而患病样本仅占1%。如果直接用准确率(Accuracy)评估模型,一个总是预测"健康"的傻瓜模型就能获得99%的"高准确率",这显然掩盖了模型对少数类的识别能力。此时就需要引入更精细的评估指标——精确率(Precision)、召回率(Recall)和F1分数(F-Measure)。
这三个指标构成了分类模型评估的金三角,特别适合以下场景:
- 欺诈检测(正常交易远多于欺诈交易)
- 罕见病诊断(健康样本远多于患病样本)
- 网络入侵检测(正常流量远多于攻击流量)
- 产品质量检测(合格品远多于缺陷品)
关键认知:当少数类样本占比低于20%时,就应该警惕评估指标的选择,准确率此时可能产生严重误导。
2. 核心指标数学原理拆解
2.1 混淆矩阵基础
所有分类指标都源于混淆矩阵(Confusion Matrix)。以二分类为例:
| 预测为正类 | 预测为负类 | |
|---|---|---|
| 实际为正类(TP) | 80 | 20(FN) |
| 实际为负类(FP) | 30 | 870(TN) |
- TP(True Positive):模型正确预测的正例
- FP(False Positive):模型误判为正例的负例(误报)
- FN(False Negative):模型漏判的正例(漏报)
- TN(True Negative):模型正确预测的负例
2.2 精确率(Precision)计算
精确率衡量模型预测为正类的样本中,真实正类的比例:
$$ Precision = \frac{TP}{TP + FP} $$
在前例中: $$ Precision = \frac{80}{80+30} = 0.727 $$
高精确率意味着当模型预测为正类时,结果可信度高。适用于重视预测准确性的场景,如垃圾邮件分类(用户不希望正常邮件被误判为垃圾邮件)。
2.3 召回率(Recall)计算
召回率衡量实际正类被模型正确识别的比例:
$$ Recall = \frac{TP}{TP + FN} $$
前例计算: $$ Recall = \frac{80}{80+20} = 0.8 $$
高召回率意味着模型能捕捉到更多真实正例。适用于漏检成本高的场景,如癌症筛查(宁可误诊也不愿漏诊)。
2.4 F1分数(F-Measure)计算
F1是精确率和召回率的调和平均数:
$$ F1 = 2 \times \frac{Precision \times Recall}{Precision + Recall} $$
前例计算: $$ F1 = 2 \times \frac{0.727 \times 0.8}{0.727 + 0.8} = 0.762 $$
调和平均的特性使得F1对两者都敏感,只有当Precision和Recall都较高时,F1才会高。这使其成为不平衡分类的综合评价指标。
3. Python实战计算指南
3.1 使用scikit-learn计算
from sklearn.metrics import precision_score, recall_score, f1_score
from sklearn.datasets import make_classification
from sklearn.linear_model import LogisticRegression
# 创建不平衡数据集(正:负=1:9)
X, y = make_classification(n_samples=1000, weights=[0.9, 0.1], random_state=42)
# 训练简单模型
model = LogisticRegression()
model.fit(X, y)
y_pred = model.predict(X)
# 计算指标
precision = precision_score(y, y_pred)
recall = recall_score(y, y_pred)
f1 = f1_score(y, y_pred)
print(f"Precision: {precision:.3f}, Recall: {recall:.3f}, F1: {f1:.3f}")
3.2 多分类场景处理
对于多类不平衡问题,有两种计算方式:
- macro:各类别指标的算术平均
- weighted:按各类别样本量加权平均
# 多分类指标计算
precision_macro = precision_score(y, y_pred, average='macro')
recall_weighted = recall_score(y, y_pred, average='weighted')
经验选择:当关注所有类别平等表现时用macro,当需要考虑类别不平衡时用weighted。
4. 实际应用中的陷阱与对策
4.1 指标选择的常见误区
-
误区一:盲目追求单一指标
- 只优化Recall可能导致大量FP(如把所有样本预测为正类)
- 只优化Precision可能导致大量FN(模型过于保守)
-
误区二:忽视业务场景
- 反欺诈系统:通常更重视Recall(宁可误杀不可放过)
- 推荐系统:通常更重视Precision(推荐内容必须精准)
4.2 样本极度不平衡时的调整策略
当正负样本比超过1:100时:
-
重采样技术
- 过采样少数类(SMOTE算法)
- 欠采样多数类(随机删除)
-
代价敏感学习
# 设置类别权重 model = LogisticRegression(class_weight={0:1, 1:10}) -
阈值调整
# 默认阈值为0.5,可调整以平衡Precision/Recall y_prob = model.predict_proba(X)[:, 1] y_pred_adjusted = (y_prob > 0.3).astype(int) # 降低阈值提高Recall
4.3 指标波动问题处理
当评估指标在不同测试集上波动较大时:
-
采用分层K折交叉验证
from sklearn.model_selection import cross_val_score f1_scores = cross_val_score(model, X, y, cv=5, scoring='f1') -
使用Bootstrapping计算置信区间
from sklearn.utils import resample stats = [] for _ in range(1000): X_resample, y_resample = resample(X, y) model.fit(X_resample, y_resample) stats.append(f1_score(y, model.predict(X))) print(f"F1 95% CI: [{np.percentile(stats, 2.5):.3f}, {np.percentile(stats, 97.5):.3f}]")
5. 进阶应用场景
5.1 PR曲线与ROC曲线的选择
-
PR曲线(Precision-Recall Curve):
- 更适合极度不平衡数据
- 关注正类的识别能力
- 面积表示为AP(Average Precision)
-
ROC曲线(Receiver Operating Characteristic):
- 同时考虑正负类表现
- 更适合相对平衡的数据
- 面积表示为AUC
from sklearn.metrics import plot_precision_recall_curve
import matplotlib.pyplot as plt
disp = plot_precision_recall_curve(model, X, y)
plt.title('Precision-Recall Curve for Imbalanced Data')
plt.show()
5.2 阈值移动技术
通过调整分类阈值来优化业务指标:
from sklearn.metrics import precision_recall_curve
precisions, recalls, thresholds = precision_recall_curve(y, y_prob)
# 找到满足Recall≥90%的最高Precision阈值
target_recall = 0.9
idx = np.argmax(recalls >= target_recall)
optimal_threshold = thresholds[idx]
5.3 自定义损失函数
当标准指标无法满足需求时,可自定义:
from sklearn.metrics import make_scorer
def custom_f2_score(y_true, y_pred):
precision = precision_score(y_true, y_pred)
recall = recall_score(y_true, y_pred)
return 5 * (precision * recall) / (4 * precision + recall)
f2_scorer = make_scorer(custom_f2_score)
6. 行业最佳实践建议
-
医疗诊断领域:
- 优先保证高Recall(降低漏诊率)
- 典型目标:Recall > 95%,同时Precision > 50%
-
金融风控领域:
- 平衡Precision和Recall
- 典型目标:F1 > 0.7,单边指标不低于0.6
-
推荐系统领域:
- 优先保证高Precision(推荐准确性)
- 典型目标:Precision > 80%,Recall可适当放宽
实际项目中,我通常会建立如下评估流程:
- 先看类别分布,判断是否不平衡
- 根据业务需求确定指标优先级
- 绘制PR曲线寻找最佳操作点
- 用交叉验证验证指标稳定性
- 最终选择满足业务需求的最小复杂度模型
更多推荐


所有评论(0)