6 · 分析完成后,如何保存并继续查询?¶
本批保留 Home Credit 两张 application 表的全部 356,255 条记录。TARGET 来自原比赛训练表,比赛测试表的 48,744 条记录保持 null。APPLY_DATE 是按 ID 稳定散列生成的演示日期。0train 用于拟合和 PSI 基准,1val 用于验证或筛选,2test 与 3oot 用于固定结果的独立复核,4_oot_undue 仅表示比赛未公开标签。日期、元数据和角色映射见输入方案与分区说明。
本批实际结果¶
| 检查 | 实际结果 |
|---|---|
| 第一页/下一页 | 3/3 |
| 合法空结果 | 0 |
| 无效列 | ValueError |
| 字符/预算 | 7547/9000 |
| 固定策略回放一致 | True |
新进程只读取 binning.marsreport。从 describe() 找到目录、单位、计算状态和业务元数据,再按问题请求有限页。 分页结果记录 total_rows、returned_rows、omitted_rows、next_offset 和 reference。to_ai_context 的 max_chars 是字符预算,不是 token。 比较 1val 与 4_oot_undue 时先核对标签覆盖。无标签指标是未观测,不能把 null 翻译为零风险。 这些查询是确定性公共 API 消费,没有调用 LLM。外部 Agent 可按同样接口继续取证,不依赖内置会话或模型 SDK。 快照只保存已计算统计;新增维度、原始记录或重新拟合需要原数据。恢复对象为 ReportSnapshot。
从报告查看真实表与图,按实际分母判断。完整可运行代码使用共享准备入口,复用同一宽表与固定参考样本。
def _consume(output: Path) -> None:
"""新进程只读快照,验证分页、字符预算、引用和固定聚合策略回放。"""
report = load_report(output / "binning.marsreport")
original = json.loads((output / "case-2.json").read_text(encoding="utf-8"))
assert report.report_id == original["report_id"]
for key in ("feature_metadata", "business_context", "parameters", "tables"):
assert report.describe()[key] == original["description"][key], key
for query in original["queries"]:
ref = query["reference"]
if ref["report_id"] == report.report_id:
assert _rows(report.get_table(ref["table"], **ref["query"])) == query["rows"]
scope = {"mars_group": "1val", "y": "TARGET"}
columns = ["feature", "mars_group", "bin_index", "bin_label", "count", "observed_count", "bad_rate"]
first = _query(report, "detail", "验证组固定箱实际第一页", features="EXT_SOURCE_2", filters=scope,
columns=columns, sort_by="bin_index", limit=3)
second = _query(report, "detail", "按 next_offset 下一页", features="EXT_SOURCE_2", filters=scope,
columns=columns, sort_by="bin_index", offset=first["next_offset"], limit=3)
empty = _query(report, "detail", "合法空结果", filters={"mars_group": "not-present"}, limit=3)
unobserved = _query(report, "detail", "无标签组的分布人数与空坏率", features="EXT_SOURCE_2",
filters={"mars_group": "4_oot_undue"}, columns=columns, limit=6)
try:
report.get_table("detail", columns=["not_a_column"], limit=1)
except ValueError as exc:
invalid_request = {"exception": "ValueError", "message": str(exc)}
else:
raise AssertionError("无效列必须失败。")
context = report.to_ai_context(queries={"detail": {"features": "EXT_SOURCE_2", "filters": scope,
"columns": columns, "limit": 40}}, max_chars=9000)
bounded = json.loads(context)
assert len(context) <= 9000
for entry in bounded["evidence"]:
assert _rows(report.get_table(entry["reference"], **entry["query"])) == entry["rows"]
(output / "agent-context.json").write_text(context + "\n", encoding="utf-8")
replay = evaluate_score_policy(load_report(output / "score-cross.marsreport"), POLICY, baseline=BASELINE)
policy = load_report(output / "policy.marsreport")
assert _rows(replay.get_table("changes")) == _rows(policy.get_table("changes"))
_case(output, 6, report, "保存分箱报告之后,如何在新进程继续查询?", [first, second, empty, unobserved], {
"snapshot_type": type(report).__name__, "identity_preserved": True, "separate_process": True,
"context_chars": len(context), "max_chars": 9000, "budget_omissions": bounded.get("omissions", bounded.get("omitted", [])),
"invalid_request": invalid_request, "policy_replay_matches": True, "table_names": list(report.describe()["tables"]),
}, "快照保存聚合结果与能力边界,不恢复原始宽表或任意分析器。")
if (output / "rules-independent.marsreport").exists():
consume(output)
if (output / "raw-correlation.marsreport").is_file():
matrix = show_correlation_matrix(load_report(output / "raw-correlation.marsreport"))
_write_correlation_html(matrix, output / "correlation.html")
_refresh_rule_html_styles(output)
新进程按目录读取已保存统计;实际有限 JSON 中的引用可重放。
from mars.reporting import load_report
report = load_report("binning.marsreport")
print(report.describe())
page = report.query_page("summary", features="EXT_SOURCE_2", limit=3)
print(page["reference"], page["data"])
实际查询结果与分页引用
{
"case": 6,
"report_id": "d73396cc-4ad6-493e-a69a-0cd2a0a435e6",
"consumer": "deterministic public API queries; no LLM",
"question": "保存分箱报告之后,如何在新进程继续查询?",
"query": {
"question": "验证组固定箱实际第一页",
"reference": {
"report_id": "d73396cc-4ad6-493e-a69a-0cd2a0a435e6",
"table": "detail",
"query": {
"offset": 0,
"limit": 3,
"features": "EXT_SOURCE_2",
"filters": {
"mars_group": "1val",
"y": "TARGET"
},
"columns": [
"feature",
"mars_group",
"bin_index",
"bin_label",
"count",
"observed_count",
"bad_rate"
],
"sort_by": "bin_index"
}
},
"total_rows": 6,
"returned_rows": 3,
"omitted_rows": 3,
"next_offset": 3,
"rows": [
{
"feature": "EXT_SOURCE_2",
"mars_group": "1val",
"bin_index": -1,
"bin_label": "Missing",
"count": 66.0,
"observed_count": 66.0,
"bad_rate": 0.09090909090909091
},
{
"feature": "EXT_SOURCE_2",
"mars_group": "1val",
"bin_index": 0,
"bin_label": "00_[-inf, 0.3922)",
"count": 7568.0,
"observed_count": 7568.0,
"bad_rate": 0.14442389006342496
},
{
"feature": "EXT_SOURCE_2",
"mars_group": "1val",
"bin_index": 1,
"bin_label": "01_[0.3922, 0.566)",
"count": 7641.0,
"observed_count": 7641.0,
"bad_rate": 0.08807747677005627
}
]
},
"unavailable": "快照保存聚合结果与能力边界,不恢复原始宽表或任意分析器。"
}
运行与下载¶
python docs/snippets/task_cases.py --case 6 --data-dir examples/home-credit-2018/data/raw_data --output-dir output/task-cases
首次生成全部关联证据用 --case all。文件缺失会明确失败,正式入口不回退合成数据。 数据下载与输入准备 · 完整共享源码 · 共享包 · 来源和哈希 · 案例索引