关于 evaluate-ml-pipeline
evaluate-ml-pipeline 面向数据科学家,规范使用 skore 对单个学习器评分并保存报告。它涵盖授权、拆分器与指标处理、检查项及报告持久化。
主要功能
- 01执行一次 skore.evaluate
- 02复用已声明的拆分器和评分
- 03汇总并保存报告检查结果
- 04通过 Project.put 持久化报告
- 05支持 local、hub 和 mlflow 模式
适用场景
- 01评估已锁定的 ML 工作流
- 02在测试表上评估预拟合模型
- 03保存评估结果和检查项
- 04选择报告存储模式
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ probabl-ai/ skore-skills --skill evaluate-ml-pipeline安装后在 Claude Code 中输入/evaluate-ml-pipeline确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/custom-checks.mdcustom-metrics.mdg_skore_mode.mdmetadata-routing.mdreports.mdskrub_interop.mdtemplates/materialize.py详细介绍
评估 ML 流水线
为一名学习器评分并保存报告。流水线、拆分器以及任何非默认评分
均已声明。skore.evaluate 是入口。不要手动编写
cross_val_score、cross_validate、classification_report,
也不要打印指标。
SkrubLearner 不实现 sklearn 的 fit(X, y)。
cross_val_score 会报错。调用 skore.evaluate(learner, data={...})
并省略 splitter=,除非 translation.splitter 为 prefit。
面向用户的文案
详情:setup-workspace references/human_facing_prose.md。
实验 Markdown 和 # 注释用于描述此次评估。
问题和结尾使用相同的数据科学术语:不要使用技能 ID、
G-* 名称或包装器 CLI。
`` 是一个站点标记。
流程
python -m skore_skills status。如果status.setup.pending非空,且status.skills.setup-ml-project为 true, 则加载setup-ml-project并停止。不要启动此技能。 此技能返回后继续。本轮不要再次加载它。 如果未安装该技能,用一行列出待处理项并停止。 不要臆造git init、脚手架或env init。如果status.setup.env或status.setup.workspace为declined,用一行说明并停止。git或editable若已拒绝,则不再询问;继续。然后运行python -m skore_skills frame show,不要加--revise。如果status.modeling_decisions不是locked,包括draft,则返回model-ml-pipeline并停止。 不要征求同意或询问存储模式,也不要展示skore.evaluate调用,即使只是预览。任何非proceed的情况都加载frame-ml-problem并停止。translation为 null → 停止。不要编写评估调用。- 依赖历史的流水线(向后移位、滞后、滚动窗口、目标移位,或与带有侧向历史的数据联接):如果缺少
tests/smoke/test_<stem>.py,或 pytest 未通过, 则停止并返回 build(§ 返回 build)。不要编写skore.evaluate。只有不存在依赖历史的步骤时,才可记录 n/a。 python -m skore_skills evaluate consent --stem <stem>。- 若结果为
ask,且本轮尚未对build-ml-pipeline中的 Evaluate 作出回答:引用 JSONcontext,并提供 Evaluate (Recommended) / Modify / Stop 选项。然后停止。 首次运行时,“运行评估”不等于同意。 - 如果用户本轮已回答 Evaluate,或 JSON 为
proceed(已存在有效 locator):继续。 stop— 缺少 smoke 文件。返回 build(§ 返回 build)。
- 若结果为
- G-SKORE-MODE。读取
status.policy.skore_mode。如果已设置, 则保留。如果未设置,询问用户选择 local(推荐)/ hub / mlflow,然后运行python -m skore_skills policy set skore_mode <mode>。local:运行mkdir reports(exist_ok); 不要写入reports/README.md。hub 或 mlflow:不要 创建reports/。然后,如果已安装add-python-package,则加载它;它会运行env add-skore --mode <mode> --execute。 此处不要写出skore[...]。此处不要运行env add。 构造方式见:references/g_skore_mode.md。切换或迁移时,如果已安装sync-ml-reports,则加载该技能。 - 输出 Pre-flight,然后用 1–3 句话说明:这是使用已锁定方案进行的本地全数据集评估,包含报告指标、skore 检查项和
project.put。检查项会在本次运行中计算,并与报告一同存储。如果translation.splitter为prefit,说明模型在训练表上拟合,并在随附的测试表上评分。注明 stem、已知的折数,以及experiments/<stem>.py和scratch/results/<stem>/。 耗时取决于行数、折数、学习器和检查项。 不要臆造分钟数。如果仍待取得同意,则预览并停止。 - 仅在
experiments/NN_*.py中编写调用。参见下方的调用 形式。编辑后运行python -m skore_skills style。 实验在report.checks.summarize()、project.put和单独的report处结束。不要执行此文件。 - 将
templates/materialize.py复制到scratch/results/<stem>/materialize.py。替换 Project 初始化代码。将<CALL>代码块替换为实验调用,参数及顺序保持一致。使用env verify中的 composed-dev Python 运行该文件一次。这是唯一一次skore.evaluate调用,也是唯一一次project.put。读取id.txt,生成 locator,并写入locator.txt。当policy.notebooks为true时,运行python -m skore_skills notebook fill experiments/<stem>.py, 仅当policy.site也为true时才添加--html。不要对实验文件运行notebook convert,也不要运行实验文件。当 notebooks 为null或false时,不要更改策略,也不要填充。当policy.site为true且已安装export-ml-site时,在 locator 写入后、审计/审阅或其他用户确认环节前,运行python -m skore_skills site build --if-stale。这会立即展示结果查看器。它不能替代 record-outcome 后的结束时构建。然后结束本轮。 不要向实验文件添加 materialize 写入操作。 每次 Python 探测都写入scratch/<ts>_<short>.py,并使用env verify中组合好的开发环境 Python 运行。不要内联使用python -c。除非用户要求,否则不要使用warnings.filterwarnings。未经确认的签名不得写入。以BLOCKED: <class> signature needs an API lookup that cannot run this turn (<why>).结束该探测。命中缓存即视为已完成查询。
调用
在 experiments/NN_*.py 中调用 skore.evaluate。省略 splitter=,让 skore 复用 DataOp 的 cv 和 split_kwargs,除非 translation.splitter 为 prefit。传入其他任何 splitter= 都会丢弃 split_kwargs。未传入 splitter= 且 DataOp 没有 cv 时,会使用 80/20 留出法;仅当 translation.report 为 EstimatorReport 且 translation.splitter 为 null 时才正确。接线方式见:
references/metadata-routing.md。
当 translation.splitter 为 prefit 时,仅在训练表上拟合,然后对测试表评分。使用 api get 确认 fit 和 evaluate。不要将训练表传入 evaluate。此处省略 splitter= 会对测试表重新划分出一个 80/20 分割。不要拼接两张表。
learner = build_learner()
fitted = learner.fit({"table": train_df})
report = skore.evaluate(
fitted,
data={"table": test_df},
splitter="prefit",
)
fit 签名为 (X, y) 的估计器也遵循相同规则:
fitted_model = LogisticRegression().fit(X_train, y_train)
report = skore.evaluate(
fitted_model, X_test, y_test, splitter="prefit"
)
X / y 和 data 不能同时使用。
SkrubLearner—skore.evaluate(learner, data={...})。键为skrub.var名称。互操作说明见:references/skrub_interop.md。fit签名为(X, y)的估计器 —skore.evaluate(estimator, X, y)。如果锁定的cv已经是评估方案,仍应省略splitter=。上述 prefit 调用是例外:估计器已经拟合,且X和y是测试表。
mark_as_X 上的 cv 应为 KFold、GroupKFold,或 build 中的基于日期的类。如果 translation 指定了 cv,而标记上没有,则返回 build(§ 返回 build)。此处不要接入 split_kwargs。split_kwargs 为空且可能存在分组列时 → 返回 build。不要默认使用 KFold。translation.splitter 的 prefit 不是标记上的 cv。
类别不平衡时不要使用 Stratified*。它会压缩跨折方差。
核心指标为 translation.metric。如果某个名称在 build-ml-pipeline 的 skore 默认列表中,则无需 scorer,multioutput-regression 除外:默认回归指标按输出分别计算,而锁定的聚合指标必须已经通过 .skb.with_scoring(...) 添加。其他任何名称都必须已经通过 .skb.with_scoring(...) 添加到预测 DataOp 上。如果尚未添加,则在调用 skore.evaluate 前返回 build(§ 返回 build)。不要调用 report.metrics.add。添加 scorer 后,该名称会作为一行出现在 report.metrics.summarize().frame() 中。对于 multioutput-regression,该 frame 还会为每个输出各列一行。不要在实验文件中对这些行求平均。结尾可以引用锁定的聚合指标;各输出的行仍保留在已存储的报告中。skore.evaluate 没有 scoring= 参数(references/custom-metrics.md)。如果已添加该名称,但它仍未出现在该 frame 中,说明预测器类不正确:必须先使用 mixin,再使用 BaseEstimator(首先是 RegressorMixin 或 ClassifierMixin)。返回 build(§ 返回 build)。单独使用 BaseEstimator,或将 BaseEstimator 放在 mixin 之前,都会失败。
锁定后用户要求的额外检查:
references/custom-checks.md。在 experiments/NN_*.py 的模块级作用域中子类化 skore.Check,然后在 evaluate 之后、summarize 之前调用 report.checks.add(...)。add 会扩展 SKD 检查。不要杜撰检查。不要从 audit/ 注册检查。使用 api get 确认 Check 和 checks.add。
每次评估都要在 evaluate 之后以及任何 checks.add 之后调用不带参数的 report.checks.summarize(),然后调用 project.put。这样会将检查结果存储在报告中。不要传入 fast_mode 或 ignore。使用 api get 确认 checks.summarize。
report = skore.evaluate(...)
report.checks.summarize()
project.put(STEM, report)
report
只有当调度器粒度过粗时才升级到 evaluate 之外的报告
(references/reports.md):单次留出拟合使用
EstimatorReport,逐折产物使用 CrossValidationReport。留出
评估使用 EstimatorReport。此循环使用一次 skore.evaluate、
一次 report.checks.summarize() 和一次 project.put 为一个学习器评分。
对于任何包含依赖历史的特征的流水线,交叉验证是必要条件,但并非充分条件。skore.evaluate 使用一个 env-dict 将图实例化一次,然后拆分索引。冒烟测试会在预测时使用一个新的 env-dict。即使冒烟测试通过,在调用方将状态切换为 done 之前,仍必须通过该测试。不要通过此技能将 JOURNAL.md History 或设计说明中的 Status 编辑为 done。
人工实验文件包含 skore.evaluate(...) 和 project.put(...),但不会执行。相同的调用会复制到 scratch/results/<stem>/materialize.py,且只有这个文件会运行,因此 project.put 只会执行一次。审计文件、临时探测脚本或对实验文件运行 notebook convert 都不得调用这些方法。读取已存储的报告时,先调用 project.summarize(),再调用 project.get(id)。get(key) 会引发 KeyError,因为 get 使用的是 id。不要通过重新运行 evaluate 来掩盖这个问题。
skore 尚未绘制的图表,在安装了该技能时使用 plot-ml-figure。
put 之后
Project.put 返回 None。materialize.py 会将该键对应的最新 id 写入 scratch/results/<stem>/id.txt。根据该 id 生成一个 locator,并在 loop locator 和 loop artifacts 之前将其写入同目录下的 locator.txt。不要将这些写入操作放在 experiments/<stem>.py 中。运行
python -m skore_skills loop locator --stem <stem>,并原样粘贴 JSON locator。缺少 locator 时写为
n/a — backend did not expose a locator。
- local —
local workspace: [reports/](../reports/) · id: <id>, 并附上reports/的绝对路径。不要链接私有文件。 - hub — 使用准确的
Consult your report at …URL:[Open report](<url>) · hub · id: <id>。如果 Skore 未提供 URL,则将项目首页链接标为Open project。 - mlflow — 如有准确的
View run …URL,则使用该 URL。若没有且tracking_uri为 HTTP(S),则使用/#/experiments/<experiment-id>/runs/<run-id>。对于file:、sqlite:、databricks或其他未提供 URL 的 URI,使用:mlflow · tracking: <uri> · experiment: <id> · run: <run-id>。不要虚构浏览器链接。
脚本会将 report._repr_html_() 写入
scratch/results/<stem>/report.html,将 repr(report) 写入
scratch/results/<stem>/report.txt,并生成 checks.html 和 metrics.html。它会根据内存中的学习器重新生成 Method 查看器:
EstimatorReport 使用 report.estimator_,
CrossValidationReport 使用 report.reports_[0].estimator_。
SkrubLearner 会将其 DataOp 封装在 learner.data_op 中。脚本会从
learner.data_op.skb 获取 draw_graph().svg 并写入 pipeline.svg,再将 DataOp 报告写入
scratch/results/<stem>/pipeline/,调用参数为 report(eval=False, open=False, overwrite=True, output_dir=...)。不要设置 environment。
这不会执行拟合。不要调用 full_report,也不要在未设置 eval=False 时调用
report。如果对 skrub 重试一次 add-python-package 后 Graphviz 仍然失败,请用一行说明错误。
回合结束
当 model-ml-pipeline 调度了本回合时,向上游传递 JSON
locator,并在上方的实时执行和检查点预览之后返回。不要运行收尾时的 loop notebooks、
loop artifacts、审计、record-outcome、再次构建站点或
git end-turn。
否则,本技能负责收尾。首先运行
python -m skore_skills loop artifacts --stem <stem>。
stop / evaluate_incomplete → 指明缺少的文件,不要
进行审计。audit → 如果已安装,则加载
audit-ml-pipeline。
record → 跳过审计。record 是该命令的操作,不是笔记本门槛。不要在审计技能中进行转换。
然后按以下顺序执行。不要调整顺序。loop notebooks 仅在
skip 时继续。
python -m skore_skills loop notebooks --stem <stem>。将 JSONaction视为权威结果。当action为convert时,不要执行 record-outcome、site build或git end-turn。not_evaluated不会触发转换。- 遇到
convert时,对每个experiments/或audit/条目运行python -m skore_skills notebook fill <source>,当html为 true 时加上--html。不要对这些文件运行notebook convert。Fill 不会 执行put。只有当本次运行以来该人工调用发生变化时,才先重新运行materialize.py,因为当前制品由它写入。仅填充audit/<stem>.py不算完成收尾。未拟合快照禁令不适用:即使实验脚本包含skore.evaluate,也要填充该脚本。重复运行步骤 1,直到action为skip。缺少 jupytext / nbformat / nbconvert → 用一行说明add-python-package。 - 只有步骤 1 为
skip后才运行 record-outcome,并且要在构建站点之前执行。如果运行了审计,且已安装manage-ml-backlog,则将其摘要和 G-AUDIT-FINDING 传入该技能;若实验脚本已转换,则一并传入步骤 2 中的 locator。 如果未运行审计,则调用 record-outcome,并传入该 locator、用户提供的标题(如有)以及n/a — audit not run。 缺少 backlog 技能 → 用一行说明。不要在此处写入 History。 smoke 未通过时,绝不要标记为done。 - 仅当
policy.site为 true 且已安装export-ml-site时,运行site build:python -m skore_skills site build --if-stale。它会在## Notebooks下嵌入audit/<stem>.nb.html;不要添加 ``。如果site build因mkdocs-material is required报错,则加载add-python-package以安装mkdocs-material(agent),然后再构建一次。不要运行pixi add/uv add。指出构建错误;不要判定本回合失败。 - 检查点,见下文。当
policy.site为 true 且检查点构建成功时,说明网站已更新,并逐字粘贴该输出中的file://行。不要提及设计说明 markdown 文件。网站未构建时,不要声称网站已更新,也不要提及 markdown 文件。 python -m skore_skills git end-turn --stage evaluate。如果 JSONaction为invoke,则在已安装时加载persist-ml-git,然后停止。否则,在已安装时加载triage-ml-task。此处不要运行git commit。
检查点
仅独立输出。用 2–6 句话总结结果,依据标题;若跳过审计,则依据
report.txt。如果运行了审计,叙述内容应依据其中的 Checks 和 Metrics。不要编造指标。
链接:当 policy.site 为 true 且构建成功时,说明网站已更新,并逐字粘贴该输出中的 file:// 行。
不要提及 html/<stem>.html 或 journal/<stem>.md。网站未构建时,不要声称网站已更新,也不要提及 markdown 文件。
叙述之后的标记:先输出 JSON locator,再输出 G-AUDIT-FINDING(若跳过,则为 n/a — audit not run)。
返回构建阶段
缺少 cv、缺少评分器、预测器类错误,以及缺少冒烟测试或测试未通过,都是应在
build-ml-pipeline 中修复的流水线问题。如何进入该流程取决于是谁加载了此技能:
- 由其他技能调度 —
model-ml-pipeline或build-ml-pipeline在本轮加载了此技能:停止并返回该循环,由它返回构建阶段进行修复。 - 直接进入 — 用户要求评估,或入口技能将流程路由到此处:当
status.skills.model-ml-pipeline为 true 时,加载model-ml-pipeline,并指出 stem。它会恢复已批准的设计,并在构建所声明的模型层级上重新进入构建阶段进行修复。请勿在此处加载build-ml-pipeline:此技能加载的子步骤最多只能运行在此技能自身的层级。若缺少model-ml-pipeline→ 用一行说明流水线需要在构建阶段修复,然后停止。
无论哪种情况,本轮都不要编写 skore.evaluate。
停止条件
- 存在待处理的设置(
status.setup.pending非空)→ 加载setup-ml-project。已拒绝的git不再询问。拒绝环境或工作区设置则停止。 - 依赖历史记录的流水线缺少冒烟测试或测试未通过 → 返回构建阶段(§ 返回构建阶段)。
split_kwargs为空且可能存在分组列 → 返回构建阶段(§ 返回构建阶段)。不要默认使用KFold。import skore失败 → 若未设置,则设置 G-SKORE-MODE,然后加载add-python-package。不要退回到cross_val_score。- 超参数搜索、服务部署和多次运行跟踪不在范围内。
- 缺少的包若已安装,则加载
add-python-package。 不要在此处运行env add。
预检 — 在任何代码之前输出
Pre-flight (evaluate-ml-pipeline):
- [ ] sklearn, skrub, skore import
- [ ] frame show is proceed; DataOp cv matches translation
(or holdout / prefit, and the marker has no cv)
- [ ] skore_mode is set (local | hub | mlflow)
- [ ] evaluate consent is proceed, or the user answered Evaluate
- [ ] Call site is experiments/NN_*.py (not executed)
- [ ] The one run is scratch/results/<stem>/materialize.py
(not cells in the experiment file)
- [ ] skore.evaluate omits splitter=
(or splitter="prefit" and only the test table is passed)
- [ ] report.checks.summarize() then project.put
(no fast_mode, no ignore; after any checks.add)
- [ ] Smoke: passing | n/a (no history-dependent step) | STOP
参考资料
references/metadata-routing.md— 锁定的cv保留在 DataOp 上;evaluate 不传入splitter=。references/skrub_interop.md— 环境字典与(X, y)。references/g_skore_mode.md— Project 构造函数。references/reports.md— 何时evaluate过于笼统。references/custom-metrics.md— 通过with_scoring使用非默认指标。references/custom-checks.md— 用户要求的检查。templates/materialize.py— 唯一的评估运行。复制到scratch/results/<stem>/materialize.py。