research(rectification): scoring-method scaffold — LR weights, absence, precision follow-up pipelines on v4, verdicts pending v5 (BUG-1091)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
5f84637ea9
commit
abf2ad6aea
@@ -121,3 +121,4 @@ Do not open new product surfaces before at least one of these four lanes is clos
|
||||
- 定论页(先读这个):`<repo>/docs/research/rectification_minute_resolution_closure_2026_09_14.md`
|
||||
- 两个已被证伪的假设:加权重能拉开候选;簇合并把候选并没了(合并从未触发)。
|
||||
- 未解决的只剩「区间内部并列」,目前唯一被证明有效的信息源是用户提供的带年月新经历。
|
||||
- 2026-09-29 打分方法研究(脚手架,判定待 v5):`<repo>/docs/research/rectification_scoring_research_2026_09_29.md`——似然比校准权重 / 缺席证据 / 精度追问三条流水线已在 v4 上跑通,所有判定 `pending_v5`;任务书 `docs/tasks/TASK-rectification-scoring-research-20260929.md`,前置 `TASK-rectification-holdout-expansion-20260929.md`。
|
||||
|
||||
@@ -94,3 +94,8 @@
|
||||
- 任务书和 BUG-689 邀请语依据里的「1 分钟 ≈ 1.1 天大运边界位移」有误,实测中位 3.8 天(1.3–5.9)。45 天闸门对应 8–34 分钟,不是 40 分钟。
|
||||
- 新增答错容错:答错 1 题,真值在区间 98–100%;答错 2 题,±30 / ±60 上 7–10% 的回放会挤出真值(两道反答 = 8 分 = 淘汰线)。
|
||||
- 全文见 `docs/research/rectification_offline_research_2026_09_26.md`。
|
||||
|
||||
## 9. 后续(2026-09-29 打分方法研究单,脚手架阶段)
|
||||
|
||||
- §1.3「加权重类改法全部不过门」说的是**人拍权重**。2026-09-29 研究单换了路线:每条规则的权重由数据估(似然比,leave-one-case-out),允许负权重(只奖不罚是结构性问题),KP / Pranapada / D60 作为特征进入由数据定权重;另测「缺席证据」与「对已说事件追问月份」。
|
||||
- 脚手架与 v4 流水线见 `docs/research/rectification_scoring_research_2026_09_29.md`;**判定必须在 v5(≥60 例)上做**,v4 上的数字只是调试参考(BUG-1090 / BUG-1091)。本页 §1–§7 的结论不因此改变。
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
# 生时校正打分方法研究:似然比权重 / 缺席证据 / 精度追问(脚手架阶段,2026-09-29)
|
||||
|
||||
- 任务书:`docs/tasks/TASK-rectification-scoring-research-20260929.md`;进度:`docs/tasks/PROGRESS-rectification-scoring-research-20260929.md`
|
||||
- 分支:`codex/rectification-scoring-research-20260929`,基线 `origin/staging` @ `6e393780`(开工时 head;任务书写作时为 `5febb111`,其间只有文档提交)。
|
||||
- 性质:**离线测量,不改线上代码、打分、阈值、出题闸门、Skill、冻结文件。** 研究计分器是 `precision_gate_lib.score_event_with_policy`(09-14 / 09-26 已证与线上逐分相同)加上不计分的"额外观察",通过 `build_event_contribution_matrix(row_provider=…)` 走线上同一条矩阵 / 出题 / 六题回放链。
|
||||
- 数据:`references/real_case_calibration/minute_rectification_holdout_v4.json`,20 例公开 Rodden-AA。**这是开放集回放,不是盲测;本页所有数字都是 v4 调试参考,任务书规定判定只能在 v5(≥60 例)上做,所以每一项的判定栏都是 `pending_v5`。**
|
||||
- 口径:ayanamsa `raman`,node mode `mean`,步长 2 分钟,半径 ±10 / ±30 / ±60;六题回放(`ASK_COUNT = 6`,按真值作答,题目由线上 G0 出题器按**线上矩阵**出一次、各方案共用);交付区间 = 未淘汰且落后头名不足 8 分的簇并集。两种先验都报:`raw`(引擎行原始分,09-14 / 09-26 口径)与 `percent`(线上 `relative_support` 百分比口径;似然比方案用带温度的 softmax 后验,见 R-A)。
|
||||
- 复跑:`PYTHONHASHSEED=0 python3 scripts/research/scoring_research.py --cache-dir <临时目录>`(约 14 分钟)→ `docs/research/scoring_research_{lr,absence,precision_followup}_2026_09_29.json`。同机两次运行 JSON 逐字节一致(见进度记录)。
|
||||
- 判门:`precision_gate_lib.gate_verdict`(头名不降**且**宽度下降、覆盖不降);JSON 里以 `debug_verdict_v4` 记录,`verdict` 字段一律 `pending_v5`。
|
||||
|
||||
## 结论
|
||||
|
||||
| 项 | 一句话结论(v4 调试参考) | 判定 |
|
||||
| --- | --- | --- |
|
||||
| R-0 脚手架 | 研究计分器与线上 `score_candidates` 在 20 例 × 3 档 = 60 个 case-radius 上**逐分对账 0 差**(分数与规则 id 都相同);每个 (候选, 事件, 采样日期) 记录 42 个特征(线上规则 25 个 + 额外观察 17 个) | 完成 |
|
||||
| R-A 似然比权重 | 流水线跑通。v4 上:留一法 `raw` 口径头名 / 覆盖与基线持平或略动(±30 A3 头名 0.55 → 0.65、宽度 33 → 31),引擎自身头名(答题前)±10 0.30 → 0.40–0.45;`percent` 口径的 softmax 后验即使按训练集拟合温度仍过度自信,把真值挤出区间(±10 squeezed 3–5 例)。20 例上 42 个特征里 31–38 个的置信区间跨 0 | `pending_v5` |
|
||||
| R-B 缺席证据 | 流水线跑通。v4 上按卡片同等强度(2 分)扣分会大量挤出真值(±60 覆盖 1.00 → 0.40)——**v4 的事件表是传记摘录,不是完整时间线,空白年不等于没发生**;真人口述同样不完整。0.5 分档不挤真值但头名下降 | `pending_v5`(v4 信号明确为负,v5 上若不翻转即关闭) |
|
||||
| R-C 精度追问 | 流水线跑通。把日精度经历降成"只记得年"后,**每例平均只有 0.2 / 0.45 / 0.7 件经历在知道月份后能把候选分到两边**(±10 只有 2/20 例有);对这些例子把那一件恢复到月精度重算先验(`C1_prior`)在 ±30 上 7 例头名 0.71 vs 该 7 例的 C0,其余档位样本太少 | `pending_v5` |
|
||||
|
||||
## R-0 · 脚手架与对账
|
||||
|
||||
- `scripts/research/scoring_research_lib.py`
|
||||
- `make_recording_provider`:对每个 legacy 单事件请求,用 `score_event_with_policy`(V0 基线)+ 线上的过运 / Ashtakavarga / Shadbala 辅助(取 context 里线上算好的结果)产出**与线上完全相同**的 evidence,同时把该候选在该事件下的额外观察写进 `FeatureStore`:
|
||||
- 线上规则(记为特征):`vim_{md,ad,pd}_domain_{house,lord,varga}`、`{label}_functional_{benefic,malefic}_auxiliary`、`narayana_{md,ad}_domain_house`、`{label}_arudha_auxiliary`、`controlled_transit_{jupiter,saturn}_domain_house`、`ashtakavarga_target_house_{support,pressure}_auxiliary`、`shadbala_sthana_drik_naisargika_{support,pressure}_auxiliary`。`event_kind:*`、`no_domain_activation`、`*_auxiliary_not_primary` 不作特征。
|
||||
- 额外观察(线上算了没计分):`kp_target_cusp_{sublord,starlord}_is_vim_{md,ad,pd}`、`kp_asc_sublord_is_vim_{md,ad,pd}`(`feature.kp_cusps.houses`,Placidus + Krishnamurti)、`vim_{md,ad,pd}_domain_varga_d60`(D60 现算)、`{pranapada,hora_lagna,ghati_lagna,bhava_lagna}_in_target_house`(`_fine_minute_indices`)。
|
||||
- `reconcile_rows`:逐分比较分数与规则 id。**60/60 case-radius 差异 0。**
|
||||
- `event_feature_matrix`:特征值 = 该规则在该事件采样日期上命中的比例(年精度 12 个采样日、月 3 个、日 1 个),与线上按采样日平均分数同口径。
|
||||
- 真值标签:候选属于真值所在的**签名簇**(`raw_signature_clusters`)。
|
||||
- 测试:`tests/test_scoring_research.py`(10 条:LR 估计、留一法不泄漏、特征矩阵、规则过滤、加权 provider、缩放答案、缺席年、精度升降、百分比、以及 v4 公开案例 ±10 对账 0 差)。
|
||||
|
||||
## R-A · 似然比校准权重
|
||||
|
||||
**方法。** 对每个特征 f,`log LR_present = log P(f | 真值簇) − log P(f | 非真值簇)`,拉普拉斯平滑 α = 1(`(Σx + 1) / (N + 2)`);`log LR_absent` 为朴素贝叶斯互补项。每档半径单独估。
|
||||
|
||||
| 方案 | 特征 | 权重规则 |
|
||||
| --- | --- | --- |
|
||||
| A1 | 只用线上 25 条规则 | 只奖不罚:`max(log LR_present, 0)`,不用 absent 项 |
|
||||
| A2 | 加 17 个额外观察 | 同上 |
|
||||
| A3 | 同 A2 | 朴素贝叶斯:present + absent 两项都用,允许负权重 |
|
||||
|
||||
候选分 = Σ 事件 Σ 特征(x·w_present + (1−x)·w_absent),经线上矩阵的事件类型系数、精度权重、采样日平均与大运边界邻近项(后者按线上原样附加,不重加权)。两个只从**训练折**估的标定量:`scale`(研究分的例内极差中位 → 线上极差中位,让 `raw` 回放的 ±2 / 8 分线意义不变)、`temperature`(Platt 单温度,最大化训练例真值簇的对数后验;网格 0.25–256),`percent` 先验 = softmax(分 / T) × 100。**留一法按案例留**(`loo_folds`),全集拟合另报只作参照。
|
||||
|
||||
### 六题回放(留一法;括号内为全集拟合)
|
||||
|
||||
`raw` 口径:
|
||||
|
||||
| 半径 | 方案 | 头名命中 | 真值在区间 | 宽度中位 | 引擎头名(答题前) | 挤出真值 | debug 判定 |
|
||||
| --- | --- | ---: | ---: | ---: | ---: | ---: | --- |
|
||||
| ±10 | 基线 | 0.80 | 1.00 | 15 | 0.30 | 0 | — |
|
||||
| ±10 | A1 | 0.70 (0.75) | 1.00 | 14 | 0.45 | 0 | no_benefit |
|
||||
| ±10 | A2 | 0.75 (0.80) | 1.00 | 15 | 0.40 (0.50) | 0 | no_benefit |
|
||||
| ±10 | A3 | 0.80 (0.85) | 1.00 | 15 | 0.40 (0.50) | 0 | no_benefit |
|
||||
| ±30 | 基线 | 0.55 | 1.00 | 33 | 0.20 | 0 | — |
|
||||
| ±30 | A1 | 0.55 (0.70) | 1.00 | 32 | 0.25 | 0 | benefit(宽度 −1) |
|
||||
| ±30 | A2 | 0.60 (0.65) | 1.00 | 34 | 0.10 (0.30) | 0 | no_benefit |
|
||||
| ±30 | A3 | 0.65 (0.75) | 1.00 | 31 | 0.20 (0.45) | 0 | benefit(宽度 −2) |
|
||||
| ±60 | 基线 | 0.40 | 1.00 | 56 | 0.05 | 0 | — |
|
||||
| ±60 | A1 | 0.45 (0.50) | 1.00 | 61 | 0.15 (0.20) | 0 | no_benefit |
|
||||
| ±60 | A2 | 0.55 (0.60) | 1.00 | 61 | 0.00 (0.10) | 0 | no_benefit |
|
||||
| ±60 | A3 | 0.50 (0.70) | **0.95** | 61 | 0.05 (0.30) | 1 | no_benefit |
|
||||
|
||||
`percent` 口径(基线 = 线上比例百分比;A* = 拟合温度的 softmax 后验):
|
||||
|
||||
| 半径 | 方案 | 头名命中 | 真值在区间 | 宽度中位 | 挤出真值 | 温度(各折) |
|
||||
| --- | --- | ---: | ---: | ---: | ---: | --- |
|
||||
| ±10 | 基线 | 0.90 | 1.00 | 11 | 0 | — |
|
||||
| ±10 | A1 / A2 / A3 | 0.60 / 0.50 / 0.55 | 0.80 / 0.85 / 0.75 | 7 / 7 / 5 | 4 / 3 / 5 | 1–2 / 1 / 0.5–1 |
|
||||
| ±30 | 基线 | 0.85 | 1.00 | 33 | 0 | — |
|
||||
| ±30 | A1 / A2 / A3 | 0.65 / 0.55 / 0.55 | 0.95 / 0.80 / 0.90 | 31 / 10 / 13 | 1 / 4 / 2 | 2–4 / 1–2 / 1–2 |
|
||||
| ±60 | 基线 | 0.80 | 1.00 | 53 | 0 | — |
|
||||
| ±60 | A1 / A2 / A3 | 0.65 / 0.50 / 0.40 | 1.00 / 0.80 / 0.80 | 57 / 32 / 38 | 0 / 4 / 4 | 4–8 / 2–4 / 2 |
|
||||
|
||||
**读法(v4,仅供 v5 前设计参考,不是结论)。**
|
||||
|
||||
1. 对账通过后,`raw` 口径的留一法数字与基线基本持平:似然比权重没有让真值掉出区间(±60 A3 一例除外),也没有明显收窄;引擎答题前的头名在 ±10 从 0.30 到 0.40–0.45、±60 A1 从 0.05 到 0.15,全集拟合再高一些——**全集与留一法的差距就是 20 例过拟合的量**。
|
||||
2. `percent` 口径下 softmax 后验**过度自信**:即使温度按训练折拟合,仍把 15–25% 例子的真值挤出区间。校准曲线(A3 留一法)在 ±10 上 [0.20,0.30) 桶预测 0.24 / 实际 0.40、[0.50,0.70) 预测 0.58 / 实际 0.40、[0.70,1.00) 只有 1 个点且错;±30 / ±60 高桶几乎无样本。要上线必须先解决后验的标定,而不是先验本身。
|
||||
3. **42 个特征里 31 / 36 / 38 个(±10 / ±30 / ±60)的 5–95% 置信区间跨 0**(案例级 bootstrap 200 次)。±10 上区间不跨 0 的:`ashtakavarga_target_house_pressure_auxiliary`(+0.41)、`vim_ad_domain_varga`(+0.30)、`vim_md_domain_varga`(+0.27)、`ghati_lagna_in_target_house` / `hora_lagna_in_target_house`(+0.31)、`pranapada_in_target_house`(**−0.36**)、`vim_ad_arudha_auxiliary`(−0.21)、`narayana_ad_domain_house`(−0.21)、`kp_target_cusp_sublord_is_vim_ad`(−0.19)。方向与线上手拍权重相反的几条(Arudha、Narayana AD、KP AD 子主为负)正是 20 例上说不清的地方——这就是任务书要先扩集的原因。
|
||||
4. 稳健性(留一法 A3,`raw`):±7 天抖动与 ±1–3 月平移三档真值在区间 0.95–1.00;答错 1 题 0.96–1.00、答错 2 题 0.91–0.99(与 09-26 基线同量级)。`percent` 口径下三项都更差(0.70–0.90),同样是后验过自信的表现。
|
||||
|
||||
## R-B · 缺席证据
|
||||
|
||||
**方法。** 只用训练事件(留一件 holdout 不用)。每个领域取第一件与最后一件带年月事件之间的年份,没有该领域事件的年份 = 缺席年。对每个缺席 (领域, 年) 用出题器同一判定函数 `_evaluate_contexts(month=None)` 在代表候选上求"这一年该领域是否激活"的分边;分得开就当作一道答了"没有"的题,按 0.5 / 1.0 / 2.0 分扣(卡片是 2.0;低于卡片强度的扣分不计强冲突、不会淘汰)。之后照常六题。漏说稳健性:随机删掉 1–2 件训练事件再算缺席年(每例 5 次,种子固定)。
|
||||
|
||||
`raw` 口径六题回放(`percent` 口径同向,见 JSON):
|
||||
|
||||
| 半径 | 方案 | 头名命中 | 真值在区间 | 宽度中位 | 挤出真值 | 漏说 1 件(100 次回放)真值在区间 | 漏说 2 件 |
|
||||
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
|
||||
| ±10 | B0 | 0.80 | 1.00 | 15 | 0 | — | — |
|
||||
| ±10 | 缺席 @0.5 分 | 0.70 | 1.00 | 15 | 0 | 1.00 | 1.00 |
|
||||
| ±10 | 缺席 @1.0 分 | 0.70 | 1.00 | 14 | 0 | 1.00 | 1.00 |
|
||||
| ±10 | 缺席 @2.0 分(=卡片) | 0.55 | **0.85** | 13 | 3 | 0.94 | 0.94 |
|
||||
| ±30 | B0 | 0.55 | 1.00 | 33 | 0 | — | — |
|
||||
| ±30 | 缺席 @0.5 分 | 0.50 | 1.00 | 34 | 0 | 1.00 | 1.00 |
|
||||
| ±30 | 缺席 @1.0 分 | 0.45 | 1.00 | 33 | 0 | 1.00 | 1.00 |
|
||||
| ±30 | 缺席 @2.0 分 | 0.25 | **0.70** | 19 | 6 | 0.80 | 0.87 |
|
||||
| ±60 | B0 | 0.40 | 1.00 | 56 | 0 | — | — |
|
||||
| ±60 | 缺席 @0.5 分 | 0.35 | 1.00 | 68 | 0 | 1.00 | 1.00 |
|
||||
| ±60 | 缺席 @1.0 分 | 0.25 | 1.00 | 61 | 0 | 1.00 | 1.00 |
|
||||
| ±60 | 缺席 @2.0 分 | 0.10 | **0.40** | 9 | 12 | 0.54 | 0.73 |
|
||||
|
||||
每例平均缺席年 17.95;能分边的缺席题 2.05 / 4.30 / 6.15 道(有题的例子 12 / 17 / 17)。三档 debug 判定全部 no_benefit。
|
||||
|
||||
读法:
|
||||
|
||||
1. **按卡片强度扣,真值被大量挤出**(±60 覆盖 1.00 → 0.40)。原因不是方法错,而是 v4 的事件表是传记摘录:那些"空白年"里公众人物多半确有该领域的事,只是没进数据集;扣分等于用不完整的时间线否定真值。真人口述同样不完整(用户不会把每年的事都说全),所以这条在 v5 上大概率也是负的——**若 v5 上不翻转,R-B 关闭**。
|
||||
2. 0.5 / 1.0 分档不挤真值(覆盖 1.00)但头名一律下降、宽度不降,等于只加噪声。漏说 1–2 件在低强度下不伤覆盖,在卡片强度下把覆盖压到 0.54–0.94。
|
||||
|
||||
## R-C · 精度追问可行性
|
||||
|
||||
**方法。** 把每例所有日精度经历降成"只记得年"(v4 没有月精度)作为口述形态 `C0_spoken`,先验按线上重算。对每件训练中的日精度经历,用 `_evaluate_contexts(month=真实月份)` 判断"知道月份后能否把代表候选分到两边";能分的按信息增益排序取前 1 / 2 件:`C{k}_prior`(那件恢复到月精度重算先验)、`C{k}_probe`(当作答"是"的卡)、`C{k}_both`。
|
||||
|
||||
| 半径 | 每例可追问件数均值 | ≥1 件的例子 | ≥2 件的例子 |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| ±10 | 0.20 | 2 / 20 | 1 / 20 |
|
||||
| ±30 | 0.45 | 7 / 20 | 1 / 20 |
|
||||
| ±60 | 0.70 | 10 / 20 | 3 / 20 |
|
||||
|
||||
| 半径 | 方案 | n | 头名命中(raw) | 真值在区间 | 宽度中位 | 同 n 例的 C0(raw 头名 / 宽度) |
|
||||
| --- | --- | ---: | ---: | ---: | ---: | --- |
|
||||
| ±10 | C1_prior / C1_probe | 2 | 1.00 / 0.50 | 1.00 | 16 | 见 JSON per-arm(样本太少) |
|
||||
| ±30 | C1_prior | 7 | 0.71 | 1.00 | 31 | debug 判定 benefit(percent 口径头名 1.00) |
|
||||
| ±30 | C1_probe | 7 | 0.57 | 1.00 | 33 | no_benefit |
|
||||
| ±60 | C1_prior / C1_probe | 10 | 0.40 / 0.40 | 1.00 | 58 / 63 | no_benefit |
|
||||
|
||||
**读法。** 可追问的经历很少(与 09-29 打字经历研究一致:绝大多数经历落在所有候选都一样的大运段),但在 ±30 上"恢复到月精度重算先验"(走线上已有的打字经历通道,不加卡片)对那 7 例有正向信号;"当作答是的卡"没有。样本太少,只能说值得在 v5 上按同口径重测;产品层实现(只对落在候选分歧点的那一件追问月份,算在定向追问 2 条额度内)要等 v5 判定。
|
||||
|
||||
## 给产品的话
|
||||
|
||||
- 三条流水线都跑通、与线上对账 0 差,**但没有任何一条在 v4 上能下结论**,20 例上 42 个特征有四分之三分不清正负。这一轮交付的是"能在 v5 上一键复跑的测量工具",不是新打分。
|
||||
- v4 上唯一方向明确的信号是负的:把口述时间线的空白当"没发生"会伤真值(R-B)。
|
||||
- v5 交付后的复跑命令:`PYTHONHASHSEED=0 python3 scripts/research/scoring_research.py --holdout references/real_case_calibration/minute_rectification_holdout_v5.json --dataset-label v5 --out-suffix v5_<日期>`。
|
||||
|
||||
## 附:复跑命令
|
||||
|
||||
```bash
|
||||
PYTHONHASHSEED=0 python3 scripts/research/scoring_research.py --cache-dir /tmp/scoring_ctx # 约 14 分钟,写三份 JSON
|
||||
PYTHONHASHSEED=0 python3 scripts/research/scoring_research.py --limit 3 --radii 10 --fast --no-write # 开发用
|
||||
python3 -m pytest tests/test_scoring_research.py -q
|
||||
```
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user