跳转至

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。

实际字符预算 JSON

从报告查看真实表与图,按实际分母判断。完整可运行代码使用共享准备入口,复用同一宽表与固定参考样本。

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。文件缺失会明确失败,正式入口不回退合成数据。 数据下载与输入准备 · 完整共享源码 · 共享包 · 来源和哈希 · 案例索引