transport-runtime 0.6.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- transport_runtime-0.6.0/LICENSE +25 -0
- transport_runtime-0.6.0/PKG-INFO +109 -0
- transport_runtime-0.6.0/README.md +64 -0
- transport_runtime-0.6.0/pyproject.toml +47 -0
- transport_runtime-0.6.0/setup.cfg +4 -0
- transport_runtime-0.6.0/transport_runtime/README.md +82 -0
- transport_runtime-0.6.0/transport_runtime/__init__.py +85 -0
- transport_runtime-0.6.0/transport_runtime/audit.py +210 -0
- transport_runtime-0.6.0/transport_runtime/certificate_strategy.py +115 -0
- transport_runtime-0.6.0/transport_runtime/certify.py +236 -0
- transport_runtime-0.6.0/transport_runtime/channels.py +84 -0
- transport_runtime-0.6.0/transport_runtime/cli.py +87 -0
- transport_runtime-0.6.0/transport_runtime/clinical.py +123 -0
- transport_runtime-0.6.0/transport_runtime/compiler.py +257 -0
- transport_runtime-0.6.0/transport_runtime/core.py +256 -0
- transport_runtime-0.6.0/transport_runtime/diff.py +72 -0
- transport_runtime-0.6.0/transport_runtime/fetch_data.py +105 -0
- transport_runtime-0.6.0/transport_runtime/identify.py +346 -0
- transport_runtime-0.6.0/transport_runtime/ot_gap.py +129 -0
- transport_runtime-0.6.0/transport_runtime/pipeline.py +114 -0
- transport_runtime-0.6.0/transport_runtime/robust.py +223 -0
- transport_runtime-0.6.0/transport_runtime/selection.py +186 -0
- transport_runtime-0.6.0/transport_runtime/slope.py +403 -0
- transport_runtime-0.6.0/transport_runtime/theory.py +122 -0
- transport_runtime-0.6.0/transport_runtime/verify.py +76 -0
- transport_runtime-0.6.0/transport_runtime.egg-info/PKG-INFO +109 -0
- transport_runtime-0.6.0/transport_runtime.egg-info/SOURCES.txt +48 -0
- transport_runtime-0.6.0/transport_runtime.egg-info/dependency_links.txt +1 -0
- transport_runtime-0.6.0/transport_runtime.egg-info/entry_points.txt +3 -0
- transport_runtime-0.6.0/transport_runtime.egg-info/requires.txt +10 -0
- transport_runtime-0.6.0/transport_runtime.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Shengjie Zhang, Wenhao Tian (Shihezi University School of Medicine)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
NOTE: The MIT license covers code only. Data are CDC public-use files
|
|
24
|
+
(NHANES, BRFSS) under their own terms; derived statistical artifacts in
|
|
25
|
+
results/ are released alongside the paper under CC BY 4.0.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: transport-runtime
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Zero-label deployment runtime for fitted classifiers under transport drift
|
|
5
|
+
Author-email: Shengjie Zhang <2142024286@qq.com>, Wenhao Tian <2144767610@qq.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Keywords: transportability,calibration,conformal prediction,distribution shift,drift audit
|
|
8
|
+
Classifier: Development Status :: 4 - Beta
|
|
9
|
+
Classifier: Intended Audience :: Science/Research
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: numpy>=2.0
|
|
19
|
+
Requires-Dist: pandas>=1.5
|
|
20
|
+
Requires-Dist: scipy>=1.10
|
|
21
|
+
Provides-Extra: xgb
|
|
22
|
+
Requires-Dist: xgboost>=1.7; extra == "xgb"
|
|
23
|
+
Provides-Extra: test
|
|
24
|
+
Requires-Dist: pytest>=7; extra == "test"
|
|
25
|
+
Requires-Dist: xgboost>=1.7; extra == "test"
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# Transport Runtime
|
|
29
|
+
|
|
30
|
+
Zero-label deployment for any fitted probabilistic classifier.
|
|
31
|
+
|
|
32
|
+
Models are trained on one distribution and executed on another. Transport Runtime wraps any
|
|
33
|
+
fitted classifier with a transport layer: a hot-swappable level interface (exact per-channel
|
|
34
|
+
calibration from public prevalences only), a drift-law audit (three-line report + level
|
|
35
|
+
contamination index), and conformal certificates.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from transport_runtime import TransportLayer
|
|
39
|
+
|
|
40
|
+
layer = TransportLayer(model).fit_calibration(X_src, y_src, channels_src)
|
|
41
|
+
layer.audit(X_new, channels_new, y_new) # three-line drift report + HCI
|
|
42
|
+
deployed = layer.deploy(pi_public, X_unlab, ch) # zero-label deployment
|
|
43
|
+
deployed.predict_proba(X_new, channels_new) # per-channel exact level (Prop 1)
|
|
44
|
+
conf = layer.conformal(X_unlab, ch, pi_public, alpha=0.1, per_channel=True)
|
|
45
|
+
conf.predict_set(X_new, channels_new) # prediction sets with certificates
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Theorem index (each function is one theorem, with citation and validation record)
|
|
49
|
+
|
|
50
|
+
| Function | Theorem | Source | Validation |
|
|
51
|
+
|---|---|---|---|
|
|
52
|
+
| `moment_delta` / `deploy` | Prop 1: per-channel moment identity — deployed level error identically zero | this project (docs/pilevel_theory.md) | results/pilevel_v08_seeds10.csv, v09 (10 seeds, O/E=1.0000 ×10/10) |
|
|
53
|
+
| `audit` (intercept share, warning) | Drift law: level/slope share decomposition | this project (case series, docs/case_*/DRIFTLAW.md) | six case CSVs in results/ |
|
|
54
|
+
| `hci` | HCI: level-contamination index (slope of per-channel mean margin on logit prevalence) | this project (docs/levelfree_theory.md) | XGB 1.041 vs randomized-training 1.066 (LevelFree falsification record) |
|
|
55
|
+
| `conformal(weighted=True)` | Weighted conformal under covariate shift | Tibshirani et al. 2019 | results/transport_cert_v01.csv (marginal coverage ≥ nominal; per-channel gaps persist) |
|
|
56
|
+
| `conformal(per_channel=True)` | Per-channel thresholds (two-tier: level layer + residual slope share) | this project | results/transport_cert_v02.csv (T3 per-channel coverage 0.896–0.897 flat) |
|
|
57
|
+
| `ot_gap.cdf_l1_gap` | Total coverage gap = ∫p(t)\|F_P−F_Q\|dt (change of variables) + DKW | Correia & Louizos 2025 (arXiv:2507.10425) Thm 3.2/A.2 | synthetic 0.2545 vs 0.2544; T1 real 0.0485 vs empirical 0.0415 |
|
|
58
|
+
| `ot_gap.label_free_gap` | Label-free bound via auxiliary score distributions | Correia & Louizos 2025 Thm 3.3 | validity depends on dominance: `aux_minmax` always valid; `aux_uniform/aux_model` require model accuracy — checked via `check_dominance` |
|
|
59
|
+
| `fit_channel_affine` / `channel_affine_repair` | Prop 4(iii)/(iv): mean-one slope-repair boundary (audited families keep E[M]=1; no universal guarantee) | this project | results/prop4iii_boundary_audit_summary.csv, results/brfss_slope_repair_v01_summary.csv |
|
|
60
|
+
| `decision_curve` / `clinical_threshold_audit` | Net-benefit decision-curve transport evidence | this project | results/*_dca_v01_summary.csv (13 outcome lines) |
|
|
61
|
+
| `transportability_id` / `valid_backdoor_set` / `s_admissible` | Conservative transport-by-adjustment identification: backdoor validity + S-admissibility on explicit DAGs | Pearl–Bareinboim selection-diagram programme; implementation is **not** a complete mz-transportability algorithm | `transport_runtime/tests/test_identify.py` |
|
|
62
|
+
|
|
63
|
+
## Design principles
|
|
64
|
+
|
|
65
|
+
1. **Zero-label deployment**: target side needs only unlabeled features + public per-channel prevalences.
|
|
66
|
+
2. **Two-tier certificates mirror the drift law**: level (intercept) share → moment-matched level
|
|
67
|
+
layer; residual slope share → per-channel conformal thresholds.
|
|
68
|
+
3. **Negative results are documented**: audited training-time level-intervention families fail to remove level
|
|
69
|
+
content (impossibility duality, docs/theory_impossibility.md, Props 4–5, bounded to audited families) — within those audited families the runtime is the
|
|
70
|
+
complete solution set, which is why this is a runtime and not a training method.
|
|
71
|
+
4. **Honest bounds**: certificates widen/fail visibly under slope corruption (Prop 2′) rather
|
|
72
|
+
than failing silently.
|
|
73
|
+
|
|
74
|
+
## Scope and limits
|
|
75
|
+
|
|
76
|
+
- Within-channel ranking must transport (Prop 2′: residual ≤ ECE_w + L·τ). If discrimination
|
|
77
|
+
itself collapses, no level layer can repair it — audit will say so.
|
|
78
|
+
- Small channels: level offsets are shrunk toward a global delta (kappa=200); per-channel
|
|
79
|
+
conformal degrades in small/rare-event channels (empirical: T2 band 0).
|
|
80
|
+
- The package does not improve iid performance; its ceiling is parity (that is a theorem, not
|
|
81
|
+
a limitation of implementation).
|
|
82
|
+
|
|
83
|
+
## Roadmap
|
|
84
|
+
|
|
85
|
+
- [x] `identify` module: conservative transportability / S-admissibility checker for explicit DAGs (Pearl–Bareinboim adjustment formula; not a complete mz-transportability engine)
|
|
86
|
+
- [ ] OT weight-learning (Correia & Louizos 2025 Sec. 4)
|
|
87
|
+
- [x] transport-suite v1 step A: aggregator over audited `results/*.csv` → `results/transport_suite_v01_summary.csv` and `results/transport_suite_v01_cert_summary.csv`
|
|
88
|
+
- [x] transport-suite v1 step B: low-compute synthetic regression runner (`scripts/transport_suite_v01_runner.py` → `results/transport_suite_v01_runner.csv`)
|
|
89
|
+
- [x] robust layer v0.4: EB uncertainty-aware repair + interval bounds (`transport_runtime.robust`)
|
|
90
|
+
- [x] compiler layer v0.4: TransportCompiler / DeploymentContract with adaptive point-vs-EB repair gating and archive manifest input fingerprints
|
|
91
|
+
- [x] channelization layer v0.4: automatic score-channel discovery from unlabeled covariates and fitted model scores
|
|
92
|
+
- [x] channel selection layer v0.4: transport-aware candidate channel selection balancing level structure and shift risk, with bootstrap stability selection
|
|
93
|
+
- [x] slope-risk + repair layer v0.4: within-channel score-shift / KS diagnosis, limited-label channel-affine repair, validation-based repair-value estimation, and threshold sensitivity analysis
|
|
94
|
+
- [x] slope uncertainty certificate (post-v0.5 working tree): `bootstrap_channel_affine` returns per-channel slope/intercept percentile CIs and success rates; `channel_affine_margin_interval` converts those coefficient CIs into repaired-margin intervals. This quantifies finite-label fitting uncertainty; it is not a proof of target-domain calibration.
|
|
95
|
+
- [x] system demo: end-to-end compiler contract generation with archive manifest, slope repair value estimation, slope repair, certificate replay, and verification (`scripts/ncs_system_v01.py`)
|
|
96
|
+
- [x] verification layer v0.4: contract self-checks for prevalence validity, certificate alpha, slope-risk finiteness, and input fingerprint matching
|
|
97
|
+
- [x] certificate recommendation + replay layer v0.4: risk-aware policy selection and labeled-target coverage evaluation; post-v0.5 `summarize_slope_uncertainty` incorporates finite-label slope-repair CI widths into certificate policy recommendation, `recommend_certificate_from_audit_pack` consumes audit packs directly, and `summarize_channel_clinical_risk` lets recommendations respond to channel-level clinical losses
|
|
98
|
+
- [x] audit pack layer v0.4: standardized JSON artifact combining manifest, slope risk, verification, and certificate evaluation; post-v0.5 `slope_boot=True` adds finite-label slope-repair coefficient CIs and repaired-margin interval summaries, `clinical=True` adds global threshold-specific net-benefit summaries, and `channel_clinical=True` adds per-channel clinical utility summaries
|
|
99
|
+
- [x] clinical decision-curve layer (post-v0.5 working tree): `decision_curve`, `compare_decision_curves`, `clinical_threshold_audit`, and `channel_clinical_audit` evaluate threshold-specific net benefit for unrepaired vs repaired deployment outputs
|
|
100
|
+
- [x] release artifact builder with SHA256 checksums (`scripts/release_v01.py`; current built version `0.5.0`)
|
|
101
|
+
- [x] contract diff layer v0.4: explicit version-to-version comparison for deployment contracts
|
|
102
|
+
- [x] full-system benchmark v0.4: 10-seed clean/level/slope/level+slope scenarios with contract, flagged-only slope repair, and risk-proportional label allocation (`scripts/ncs_fullsystem_v01.py`)
|
|
103
|
+
- [x] figure generation: NCS-oriented benchmark figures and interface schematic (`scripts/ncs_figures_v01.py`, `scripts/ncs_schematic_v01.py` → `results/figs/`)
|
|
104
|
+
- [ ] PyPI release
|
|
105
|
+
|
|
106
|
+
## Citation
|
|
107
|
+
|
|
108
|
+
Transport Runtime. Shengjie Zhang, Shihezi University School of Medicine. ORCID 0009-0000-3975-6954.
|
|
109
|
+
Archived at ScienceDB (DOI pending). License: MIT.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# transport-runtime — zero-label model transport with provable level-repair guarantees
|
|
2
|
+
|
|
3
|
+
面向 NCS(Nature Computational Science)投稿的计算研究项目:当预测模型部署到新人群、
|
|
4
|
+
新地区或新年代时,零标签校准(zero-label level repair)在什么条件下是**数学保证成立**
|
|
5
|
+
的,什么时候会失败;以及配套的运行时审计协议与开源软件。
|
|
6
|
+
|
|
7
|
+
## 核心主张(248 臂真实数据证据链支撑,13 结局线,三科学域)
|
|
8
|
+
|
|
9
|
+
0. **校准-判别分离**:level 修复改善校准(52/64 臂 ECE 降)而判别力冻结(max dAUC 0.009)——fig21/22 系统证据
|
|
10
|
+
1. **Level-drift law**:跨人群/跨周期/跨学科部署时 naive 预测系统漂移(OE 0.39–14.96,政治科学臂创全链纪录),
|
|
11
|
+
漂移幅度随间隔单调增长(I→P 2.26 → G→I 2.06 → G→P 2.40),
|
|
12
|
+
跨人群漂移远大于同人群时间漂移(1.21 vs ≤1.08)。
|
|
13
|
+
2. **Level 修复定理**:在满足 (C)(强 log-concave)+ E[M]=1 + 对称单峰的条件下,
|
|
14
|
+
level repair 使 R(π) ≤ 1 对一切 π 成立(Prop 4(iv) 强形式,第 30 轮解析证明;
|
|
15
|
+
ψ-Jensen 引理 + Rojo & He 1991 保持定理)。
|
|
16
|
+
3. **Slope 修复边界**:真实数据上 slope 修复无校准收益(ECE 反升)、无临床净获益
|
|
17
|
+
(DCA 阴性)——conservative 设计(audit + certificate + 最小样本门控)获实证支持。
|
|
18
|
+
|
|
19
|
+
## 仓库结构
|
|
20
|
+
|
|
21
|
+
- `transport_runtime/` 可安装 Python 包(审计核心、临床模块、斜率修复、理论证书)
|
|
22
|
+
- `transport_runtime/tests/` 模块测试(沙箱 standalone:84 通过 / 3 可选跳过;含可选共 87 项)
|
|
23
|
+
- `scripts/` 全部确定性脚本(121 个;52 个入 reproduce_all 管线)
|
|
24
|
+
- `results/` 全部产物 CSV/JSON/TEX/PNG(程序读数,无手抄值)
|
|
25
|
+
- `results/figs/fig14_evidence_forest.png` 248 臂证据森林图
|
|
26
|
+
- `results/tables/tab_evidence_summary.tex` 248 行三线表(booktabs 纪律自检;0% 公共患病率误差臂)
|
|
27
|
+
- `preprint/transport_runtime_compendium_v01.md` 合集式大预印本(v0.7.33)
|
|
28
|
+
- `docs/` 理论文档(theory_impossibility.md 第 28–30 轮:保持定理核验与 ψ-Jensen 证明)
|
|
29
|
+
- `manuscript/theorem_index.md` 定理索引
|
|
30
|
+
- `results/ARM_SOURCE_INDEX.csv` 248 臂→源 CSV 可追溯索引
|
|
31
|
+
- `transport_runtime/fetch_data.py` + `transport-runtime-fetch` CLI(PyPI 一键获取全部文件,URL 发布时填入)
|
|
32
|
+
- `docs/AUDIT_CLOSURE_SUMMARY.md` 补漏洞总验收单(41 轮,42+ 攻击面)
|
|
33
|
+
- `docs/PUBLICATION_STRATEGY_DECISIONS.md` 发表策略决策 D1-D5
|
|
34
|
+
- `docs/REFERENCE_MASTER_LIST.md` 统一参考文献主表 + PubMed 核验
|
|
35
|
+
- `docs/RELEASE_ARCHIVAL_CHECKLIST.md` M7 发布清单(ScienceDB-only,Zenodo 禁用)
|
|
36
|
+
- `manuscript/` DRAFT_BUDGET / cover_letter_skeleton / SI_SKELETON / updated_abstract_150w_draft(写作脚手架,prose 待授权)
|
|
37
|
+
- `HANDOFF.md` 跨会话交接卡(新会话必读)
|
|
38
|
+
- `logs/` 轮次日志
|
|
39
|
+
|
|
40
|
+
## 一键复现
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
PYTHONPATH=. python scripts/reproduce_all_v01.py # 创建校验清单(全链约 10 分钟,两段式)
|
|
44
|
+
PYTHONPATH=. python scripts/reproduce_all_v01.py --verify # 验证字节级一致
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
全部 248 臂证据、机制探针、理论证书、森林图数据、三线表从原始公共数据
|
|
48
|
+
(NHANES 2011-2020 三个周期 + BRFSS 2016-2024)以固定种子精确再生。
|
|
49
|
+
|
|
50
|
+
## 数据可得性
|
|
51
|
+
|
|
52
|
+
- NHANES:https://wwwn.cdc.gov/Nchs/Data/Nhanes/Public/ (示范格式
|
|
53
|
+
`https://wwwn.cdc.gov/Nchs/Data/Nhanes/Public/2021/DataFiles/DEMO_L.xpt`;
|
|
54
|
+
本项目使用 2011-2012(G)、2015-2016(I)、2017-2020(P) 周期公开文件,本地镜像于 data/)
|
|
55
|
+
- BRFSS:https://www.cdc.gov/brfss/annual_data/annual_YYYY.html (2016-2024 年度文件,本地镜像于 data/brfss/)
|
|
56
|
+
|
|
57
|
+
## 作者
|
|
58
|
+
|
|
59
|
+
- 共同第一:Shengjie Zhang(石河子大学医学院,ORCID 0009-0000-3975-6954)
|
|
60
|
+
- 共同第一兼通讯:Wenhao Tian(石河子大学医学院,ORCID 0009-0002-0660-3024)
|
|
61
|
+
|
|
62
|
+
## 许可
|
|
63
|
+
|
|
64
|
+
代码 MIT;数据为 CDC 公开数据,遵循各原始使用条款。
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "transport-runtime"
|
|
7
|
+
version = "0.6.0"
|
|
8
|
+
description = "Zero-label deployment runtime for fitted classifiers under transport drift"
|
|
9
|
+
readme = "transport_runtime/README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
license-files = ["LICENSE"]
|
|
13
|
+
authors = [
|
|
14
|
+
{name = "Shengjie Zhang", email = "2142024286@qq.com"},
|
|
15
|
+
{name = "Wenhao Tian", email = "2144767610@qq.com"}
|
|
16
|
+
]
|
|
17
|
+
keywords = ["transportability", "calibration", "conformal prediction", "distribution shift", "drift audit"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 4 - Beta",
|
|
20
|
+
"Intended Audience :: Science/Research",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.10",
|
|
23
|
+
"Programming Language :: Python :: 3.11",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
"Topic :: Scientific/Engineering"
|
|
26
|
+
]
|
|
27
|
+
dependencies = [
|
|
28
|
+
"numpy>=2.0",
|
|
29
|
+
"pandas>=1.5",
|
|
30
|
+
"scipy>=1.10"
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
xgb = ["xgboost>=1.7"]
|
|
35
|
+
test = ["pytest>=7", "xgboost>=1.7"]
|
|
36
|
+
|
|
37
|
+
[project.scripts]
|
|
38
|
+
transport-runtime = "transport_runtime.cli:main"
|
|
39
|
+
transport-runtime-fetch = "transport_runtime.fetch_data:main"
|
|
40
|
+
|
|
41
|
+
[tool.setuptools]
|
|
42
|
+
packages = ["transport_runtime"]
|
|
43
|
+
package-dir = {"" = "."}
|
|
44
|
+
include-package-data = false
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
testpaths = ["transport_runtime/tests"]
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# Transport Runtime
|
|
2
|
+
|
|
3
|
+
Zero-label deployment for any fitted probabilistic classifier.
|
|
4
|
+
|
|
5
|
+
Models are trained on one distribution and executed on another. Transport Runtime wraps any
|
|
6
|
+
fitted classifier with a transport layer: a hot-swappable level interface (exact per-channel
|
|
7
|
+
calibration from public prevalences only), a drift-law audit (three-line report + level
|
|
8
|
+
contamination index), and conformal certificates.
|
|
9
|
+
|
|
10
|
+
```python
|
|
11
|
+
from transport_runtime import TransportLayer
|
|
12
|
+
|
|
13
|
+
layer = TransportLayer(model).fit_calibration(X_src, y_src, channels_src)
|
|
14
|
+
layer.audit(X_new, channels_new, y_new) # three-line drift report + HCI
|
|
15
|
+
deployed = layer.deploy(pi_public, X_unlab, ch) # zero-label deployment
|
|
16
|
+
deployed.predict_proba(X_new, channels_new) # per-channel exact level (Prop 1)
|
|
17
|
+
conf = layer.conformal(X_unlab, ch, pi_public, alpha=0.1, per_channel=True)
|
|
18
|
+
conf.predict_set(X_new, channels_new) # prediction sets with certificates
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Theorem index (each function is one theorem, with citation and validation record)
|
|
22
|
+
|
|
23
|
+
| Function | Theorem | Source | Validation |
|
|
24
|
+
|---|---|---|---|
|
|
25
|
+
| `moment_delta` / `deploy` | Prop 1: per-channel moment identity — deployed level error identically zero | this project (docs/pilevel_theory.md) | results/pilevel_v08_seeds10.csv, v09 (10 seeds, O/E=1.0000 ×10/10) |
|
|
26
|
+
| `audit` (intercept share, warning) | Drift law: level/slope share decomposition | this project (case series, docs/case_*/DRIFTLAW.md) | six case CSVs in results/ |
|
|
27
|
+
| `hci` | HCI: level-contamination index (slope of per-channel mean margin on logit prevalence) | this project (docs/levelfree_theory.md) | XGB 1.041 vs randomized-training 1.066 (LevelFree falsification record) |
|
|
28
|
+
| `conformal(weighted=True)` | Weighted conformal under covariate shift | Tibshirani et al. 2019 | results/transport_cert_v01.csv (marginal coverage ≥ nominal; per-channel gaps persist) |
|
|
29
|
+
| `conformal(per_channel=True)` | Per-channel thresholds (two-tier: level layer + residual slope share) | this project | results/transport_cert_v02.csv (T3 per-channel coverage 0.896–0.897 flat) |
|
|
30
|
+
| `ot_gap.cdf_l1_gap` | Total coverage gap = ∫p(t)\|F_P−F_Q\|dt (change of variables) + DKW | Correia & Louizos 2025 (arXiv:2507.10425) Thm 3.2/A.2 | synthetic 0.2545 vs 0.2544; T1 real 0.0485 vs empirical 0.0415 |
|
|
31
|
+
| `ot_gap.label_free_gap` | Label-free bound via auxiliary score distributions | Correia & Louizos 2025 Thm 3.3 | validity depends on dominance: `aux_minmax` always valid; `aux_uniform/aux_model` require model accuracy — checked via `check_dominance` |
|
|
32
|
+
| `fit_channel_affine` / `channel_affine_repair` | Prop 4(iii)/(iv): mean-one slope-repair boundary (audited families keep E[M]=1; no universal guarantee) | this project | results/prop4iii_boundary_audit_summary.csv, results/brfss_slope_repair_v01_summary.csv |
|
|
33
|
+
| `decision_curve` / `clinical_threshold_audit` | Net-benefit decision-curve transport evidence | this project | results/*_dca_v01_summary.csv (13 outcome lines) |
|
|
34
|
+
| `transportability_id` / `valid_backdoor_set` / `s_admissible` | Conservative transport-by-adjustment identification: backdoor validity + S-admissibility on explicit DAGs | Pearl–Bareinboim selection-diagram programme; implementation is **not** a complete mz-transportability algorithm | `transport_runtime/tests/test_identify.py` |
|
|
35
|
+
|
|
36
|
+
## Design principles
|
|
37
|
+
|
|
38
|
+
1. **Zero-label deployment**: target side needs only unlabeled features + public per-channel prevalences.
|
|
39
|
+
2. **Two-tier certificates mirror the drift law**: level (intercept) share → moment-matched level
|
|
40
|
+
layer; residual slope share → per-channel conformal thresholds.
|
|
41
|
+
3. **Negative results are documented**: audited training-time level-intervention families fail to remove level
|
|
42
|
+
content (impossibility duality, docs/theory_impossibility.md, Props 4–5, bounded to audited families) — within those audited families the runtime is the
|
|
43
|
+
complete solution set, which is why this is a runtime and not a training method.
|
|
44
|
+
4. **Honest bounds**: certificates widen/fail visibly under slope corruption (Prop 2′) rather
|
|
45
|
+
than failing silently.
|
|
46
|
+
|
|
47
|
+
## Scope and limits
|
|
48
|
+
|
|
49
|
+
- Within-channel ranking must transport (Prop 2′: residual ≤ ECE_w + L·τ). If discrimination
|
|
50
|
+
itself collapses, no level layer can repair it — audit will say so.
|
|
51
|
+
- Small channels: level offsets are shrunk toward a global delta (kappa=200); per-channel
|
|
52
|
+
conformal degrades in small/rare-event channels (empirical: T2 band 0).
|
|
53
|
+
- The package does not improve iid performance; its ceiling is parity (that is a theorem, not
|
|
54
|
+
a limitation of implementation).
|
|
55
|
+
|
|
56
|
+
## Roadmap
|
|
57
|
+
|
|
58
|
+
- [x] `identify` module: conservative transportability / S-admissibility checker for explicit DAGs (Pearl–Bareinboim adjustment formula; not a complete mz-transportability engine)
|
|
59
|
+
- [ ] OT weight-learning (Correia & Louizos 2025 Sec. 4)
|
|
60
|
+
- [x] transport-suite v1 step A: aggregator over audited `results/*.csv` → `results/transport_suite_v01_summary.csv` and `results/transport_suite_v01_cert_summary.csv`
|
|
61
|
+
- [x] transport-suite v1 step B: low-compute synthetic regression runner (`scripts/transport_suite_v01_runner.py` → `results/transport_suite_v01_runner.csv`)
|
|
62
|
+
- [x] robust layer v0.4: EB uncertainty-aware repair + interval bounds (`transport_runtime.robust`)
|
|
63
|
+
- [x] compiler layer v0.4: TransportCompiler / DeploymentContract with adaptive point-vs-EB repair gating and archive manifest input fingerprints
|
|
64
|
+
- [x] channelization layer v0.4: automatic score-channel discovery from unlabeled covariates and fitted model scores
|
|
65
|
+
- [x] channel selection layer v0.4: transport-aware candidate channel selection balancing level structure and shift risk, with bootstrap stability selection
|
|
66
|
+
- [x] slope-risk + repair layer v0.4: within-channel score-shift / KS diagnosis, limited-label channel-affine repair, validation-based repair-value estimation, and threshold sensitivity analysis
|
|
67
|
+
- [x] slope uncertainty certificate (post-v0.5 working tree): `bootstrap_channel_affine` returns per-channel slope/intercept percentile CIs and success rates; `channel_affine_margin_interval` converts those coefficient CIs into repaired-margin intervals. This quantifies finite-label fitting uncertainty; it is not a proof of target-domain calibration.
|
|
68
|
+
- [x] system demo: end-to-end compiler contract generation with archive manifest, slope repair value estimation, slope repair, certificate replay, and verification (`scripts/ncs_system_v01.py`)
|
|
69
|
+
- [x] verification layer v0.4: contract self-checks for prevalence validity, certificate alpha, slope-risk finiteness, and input fingerprint matching
|
|
70
|
+
- [x] certificate recommendation + replay layer v0.4: risk-aware policy selection and labeled-target coverage evaluation; post-v0.5 `summarize_slope_uncertainty` incorporates finite-label slope-repair CI widths into certificate policy recommendation, `recommend_certificate_from_audit_pack` consumes audit packs directly, and `summarize_channel_clinical_risk` lets recommendations respond to channel-level clinical losses
|
|
71
|
+
- [x] audit pack layer v0.4: standardized JSON artifact combining manifest, slope risk, verification, and certificate evaluation; post-v0.5 `slope_boot=True` adds finite-label slope-repair coefficient CIs and repaired-margin interval summaries, `clinical=True` adds global threshold-specific net-benefit summaries, and `channel_clinical=True` adds per-channel clinical utility summaries
|
|
72
|
+
- [x] clinical decision-curve layer (post-v0.5 working tree): `decision_curve`, `compare_decision_curves`, `clinical_threshold_audit`, and `channel_clinical_audit` evaluate threshold-specific net benefit for unrepaired vs repaired deployment outputs
|
|
73
|
+
- [x] release artifact builder with SHA256 checksums (`scripts/release_v01.py`; current built version `0.5.0`)
|
|
74
|
+
- [x] contract diff layer v0.4: explicit version-to-version comparison for deployment contracts
|
|
75
|
+
- [x] full-system benchmark v0.4: 10-seed clean/level/slope/level+slope scenarios with contract, flagged-only slope repair, and risk-proportional label allocation (`scripts/ncs_fullsystem_v01.py`)
|
|
76
|
+
- [x] figure generation: NCS-oriented benchmark figures and interface schematic (`scripts/ncs_figures_v01.py`, `scripts/ncs_schematic_v01.py` → `results/figs/`)
|
|
77
|
+
- [ ] PyPI release
|
|
78
|
+
|
|
79
|
+
## Citation
|
|
80
|
+
|
|
81
|
+
Transport Runtime. Shengjie Zhang, Shihezi University School of Medicine. ORCID 0009-0000-3975-6954.
|
|
82
|
+
Archived at ScienceDB (DOI pending). License: MIT.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Transport Runtime: zero-label deployment for any fitted classifier."""
|
|
2
|
+
from .core import TransportLayer, DeployedModel, DeployedConformal, moment_delta
|
|
3
|
+
from .ot_gap import (cdf_l1_gap, label_free_gap, aux_minmax, aux_uniform,
|
|
4
|
+
aux_model, total_coverage_gap)
|
|
5
|
+
from .channels import discover_score_channels, quantile_channel
|
|
6
|
+
from .clinical import channel_clinical_audit, clinical_threshold_audit, compare_decision_curves, decision_curve
|
|
7
|
+
from .selection import select_transport_channel, select_transport_channel_stability
|
|
8
|
+
from .slope import (
|
|
9
|
+
allocate_labels_for_slope,
|
|
10
|
+
apply_channel_affine,
|
|
11
|
+
channel_affine_repair,
|
|
12
|
+
channel_affine_margin_interval,
|
|
13
|
+
bootstrap_channel_affine,
|
|
14
|
+
ece_from_p,
|
|
15
|
+
evaluate_affine_repair,
|
|
16
|
+
fit_channel_affine,
|
|
17
|
+
margins_from_model,
|
|
18
|
+
slope_threshold_sensitivity,
|
|
19
|
+
summarize_slope_risk,
|
|
20
|
+
within_channel_score_shift,
|
|
21
|
+
)
|
|
22
|
+
from .certify import CertificateRecommendation, evaluate_certificate, recommend_certificate, recommend_certificate_from_audit_pack, summarize_channel_clinical_risk, summarize_slope_uncertainty
|
|
23
|
+
from .audit import audit_pack, save_audit_pack
|
|
24
|
+
from .diff import contract_diff
|
|
25
|
+
from .verify import CheckResult, VerificationReport, verify_contract
|
|
26
|
+
from .compiler import (
|
|
27
|
+
CertificateSpec,
|
|
28
|
+
ChannelSpec,
|
|
29
|
+
DeploymentContract,
|
|
30
|
+
PrevalenceSpec,
|
|
31
|
+
TransportCompiler,
|
|
32
|
+
)
|
|
33
|
+
from .robust import (
|
|
34
|
+
PrevalenceIntervalSet,
|
|
35
|
+
choose_repair,
|
|
36
|
+
deploy_eb,
|
|
37
|
+
deploy_interval,
|
|
38
|
+
empirical_bayes_target,
|
|
39
|
+
estimate_repair_gain,
|
|
40
|
+
interval_regret_bound,
|
|
41
|
+
interval_uniform_variance,
|
|
42
|
+
minimax_target,
|
|
43
|
+
worst_case_channel_bias,
|
|
44
|
+
)
|
|
45
|
+
from .identify import (
|
|
46
|
+
IdentificationResult,
|
|
47
|
+
STATUS_INCONCLUSIVE,
|
|
48
|
+
STATUS_NOT_TRANSPORTABLE_BY_ADJUSTMENT,
|
|
49
|
+
STATUS_TRANSPORTABLE,
|
|
50
|
+
ancestors,
|
|
51
|
+
d_connected,
|
|
52
|
+
descendants,
|
|
53
|
+
intervened_graph,
|
|
54
|
+
is_dag,
|
|
55
|
+
s_admissible,
|
|
56
|
+
transportability_id,
|
|
57
|
+
valid_backdoor_set,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
__all__ = [
|
|
61
|
+
'TransportLayer', 'DeployedModel', 'DeployedConformal', 'moment_delta',
|
|
62
|
+
'ChannelSpec', 'PrevalenceSpec', 'CertificateSpec', 'TransportCompiler', 'DeploymentContract',
|
|
63
|
+
'quantile_channel', 'discover_score_channels', 'select_transport_channel', 'select_transport_channel_stability',
|
|
64
|
+
'decision_curve', 'compare_decision_curves', 'clinical_threshold_audit', 'channel_clinical_audit',
|
|
65
|
+
'margins_from_model', 'within_channel_score_shift', 'summarize_slope_risk', 'slope_threshold_sensitivity',
|
|
66
|
+
'fit_channel_affine', 'apply_channel_affine', 'channel_affine_repair',
|
|
67
|
+
'bootstrap_channel_affine', 'channel_affine_margin_interval',
|
|
68
|
+
'allocate_labels_for_slope',
|
|
69
|
+
'ece_from_p', 'evaluate_affine_repair',
|
|
70
|
+
'verify_contract', 'VerificationReport', 'CheckResult',
|
|
71
|
+
'recommend_certificate', 'recommend_certificate_from_audit_pack', 'CertificateRecommendation', 'evaluate_certificate', 'summarize_slope_uncertainty', 'summarize_channel_clinical_risk',
|
|
72
|
+
'audit_pack', 'save_audit_pack', 'contract_diff',
|
|
73
|
+
'cdf_l1_gap', 'label_free_gap', 'aux_minmax', 'aux_uniform',
|
|
74
|
+
'aux_model', 'total_coverage_gap',
|
|
75
|
+
'PrevalenceIntervalSet', 'deploy_interval', 'interval_regret_bound',
|
|
76
|
+
'deploy_eb', 'empirical_bayes_target', 'estimate_repair_gain', 'choose_repair', 'interval_uniform_variance',
|
|
77
|
+
'minimax_target', 'worst_case_channel_bias',
|
|
78
|
+
'IdentificationResult', 'transportability_id', 'valid_backdoor_set',
|
|
79
|
+
's_admissible', 'd_connected', 'intervened_graph', 'is_dag',
|
|
80
|
+
'ancestors', 'descendants', 'STATUS_TRANSPORTABLE', 'STATUS_INCONCLUSIVE',
|
|
81
|
+
'STATUS_NOT_TRANSPORTABLE_BY_ADJUSTMENT',
|
|
82
|
+
]
|
|
83
|
+
__version__ = '0.6.0'
|
|
84
|
+
|
|
85
|
+
from transport_runtime.pipeline import TransportPipeline # noqa: E402,F401
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
"""Standardized audit pack for deployment contracts.
|
|
2
|
+
|
|
3
|
+
An audit pack is the single JSON artifact that combines:
|
|
4
|
+
- contract manifest;
|
|
5
|
+
- slope-risk summary;
|
|
6
|
+
- contract verification;
|
|
7
|
+
- labeled-target certificate replay, when labels are available.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import json
|
|
12
|
+
|
|
13
|
+
import numpy as np
|
|
14
|
+
from scipy.special import expit
|
|
15
|
+
|
|
16
|
+
from .certify import evaluate_certificate
|
|
17
|
+
from .clinical import clinical_threshold_audit, decision_curve
|
|
18
|
+
from .compiler import DeploymentContract
|
|
19
|
+
from .slope import bootstrap_channel_affine, channel_affine_margin_interval, margins_from_model
|
|
20
|
+
from .verify import verify_contract
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _tolist(value):
|
|
24
|
+
return np.asarray(value, dtype=float).tolist()
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _slope_repair_certificate(contract, X, channels, y, boot_kwargs):
|
|
28
|
+
levels = getattr(contract.deployed, "levels_", None)
|
|
29
|
+
if levels is None:
|
|
30
|
+
return None
|
|
31
|
+
f_repaired = margins_from_model(contract.layer.model, X) + np.asarray(levels, dtype=float)[np.asarray(channels, dtype=int)]
|
|
32
|
+
boot = bootstrap_channel_affine(f_repaired, y, channels, **boot_kwargs)
|
|
33
|
+
interval = channel_affine_margin_interval(f_repaired, channels, boot)
|
|
34
|
+
width = interval["upper"] - interval["lower"]
|
|
35
|
+
return {
|
|
36
|
+
"note": "finite-label uncertainty for affine slope repair fitted after level repair; "
|
|
37
|
+
"this is fitting uncertainty, not proof of target calibration",
|
|
38
|
+
"alpha": float(boot["alpha"]),
|
|
39
|
+
"ci_level": float(boot["ci_level"]),
|
|
40
|
+
"n_boot": int(boot["n_boot"]),
|
|
41
|
+
"channel_n": _tolist(boot["channel_n"]),
|
|
42
|
+
"a": _tolist(boot["a"]),
|
|
43
|
+
"b": _tolist(boot["b"]),
|
|
44
|
+
"a_mean": _tolist(boot["a_mean"]),
|
|
45
|
+
"b_mean": _tolist(boot["b_mean"]),
|
|
46
|
+
"a_std": _tolist(boot["a_std"]),
|
|
47
|
+
"b_std": _tolist(boot["b_std"]),
|
|
48
|
+
"a_ci_lower": _tolist(boot["a_ci_lower"]),
|
|
49
|
+
"a_ci_upper": _tolist(boot["a_ci_upper"]),
|
|
50
|
+
"b_ci_lower": _tolist(boot["b_ci_lower"]),
|
|
51
|
+
"b_ci_upper": _tolist(boot["b_ci_upper"]),
|
|
52
|
+
"bootstrap_success_rate": _tolist(boot["bootstrap_success_rate"]),
|
|
53
|
+
"margin_interval_summary": {
|
|
54
|
+
"n": int(len(width)),
|
|
55
|
+
"mean_width": float(np.mean(width)),
|
|
56
|
+
"median_width": float(np.median(width)),
|
|
57
|
+
"q95_width": float(np.quantile(width, 0.95)),
|
|
58
|
+
"max_width": float(np.max(width)),
|
|
59
|
+
},
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def _clinical_threshold_audit(contract, X, channels, y, thresholds):
|
|
64
|
+
base_p = expit(margins_from_model(contract.layer.model, X))
|
|
65
|
+
repaired_p = contract.predict_proba(X, channels)
|
|
66
|
+
audit = clinical_threshold_audit(y, base_p, repaired_p, thresholds=thresholds)
|
|
67
|
+
return {
|
|
68
|
+
"note": "threshold-specific net-benefit audit comparing repaired contract output with unrepaired model output; "
|
|
69
|
+
"synthetic or labeled-target audit evidence does not by itself prove clinical effectiveness",
|
|
70
|
+
"thresholds": audit["thresholds"],
|
|
71
|
+
"base_net_benefit": audit["base_net_benefit"],
|
|
72
|
+
"repaired_net_benefit": audit["repaired_net_benefit"],
|
|
73
|
+
"repaired_minus_base": audit["repaired_minus_base"],
|
|
74
|
+
"summary": audit["summary"],
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def _channel_clinical_summary(contract, X, channels, y, thresholds):
|
|
79
|
+
thresholds = np.asarray(
|
|
80
|
+
thresholds if thresholds is not None else np.linspace(0.01, 0.99, 99),
|
|
81
|
+
dtype=float,
|
|
82
|
+
)
|
|
83
|
+
base_p = expit(margins_from_model(contract.layer.model, X))
|
|
84
|
+
repaired_p = contract.predict_proba(X, channels)
|
|
85
|
+
y = np.asarray(y, dtype=float)
|
|
86
|
+
channels = np.asarray(channels, dtype=int)
|
|
87
|
+
summaries = []
|
|
88
|
+
for g in np.unique(channels):
|
|
89
|
+
sel = channels == g
|
|
90
|
+
base = decision_curve(y[sel], base_p[sel], thresholds=thresholds)
|
|
91
|
+
repaired = decision_curve(y[sel], repaired_p[sel], thresholds=thresholds)
|
|
92
|
+
gain = np.asarray(repaired["net_benefit"], dtype=float) - np.asarray(base["net_benefit"], dtype=float)
|
|
93
|
+
j = int(np.argmax(gain))
|
|
94
|
+
summaries.append(
|
|
95
|
+
{
|
|
96
|
+
"channel": int(g),
|
|
97
|
+
"channel_n": int(sel.sum()),
|
|
98
|
+
"channel_prevalence": float(np.mean(y[sel])),
|
|
99
|
+
"integrated_gain": float(np.trapz(gain, thresholds)),
|
|
100
|
+
"max_gain": float(gain[j]),
|
|
101
|
+
"threshold_at_max_gain": float(thresholds[j]),
|
|
102
|
+
"worst_gain": float(np.min(gain)),
|
|
103
|
+
"fraction_improved": float(np.mean(gain > 0.0)),
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
integrated = np.array([row["integrated_gain"] for row in summaries], dtype=float)
|
|
107
|
+
fragile = summaries[int(np.argmin(integrated))]
|
|
108
|
+
return {
|
|
109
|
+
"note": "channel-level threshold-specific net-benefit summary; negative channel gains can be masked by aggregate averages",
|
|
110
|
+
"thresholds": thresholds.tolist(),
|
|
111
|
+
"channel_summaries": summaries,
|
|
112
|
+
"overall": {
|
|
113
|
+
"n_channels": int(len(summaries)),
|
|
114
|
+
"mean_integrated_gain": float(np.mean(integrated)),
|
|
115
|
+
"min_integrated_gain": float(np.min(integrated)),
|
|
116
|
+
"n_channels_negative_integrated_gain": int(np.sum(integrated < 0.0)),
|
|
117
|
+
"most_fragile_channel": fragile["channel"],
|
|
118
|
+
"most_fragile_integrated_gain": fragile["integrated_gain"],
|
|
119
|
+
"most_fragile_worst_gain": fragile["worst_gain"],
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def audit_pack(
|
|
125
|
+
contract: DeploymentContract,
|
|
126
|
+
X=None,
|
|
127
|
+
channels=None,
|
|
128
|
+
y=None,
|
|
129
|
+
slope_boot=False,
|
|
130
|
+
slope_boot_kwargs=None,
|
|
131
|
+
clinical=False,
|
|
132
|
+
clinical_thresholds=None,
|
|
133
|
+
channel_clinical=False,
|
|
134
|
+
channel_clinical_thresholds=None,
|
|
135
|
+
) -> dict:
|
|
136
|
+
"""Build a standardized audit pack for a deployment contract.
|
|
137
|
+
|
|
138
|
+
Set `slope_boot=True` to add a finite-label affine slope-repair uncertainty
|
|
139
|
+
certificate when labeled target data are supplied. The option is disabled by
|
|
140
|
+
default to keep routine audit packs lightweight.
|
|
141
|
+
"""
|
|
142
|
+
pack = contract.manifest()
|
|
143
|
+
pack["slope_risk"] = contract.slope_risk
|
|
144
|
+
|
|
145
|
+
if X is not None and channels is not None:
|
|
146
|
+
pack["verification"] = verify_contract(contract, X=X, channels=channels).to_dict()
|
|
147
|
+
else:
|
|
148
|
+
pack["verification"] = None
|
|
149
|
+
|
|
150
|
+
if contract.certificate is not None and X is not None and y is not None and channels is not None:
|
|
151
|
+
pack["certificate_evaluation"] = evaluate_certificate(contract, X, y, channels)
|
|
152
|
+
else:
|
|
153
|
+
pack["certificate_evaluation"] = None
|
|
154
|
+
|
|
155
|
+
if slope_boot:
|
|
156
|
+
if X is None or y is None or channels is None:
|
|
157
|
+
raise ValueError("slope_boot=True requires X, channels, and y")
|
|
158
|
+
kwargs = dict(slope_boot_kwargs or {})
|
|
159
|
+
pack["slope_repair_certificate"] = _slope_repair_certificate(contract, X, channels, y, kwargs)
|
|
160
|
+
else:
|
|
161
|
+
pack["slope_repair_certificate"] = None
|
|
162
|
+
|
|
163
|
+
if clinical:
|
|
164
|
+
if X is None or y is None or channels is None:
|
|
165
|
+
raise ValueError("clinical=True requires X, channels, and y")
|
|
166
|
+
pack["clinical_threshold_audit"] = _clinical_threshold_audit(contract, X, channels, y, clinical_thresholds)
|
|
167
|
+
else:
|
|
168
|
+
pack["clinical_threshold_audit"] = None
|
|
169
|
+
|
|
170
|
+
if channel_clinical:
|
|
171
|
+
if X is None or y is None or channels is None:
|
|
172
|
+
raise ValueError("channel_clinical=True requires X, channels, and y")
|
|
173
|
+
pack["channel_clinical_summary"] = _channel_clinical_summary(
|
|
174
|
+
contract, X, channels, y, channel_clinical_thresholds
|
|
175
|
+
)
|
|
176
|
+
else:
|
|
177
|
+
pack["channel_clinical_summary"] = None
|
|
178
|
+
|
|
179
|
+
return pack
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def save_audit_pack(
|
|
183
|
+
contract: DeploymentContract,
|
|
184
|
+
path,
|
|
185
|
+
X=None,
|
|
186
|
+
channels=None,
|
|
187
|
+
y=None,
|
|
188
|
+
slope_boot=False,
|
|
189
|
+
slope_boot_kwargs=None,
|
|
190
|
+
clinical=False,
|
|
191
|
+
clinical_thresholds=None,
|
|
192
|
+
channel_clinical=False,
|
|
193
|
+
channel_clinical_thresholds=None,
|
|
194
|
+
) -> dict:
|
|
195
|
+
"""Save an audit pack JSON and return it."""
|
|
196
|
+
pack = audit_pack(
|
|
197
|
+
contract,
|
|
198
|
+
X=X,
|
|
199
|
+
channels=channels,
|
|
200
|
+
y=y,
|
|
201
|
+
slope_boot=slope_boot,
|
|
202
|
+
slope_boot_kwargs=slope_boot_kwargs,
|
|
203
|
+
clinical=clinical,
|
|
204
|
+
clinical_thresholds=clinical_thresholds,
|
|
205
|
+
channel_clinical=channel_clinical,
|
|
206
|
+
channel_clinical_thresholds=channel_clinical_thresholds,
|
|
207
|
+
)
|
|
208
|
+
with open(str(path), "w", encoding="utf-8") as f:
|
|
209
|
+
json.dump(pack, f, indent=2, sort_keys=True)
|
|
210
|
+
return pack
|