第6章 模型评估与测试
2026/9/19大约 3 分钟
第6章 模型评估与测试
模型评估是AI测试的核心战场。你需要掌握离线评估、在线评估、A/B测试等完整方法论,能够对模型的质量给出
有数据支撑的结论。
6.1 离线评估 (Offline Evaluation)
离线评估在部署前使用测试数据集对模型进行评估。这是最基本的评估方式。
6.1.1 交叉验证
K折交叉验证将数据分成K份,每次用K-1份训练、1份验证,重复K次取平均。这样可以更可靠地估计模型的泛化性能,避
免数据集划分的偶然性。
from sklearn.model_selection import cross_val_score
from sklearn.metrics import make_scorer, f1_score
# 5折交叉验证
f1_scorer = make_scorer(f1_score, average='weighted')
scores = cross_val_score(
model, X, y, cv=5, scoring=f1_scorer
)
print(f'F1均值: {scores.mean():.3f} +/- {scores.std():.3f}')
# 分层K折(保持类别比例)
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)6.1.2 全面评估报告
from sklearn.metrics import classification_report
from sklearn.metrics import roc_auc_score, average_precision_score
def comprehensive_evaluation(y_true, y_pred, y_prob):'''全面模型评估报告'''
# 分类报告(精确率/召回率/F1)
print(classification_report(y_true, y_pred))
# AUC指标
if y_prob is not None:
auc = roc_auc_score(y_true, y_prob)
ap = average_precision_score(y_true, y_prob)
print(f'AUC-ROC: {auc:.3f}')
print(f'AP (PR-AUC): {ap:.3f}')
# 错误分析
errors = [(i, t, p) for i, (t, p)
in enumerate(zip(y_true, y_pred)) if t != p]
print(f'错误样本数: {len(errors)}/{len(y_true)}')
return errors6.2 在线评估与A/B测试
6.2.1 A/B测试设计
A/B测试是在线评估的黄金标准,通过将流量随机分配到不同模型版本,比较它们在真实用户上的表现。
| 要素 | 说明 | 示例 |
|---|---|---|
| 实验假设 | 新模型在X指标上优于旧模型 | 新推荐模型CTR提升5% |
| 随机分组 | 用户随机分配到控制组/实验组 | 50%/50%流量分配 |
| 样本量计算 | 基于效应大小和功效计算 | 需要10000+用户样本 |
| 观测指标 | 主指标+护栏指标 | 主:CTR; 护栏:加载时间 |
| 统计检验 | t检验/卡方检验判断显著性 | p<0.05即显著 |
| 运行时长 | 足够收集样本且覆盖周期 | 至少1-2周完整周期 |
6.2.2 A/B测试常见陷阱
常见错误:过早停止实验(p值刚到0.05就下结论)、忽略多重比较问题(同时看20个指标必有假阳性)、忽略新奇效
应(用户对新版本的短期好奇不代表长期偏好)。
6.3 模型鲁棒性测试
鲁棒性测试评估模型在面对噪声、对抗样本和分布外数据时的稳定性。
def test_robustness(model, test_data):'''模型鲁棒性测试套件'''
results = {}
# 1. 噪声注入测试
noisy_data = add_gaussian_noise(test_data, sigma=0.1)
results['noise_0.1'] = model.evaluate(noisy_data)
# 2. 特征缺失测试
for col in important_features:
masked = mask_feature(test_data, col)
results[f'missing_{col}'] = model.evaluate(masked)
# 3. 文本扰动测试
perturbations = [
('typo', add_typos),
('synonym', replace_synonyms),
('reorder', shuffle_words),
]
for name, func in perturbations:
perturbed = func(test_data)
results[name] = model.evaluate(perturbed)
return results6.4 模型公平性测试
公平性测试确保模型不会对特定群体产生歧视。这在招聘、信贷、医疗等高风险场景中至关重要。
6.4.1 公平性指标
| 指标 | 定义 | 达标标准 |
|---|---|---|
| 统计均等 | 各组正预测率相近 | 差异<0.1 |
| 机会均等 | 各组真正率相近 | 差异<0.1 |
| 预测均等 | 各组误正率相近 | 差异<0.1 |
| 校准均等 | 各组预测概率校准 | 差异<0.05 |
| 个体公平 | 相似个体得到相似预测 | 距离度量 |
def test_fairness(model, test_data, sensitive_attr):
'''公平性测试'''
groups = test_data.groupby(sensitive_attr)
metrics = {}
for name, group in groups:
y_true = group['label']
y_pred = model.predict(group)
metrics[name] = {
'accuracy': accuracy_score(y_true, y_pred),
'positive_rate': y_pred.mean(),
'tpr': recall_score(y_true, y_pred),
'fpr': false_positive_rate(y_true, y_pred),
}
# 检查组间差异
for metric_name in ['accuracy', 'positive_rate', 'tpr']:
vals = [m[metric_name] for m in metrics.values()]
gap = max(vals) - min(vals)
status = 'PASS' if gap < 0.1 else 'FAIL'
print(f'{metric_name} gap={gap:.3f} [{status}]')