mcpField
M
ml-evaluation

ml-evaluation

github.com/josiahsiegel数据与数据库5956 次安装19 周前更新
代码仓库

关于 ml-evaluation

面向机器学习系统开发与部署的评估指南,涵盖数据划分、指标选择、统计比较、错误分析和上线监测,帮助判断性能变化是否可靠且符合实际决策。

主要功能

  1. 01选择与决策目标相符的指标
  2. 02设计分组与时间序列划分
  3. 03用置信区间和配对检验比较
  4. 04分析错误切片与模型稳健性
  5. 05规划上线评估和漂移监测

适用场景

  1. 01避免训练测试数据泄漏
  2. 02比较同一测试样本上的模型
  3. 03检查不同用户群体的表现
  4. 04上线前制定监测与回滚标准

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/josiahsiegel/claude-plugin-marketplace --skill ml-evaluation

安装后在 Claude Code 中输入/ml-evaluation确认已加载。

详细介绍

机器学习评估

概览

在部署前、部署期间和部署后评估机器学习系统时,请使用此技能。有效的评估应回答:哪些决策会使用模型、哪些数据分布很重要、存在哪些失误成本、哪个指标能体现这些成本,以及测得的改进究竟是真实的,还是由数据泄漏、方差或对验证集过拟合造成的。

评估设计检查清单

  1. 定义预测单位和独立性单位。当样本存在相关性时,按用户、账户、患者、设备、文档、会话或时间进行划分。
  2. 使用简单的启发式方法、先前模型或线性/树模型基线,确定基线性能。
  3. 选择与决策相匹配的指标,而不只是方便使用的默认指标。
  4. 在最终评估之前冻结测试数据;使用验证数据进行调优。
  5. 评估不同切片:标签、地理区域、设备、语言、适当时的群体特征、数据来源、时间段和已知难例。
  6. 当样本量有限时,使用置信区间或重复交叉验证报告不确定性。
  7. 在扩大模型复杂度之前,进行定性错误分析。

数据集划分策略

仅当数据为独立同分布且样本彼此独立时,才使用随机分层划分。多行数据共享同一实体时,使用分组划分。在预测、推荐、欺诈检测、日志分析,以及任何未来数据不同于过去数据的部署场景中,使用基于时间的划分。当需要对超参数和性能估计同时进行无偏评估时,使用嵌套交叉验证。对于小型数据集,重复分层交叉验证可以降低方差;但当风险较高时,应保留一个从未使用过的最终测试集。

全面的数据泄漏预防检查清单
  • 先划分再拟合:仅在训练子集上应用 scaler.fit()、imputer.fit() 和编码器拟合。切勿在整个数据集上拟合。
  • 时间单调性:对于时间序列划分,确保验证集/测试集索引在时间顺序上严格晚于训练集索引。
  • 分组隔离:确认共享分组因素(例如患者 ID、公司 ID、会话 ID)的数据点不会同时出现在训练集和测试集中。
  • 目标泄漏:检查是否存在表示预测时间之后事件的列(例如流失模型中的“refunded_date”)。
  • 划分前不做增强:在划分之后再进行少数类过采样(例如 SMOTE)或数据增强。划分前进行过采样会导致合成的孪生样本跨越数据集边界。

指标选择

任务首选指标注意事项
平衡分类准确率、宏 F1、对数损失准确率会掩盖校准问题和少数类错误
不平衡分类PR-AUC、给定精确率下的召回率、F-beta、成本效用即使正类精确率很差,ROC-AUC 也可能看起来很高
概率分类对数损失、Brier 分数、校准曲线阈值指标会忽略概率质量
回归MAE、RMSE、RMSLE、pinball loss、R2RMSE 对异常值的权重过高;MAPE 在接近零时会失效
排序/检索NDCG、MAP、MRR、recall@k、precision@k离线负样本可能无法代表生产环境中的候选项
预测sMAPE、MASE、pinball loss、覆盖率随机划分会泄漏未来模式
生成特定任务的人工/评估模型评分标准,加上自动化检查单独使用 BLEU/ROUGE 往往无法衡量实用性和安全性
Embeddings/RAGRecall@k、MRR、答案忠实度、依据充分性、延迟必须区分检索失败和生成失败

对于高风险决策,应使用混淆矩阵和成本曲线评估运行阈值。在验证集上优化阈值,然后报告在测试集上使用固定阈值的性能。当决策依赖概率时,应校准概率。

统计比较

不要将简单的指标差异视为证据。当模型在相同样本上进行评估时,应使用配对比较。

Bootstrap 置信区间(Python 示例)
import numpy as np
from sklearn.metrics import f1_score

def bootstrap_metric_ci(
    y_true: np.ndarray, 
    y_pred: np.ndarray, 
    metric_fn = f1_score,
    n_bootstrap: int = 1000, 
    confidence_level: float = 0.95
):
    bootstrapped_scores = []
    rng = np.random.default_rng(seed=42)
    n_samples = len(y_true)
    
    for _ in range(n_bootstrap):
        # Sample with replacement
        indices = rng.choice(n_samples, size=n_samples, replace=True)
        score = metric_fn(y_true[indices], y_pred[indices])
        bootstrapped_scores.append(score)
        
    sorted_scores = np.sort(bootstrapped_scores)
    alpha = 1.0 - confidence_level
    lower_idx = int(np.floor(alpha / 2.0 * n_bootstrap))
    upper_idx = int(np.ceil((1.0 - alpha / 2.0) * n_bootstrap))
    
    return sorted_scores[lower_idx], sorted_scores[upper_idx]
用于比较配对分类器的 McNemar 检验

McNemar 检验用于评估两个模型之间的分歧是否显著。

import numpy as np
from scipy.stats import chi2_contingency

def mcnemar_test(y_true: np.ndarray, pred_model_a: np.ndarray, pred_model_b: np.ndarray):
    # Contingency Table:
    #                 Model B Correct    Model B Incorrect
    # Model A Correct       n00                n01
    # Model A Incorrect     n10                n11
    
    correct_a = (pred_model_a == y_true)
    correct_b = (pred_model_b == y_true)
    
    n01 = np.sum(correct_a & ~correct_b) # A correct, B incorrect
    n10 = np.sum(~correct_a & correct_b) # A incorrect, B correct
    
    # Calculate chi-squared with continuity correction
    if n01 + n10 == 0:
        return 1.0 # Perfect agreement
        
    statistic = (abs(n01 - n10) - 1)**2 / (n01 + n10)
    # 1 degree of freedom
    from scipy.stats import chi2
    p_value = 1 - chi2.cdf(statistic, df=1)
    
    return p_value
用于 Logits 校准的温度缩放(PyTorch)
import torch
import torch.nn as nn
import torch.optim as optim

class TemperatureScaler(nn.Module):
    def __init__(self):
        super().__init__()
        # Initial temperature parameter of 1.0 (no scaling)
        self.temperature = nn.Parameter(torch.ones(1))

    def forward(self, logits: torch.Tensor):
        return logits / self.temperature

    def fit(self, val_logits: torch.Tensor, val_labels: torch.Tensor, max_iter: int = 50):
        # Optimizes temperature parameter on validation set
        nll_criterion = nn.CrossEntropyLoss()
        optimizer = optim.LBFGS([self.temperature], lr=0.01, max_iter=max_iter)
        
        def eval_loss():
            optimizer.zero_grad()
            loss = nll_criterion(self.forward(val_logits), val_labels)
            loss.backward()
            return loss
            
        optimizer.step(eval_loss)
        return self.temperature.item()

错误分析

创建结构化的错误分类体系,而不是随机检查失败案例。细分假阳性、假阴性、高置信度错误、低置信度正确案例、分布外示例、缺失值、稀有标签、长尾实体、提示词类别以及延迟/超时。

错误分析应转化为具体的改进措施:收集数据、重新标注、更改数据集划分、调整损失函数、添加特征、改进检索、校准阈值、简化模型或调整服务流水线。

负责任的 AI 与鲁棒性

评估模型在相关人口统计、地理、语言、无障碍和运营切片上的行为。选择符合领域要求的公平性指标:人口统计均等、均等化赔率、机会均等、按群体校准或反事实一致性。说明其中的权衡;公平性指标可能相互冲突。当用户需要了解原因时,可使用可解释模型或可解释性工具,但应验证解释的稳定性和合理性。

测试模型对缺失字段、架构变更、对抗性或含噪输入、LLM/RAG 系统的提示词注入、图像损坏、文本拼写错误、分布偏移和低资源切片的鲁棒性。部署前,务必制定监控计划,以监测数据漂移、性能漂移、校准漂移和安全事件。

生产环境评估

离线指标不可或缺,但仅靠它们还不够。发布前,在可行的情况下进行影子评估、回测、批量回放或金丝雀测试。针对相同示例比较训练和服务预处理的输出。明确回滚阈值、告警接收方、重新训练标准和负责人。对于 A/B 测试,应纳入延迟、成本、用户伤害、公平性切片、业务约束和支持负担等护栏指标。

常见评估问题

  • 验证结果出色,生产表现不佳:数据泄漏、分布偏移、服务偏差、阈值不匹配或验证集缺乏代表性。
  • ROC-AUC 很高,用户价值却很低:类别不平衡或阈值决策导致指标选择不当。
  • 平均指标提升,却损害了关键用户:缺少切片评估。
  • 测试集反复使用:对基准测试集发生隐性过拟合。
  • LLM 评估结果看似良好,但回答仍会产生幻觉:自动词汇指标未衡量依据是否充分、引用质量或拒答行为。

来源

评论

支持 Markdown