总览 · ← 返回运行 20261003-172000-search-t2-heart-extrap-chain-12h
节点 n31 在终选来历上
几何均值总量比均匀线性缩放替代逐细胞线性总量回拉(γ=0.45):log 域近似恒定每细胞偏移,保住位移的跨基因 dp 排序;PLAN 的速度表达水平回归经 6 配置查分证否后按备选机制路径提交。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-172000-search-t2-heart-extrap-chain-12h |
|---|---|
| 父节点 | n29 |
| 子节点 | n33 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 56.60(+0.4) · proxy_noscale 56.60(+0.4) · 3 次复测均分 56.61 |
| 审查 | 通过 1 未发现问题:run.py 仅通过 harness 的 src.task2_spatial.view_io(load_manifest/read_stage/panel_genes/anchor_entry/extrap_step)读取 manifest 给的输入阶段,无绝对路径、..、/mnt、/home、data/raw、downloads、evaluation 目录访问,无联网(grep open/requests/urllib/socket/subprocess 无命中)。; 2 未发现问题:所有常数为算法超参(γ=0.45、PBC=10、k=0.5、ε=0.4 等),细胞型按 s… |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 55 分 |
| 程序版本 | 673b91fb60160de3bc016bf8441d2de07241525d (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 673b91fb60:solution/METHOD.md
几何均值总量比均匀线性缩放替代逐细胞线性总量回拉(γ=0.45):log 域近似恒定每细胞偏移,保住位移的跨基因 dp 排序;PLAN 的速度表达水平回归经 6 配置查分证否后按备选机制路径提交。
节点 31(improve,父 = 节点 29,proxy_noscale A 半 56.23)
实际提交的方法族与机制
- family_id: T2HX-01(copy_last 基座上的按型速度乘法外推),底物/门控/坐标冻结全部承自节点 29。
- 提交机制:几何均值再闭合(geometric re-closure),
VEC_RECLOSE_GEO=1(默认)、VEC_GAMMA=0.45(默认)。 节点 24 以来的 γ 再闭合把每个位移后细胞的线性总量拉回其自身平滑后总量:由于拉回是逐细胞线性缩放, 高表达基因以加性 log 偏移吸收、低表达基因以乘性方式吸收,跨基因 dp 排序被扭曲(实测再闭合后 spearman(dp, dt_approx) 从 0.57 掉到 0.39)。几何变体改为施加统一线性缩放s_i = (r_med / r_i)^γ(r_i = tot_new_i / tot_old_i,r_med = 全体中位数):log1p 域大值每细胞近似 平移同一常数,位移的基因排序大部分保留(γ=0.3 时 spearman_post 0.4624 > 父 0.3941),同时位移后线性 总量中位数仍落回未位移中位数(实测阶段的库容量不变量在中位数意义上保持)。零保持零、稀疏模式/坐标/ 行序/细胞数/组成全部不变;PBC=10、软阈值 k=0.5、门控、平滑 ε=0.4 底物均不变。
PLAN 机制(速度表达水平回归)——已证否
PLAN 要求逐型把 v_t 对锚阶段 log1p 表达水平 OLS 回归取残差(std 复原)以改善 de_score。已按 PLAN 实现
(VEC_VEL_REGRESS/VEC_REGRESS_MODE/VEC_REGRESS_W/VEC_REGRESS_KEEPMEAN,代码保留、默认关),
离线诊断:33 个细胞型中 28 型 R² < 0.05(PLAN 风险 1 的放弃线),仅 Forebrain 0.12 / Hindgut 0.095 /
Unknown 0.095 / Neural Tube 0.083 有可去趋势;回归前后速度 Spearman 0.92–1.00。6 次查分(≥3 种幅度组合、
共 20 次查分额度用满)de_score 全部低于父节点 0.1944,PLAN 首查目标 ≥0.20 未达成,de_direction 监控线
0.28 大多被击穿 → 按 improve 规则转备选机制(下表 #1–#6)。
结论(供后续节点):速度与表达水平的共线分量携带真实 DE 信号而非纯 chance 伪影——去水平化 (回归残差、加性解码)一律降 de_score/de_direction;#11 的支撑掩码加性解码(level-free dp)使 de_direction 塌到 0.046,是本方向最强的证否证据。
全部 20 次查分(proxy_noscale A 半;父 = 56.23:de_score 0.1944 / de_dir 0.2837 / mmd_u 0.04669 / vario 0.03795 / nb_mmd 0.07569)
| # | 配置 | 榜分 | de_score | de_dir | mmd_u | vario | nb_mmd |
|---|---|---|---|---|---|---|---|
| 1 | 回归 type w=1 | 55.86 | 0.1806 | 0.2638 | 0.04562 | 0.03991 | 0.07936 |
| 2 | 回归 global w=1 | 55.84 | 0.1667 | 0.2523 | 0.04692 | 0.03875 | 0.07828 |
| 3 | 回归 type w=0.5 | 55.88 | 0.1806 | 0.2716 | 0.04655 | 0.03949 | 0.07921 |
| 4 | 回归 type w=−0.5(反向放大) | 55.81 | 0.1528 | 0.2758 | 0.04881 | 0.03773 | 0.07881 |
| 5 | 回归 type w=1 保均值 | 55.79 | 0.1806 | 0.2538 | 0.04610 | 0.04011 | 0.07917 |
| 6 | 回归 global w=0.5 | 55.87 | 0.1667 | 0.2703 | 0.04727 | 0.03874 | 0.07861 |
| 7 | 收缩 N0=150 | 55.63 | 0.1667 | 0.2839 | 0.04649 | 0.04124 | 0.08069 |
| 8 | 收缩 N0=30 | 55.88 | 0.1667 | 0.2888 | 0.04704 | 0.03938 | 0.07912 |
| 9 | 收缩 N0=50 | 55.91 | 0.1806 | 0.2908 | 0.04683 | 0.03974 | 0.07935 |
| 10 | 收缩 N0=400 | 54.89 | 0.1528 | 0.2187 | 0.04704 | 0.04380 | 0.08328 |
| 11 | 加性解码 α=0.5(支撑掩码) | 50.81 | −0.0139 | 0.0462 | 0.05509 | 0.05929 | 0.10479 |
| 12 | 幅度分层 q40/1.15/0.55(移植节点30) | 55.87 | 0.1806 | 0.2869 | 0.05019 | 0.03644 | 0.08029 |
| 13 | 幅度分层 q40/1.3/0.4 | 55.69 | 0.1667 | 0.2821 | 0.05148 | 0.03581 | 0.08128 |
| 14 | 线性再闭合基准=原始总量 | 55.76 | 0.1667 | 0.2678 | 0.04894 | 0.03834 | 0.07897 |
| 15 | 非对称 AUP1.15/ADN0.85 | 55.83 | 0.1528 | 0.2954 | 0.05049 | 0.03565 | 0.08044 |
| 16 | 非对称 AUP0.85/ADN1.15 | 55.24 | 0.1389 | 0.2491 | 0.04694 | 0.04294 | 0.08049 |
| 17 | 速度空间扩散 w=0.5 k=15 | 55.80 | 0.1667 | 0.2811 | 0.04566 | 0.04121 | 0.07907 |
| 18 | 几何再闭合 γ=0.3 | 56.18 | 0.1944 | 0.3132 | 0.04564 | 0.03949 | 0.07906 |
| 19 | 几何再闭合 γ=0.45(提交) | 56.33 | 0.2222 | 0.3215 | 0.04542 | 0.03954 | 0.07932 |
| 20 | 几何再闭合 γ=0.15 | 56.07 | 0.1806 | 0.2999 | 0.04597 | 0.03941 | 0.07885 |
备选机制族(#7–#17):全局速度收缩(4 档幅度)、加性解码、幅度分层(2 档)、再闭合基准、方向非对称 (2 档)、速度空间扩散——全部 ≤ 55.91。几何再闭合是唯一超过父节点的机制(#18–#20,γ 单调上升)。
提交配置的分组变化(#19 vs 父)
- expression_change(父最弱组,57.02)→ 58.15:de_score 0.1944→0.2222(+2 个量化步,全树最佳, 超过 PLAN 首查目标 0.20);de_direction 0.2837→0.3215(全树最佳,连续量、远超以往配置 ±0.01 的抖动)。
- cell_state 58.06 → 58.07:mmd_u 0.04669→0.04542(全树最佳),variogram 0.03795→0.03954(略差)。
- local_spatial 59.83 → 59.09:nb_mmd 0.07569→0.07932(唯一恶化项,−0.74 分,被表达组 +1.13 覆盖)。
- shape_scale 50.00 不变(proxy_noscale 固定 + 坐标冻结)。
- 总分 56.23 → 56.33(+0.10,在 ~1 分噪声内;但机制级证据是结构性的:dp 排序保持度 spearman_post 0.39→0.46,两个 DE 指标同创树内最佳且方向一致,非单指标尖峰)。
机制生效证据与对照
- 机制改变的细胞:全部 24,826 个锚细胞的表达被位移(moved_frac=1.0),几何再闭合改变其中每个细胞的 缩放因子(与线性再闭合逐细胞不同);坐标/行序/细胞数/零模式逐位不变(数组级验证)。
- 关闭对照:
--ablate <任意名>(含 harness 将传入的VEC_VEL_REGRESS,未识别名按主要机制=几何再闭合 处理)或VEC_RECLOSE_GEO=0→ 回到同 γ=0.45 的线性再闭合,输出与主运行不同(mechanism_active 可判)。 VEC_GAMMA=0.3 VEC_RECLOSE_GEO=0时输出与父节点 29 逐位一致(X 与坐标 array_equal=True,已验证); 回归/收缩/分层/扩散/加性解码全部默认关,默认输出 = #19 查分文件逐位一致(已验证)。
验证过 / 未验证
- 已验证:默认输出逐位 = 已查分的 #19;seed 0/1/2 逐位一致(锚 24,826 ≤ max_cells 25,179,分层 take 返回全部行,机制无随机性);伪装视图(时间统一 +1、manifest 键序打乱、路径更换)输出逐位一致; vec-check 通过(主运行与 --ablate);运行 ~3s / <2GB(limits 30min/28GB 内);EXECUTION.json gpu:false。
- 未验证:γ>0.45(0.6/0.75)——γ 扫描在测试范围内单调上升,0.45 是已测最大值而非内点最优,额度用尽 无法外探,后续节点可先试 γ=0.6;B 半与官网外推榜的迁移(本地外推尺子已知高估,历史 54.2→49.6, +0.10 的总分差不可外推,但 de_score/de_direction/mmd_u 三项 raw 同向创树内最佳是更可信的信号); nb_mmd −0.0036 的代价在真实括号上是否更大。
- 单输入阶段/锚≠末输入退路同父:平滑与速度一并关闭,逐位 copy_last。
知识来源
无生物学先验知识被使用(sources=[]):本节点全部改动为算法级(再闭合的缩放几何),只依赖输入数据现场 计算的量(各细胞总量、中位总量比),不含任何由已发布阶段测量值硬编码的常数。
旋钮(默认 = 提交配置)
VEC_RECLOSE_GEO(1)、VEC_GAMMA(0.45);继承:VEC_SMOOTH_STEPS(2)、VEC_SMOOTH_EPS(0.4)、
VEC_SMOOTH_K(15)、VEC_ALPHA(1.0)、VEC_K(0.5)、VEC_PBC(10)、VEC_MIXMODE(rel)、
VEC_MIXREL(1.0)、VEC_MIXEPS(1.0)、VEC_GATE_SPEARMAN(0.3);已证否机制保留可复用:
VEC_VEL_REGRESS(0)、VEC_REGRESS_MODE/W/KEEPMEAN/MINGENES、VEC_SHRINK_N0(0)、VEC_SHRINK_MODE、
VEC_DECODE(mult)、VEC_STRAT_Q(0)/UP/DN、VEC_VDIFF_W(0)/K、VEC_RECLOSE_REF(smoothed)、
VEC_AUP/ADN(1.0)、VEC_DEBUG。
调研员的计划
| 名称 | 速度表达水平回归校正改善DE排序 |
|---|---|
| 动机 | 节点29 expression_change 57.02 是四个非固定组分中最弱(cell_state 58.06、local_spatial 59.83);de_score raw 0.1944(skill 0.557)与 mmd_u 并列最低活跃指标。速度公式 (m_a−m_p)/(m_p+1) 的分母使速度与基因锚阶段表达水平系统性负相关,而 de_score 的 chance 校正恰好减去按 ±pb(ref) 排序的基线——部分本应贡献排序信号的速度方差被当作表达水平伪影扣掉。父节点 ANALYSIS 的 next_suggestions 第2条也指出 de_score 在 γ 平台上跳动(0.1528/0.1667/0.1806),说明排序信号尚未稳定释放。 |
| 做法 | 1) 在速度估计后、软阈值前,对每型 t 的速度向量 v_t 关于 log1p(pb_anchor_t)(逐基因)做 OLS 线性回归,取残差 v_res_t;2) 残差按该型原速度的标准差重缩放(保持位移幅度尺度不变);3) 残差进入后续软阈值 k=0.5 → 乘法位移 α=1 → γ=0.3 再闭合 → PBC=10,管线其余不变(平滑 ε=0.4 底物、门控、坐标/行序/组成冻结);4) 先试按型回归;若 de_score 未升,再试全局池化回归(所有型基因合并拟合一条斜率);5) 单输入阶段 / 锚≠末输入退路同父节点:平滑与速度一并关闭,逐位 copy_last;6) vec-score 快筛:首查 de_score raw 目标 ≥0.20,同时监控 de_direction ≥0.28、mmd_u ≤0.048、nb_mmd ≤0.076,任一显著恶化即停止该方向。 |
| 风险 | 1) 若真实发育变化本身与表达水平相关(如高表达基因确实在减速),回归会移除真实信号,de_score 反降——Engineer 应先打印回归 R²,R²<0.05 说明无趋势可去除,机制无效应尽早放弃并回退;2) 残差重缩放实现错误会改变速度幅度,需数组级验证每型标准差复原;3) 预期提升可能在 1 分噪声内,用种子 0/1/2 三次查分均值确认;4) 按型回归在小型(<30 基因有效表达)上可能过拟合,设最小基因数门限(如 50),低于则跳过该型回归。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 fc5fc15878。改动的文件:solution/METHOD.md +94 −56、solution/README.md +18 −6、solution/run.py +279 −29
diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 388286b..287ec2b 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,62 +1,100 @@-坐标15-NN两步支撑掩码扩散平滑(ε=0.4,保零模式、逐基因列缩放精确复原伪批量)移植为 rel 速度乘法外推的底物,γ 重耦合扫至 0.3。--## 方法(family T2HX-01,节点 27 → 29)--在节点 27 的按型 rel 速度乘法外推(v_t=(m_a−m_p)/(m_p+1)、软阈值 k=0.5、双硬门控、PBC=10、坐标/行序/细胞数/组成冻结)之上,加**唯一结构改动**:位移前对锚阶段表达矩阵做空间平滑(复刻节点 23/26 配方):--1. 在锚坐标(输出的同一份坐标)上建 15-NN 图(cKDTree,去自身);-2. 两步扩散 `Xc ← (1−ε)·Xc + ε·mean(15 邻居)`,ε=0.4;**支撑掩码**:原矩阵为 0 的位置逐步强制回 0(零模式逐位保留,只有实测正值移动);-3. 逐基因单列缩放 `c_g = pb_orig_g / pb_smooth_g`,精确复原全局伪批量(实测最大相对差 0.0 < 1e-6)。--速度估计器、门控的 dp/dt_approx 都用**未平滑的原始**两阶段矩阵(保伪批量,使 DE/mmd 证据与节点 27 直接可比);位移作用于平滑后底物 `x′ = x_smoothed·2^(α·v̂_t)`;γ 再闭合拉向平滑后细胞自身线性总量;PBC 界 = 10 × median(**原始**输入总量),全部现场计算。回退:单输入/锚≠末输入 → 平滑与速度一并关闭,逐位 copy_last(同父节点)。--提交配置:steps=2, ε=0.4, k_NN=15, α=1, k_soft=0.5, γ=0.3, PBC=10, MIXMODE=rel, MIXREL=1, MIXEPS=1。--## 机制生效证据(PLAN mechanism_evidence 逐条)--- (a) 平滑生效:平滑前后逐基因伪批量最大相对差 0.0(<1e-6);零模式逐位不变(数组比较 True);坐标 15-NN 图上 Dirichlet 能量 35.34 → 30.82(−12.8%);100% 正值条目被改动;列缩放中位 2.36×。-- (b) 目标指标(proxy_noscale A 半,提交配置):**neighborhood_mmd raw 0.07896 ≤ 0.0800**(节点 27 为 0.08123,超过节点 26 的 0.07958,全树最好);**variogram raw 0.03872 ≤ 0.0388**(节点 27 为 0.03877,rel 速度下唯一变差的指标被修复)。-- (c) 保持项:**de_direction 0.2864 ≥ 0.26**(父 0.2776);**mmd_u 0.04763 ≤ 0.0530**(父 0.05158,全树最好);de_score 0.1806(父 0.1528)。-- (d) 组分:local_spatial 59.20(父 58.12,+1.08)、cell_state 57.74(父 56.57,+1.17)、expression_change 56.85(父 56.25,+0.60,不降反升)、shape_scale 50.00 不变(坐标冻结)。榜分 55.95(父 55.23)。-- (e) 平台:γ∈{0, 0.2, 0.3, 0.4} → 56.00/55.85/55.95/55.85(平坦,全部高于父);ε∈{0.3, 0.4}(γ=0.5)→ 55.82/55.78;提交点取 γ 平台内部、ε 平台内部,非刀尖。--## 查分记录(16 次,全部 proxy_noscale,A 半)--| ε | γ | k_soft | 榜分 | nb_mmd | variogram | mmd_u | de_dir | de_score |-|---|---|---|---:|---:|---:|---:|---:|---:|-| – (父节点27) | 0.75 | 0.5 | 55.23 | 0.08123 | 0.03877 | 0.05158 | 0.2776 | 0.1528 |-| 0.6 | 0.75 | 0.5 | 54.74 | 0.08766 | 0.03613 | 0.05768 | 0.2571 | 0.1667 |-| 0.6 | 0.5 | 0.5 | 55.06 | 0.08571 | 0.03630 | 0.05521 | 0.2564 | 0.1806 |-| 0.6 | 0.6 | 0.5 | 54.92 | 0.08631 | 0.03624 | 0.05598 | 0.2571 | 0.1667 |-| 0.6 | 0.9 | 0.5 | 54.51 | 0.08990 | 0.03596 | 0.06035 | 0.2543 | 0.1806 |-| 0.4 | 0.5 | 0.5 | 55.78 | 0.07959 | 0.03823 | 0.04911 | 0.2855 | 0.1667 |-| 0.4 | 0.75 | 0.5 | 55.46 | 0.08184 | 0.03730 | 0.05274 | 0.2831 | 0.1667 |-| 0.2 | 0.5 | 0.5 | 55.52 | 0.07959 | 0.04046 | 0.04856 | 0.2810 | 0.1389 |-| 0.3 | 0.5 | 0.5 | 55.82 | 0.07904 | 0.03938 | 0.04852 | 0.2836 | 0.1806 |-| 0.5 | 0.5 | 0.5 | 55.49 | 0.08158 | 0.03710 | 0.05094 | 0.2688 | 0.1528 |-| 0.4 | 0.4 | 0.5 | 55.85 | 0.07920 | 0.03849 | 0.04827 | 0.2860 | 0.1667 |-| 0.4 | 0.5 | 0.7 | 55.51 | 0.08150 | 0.03751 | 0.05219 | 0.2852 | 0.1667 |-| **0.4** | **0.3** | **0.5** | **55.95** | **0.07896** | **0.03872** | **0.04763** | **0.2864** | **0.1806** |-| 0.4 | 0.2 | 0.5 | 55.85 | 0.07882 | 0.03894 | 0.04713 | 0.2845 | 0.1528 |-| 0.4 | 0.0 | 0.5 | 56.00 | 0.07871 | 0.03931 | 0.04640 | 0.2855 | 0.1806 |-| 0.3 | 0.3 | 0.5 | 55.86 | 0.07852 | 0.04005 | 0.04689 | 0.2845 | 0.1667 |--读数:PLAN 初值 ε=0.6 使 neighborhood_mmd 变差(0.0857–0.0899 > 父 0.0812)——此时列缩放中位 4.35×、PBC 钳制 37% 细胞,平滑过强把与坐标配套的型内差异抹掉再放大;按 PLAN 步骤 (4) 重扫 ε 后,ε∈{0.3, 0.4}(列缩放 ~2.4×)同时改善 nb_mmd、variogram、mmd_u、de_direction、de_score。γ 的最优随平滑移动(父 0.75 → 提交 0.3,父 ANALYSIS lesson 3 再次成立)。选 γ=0.3 而非 γ=0:差 0.05 分远在噪声内,γ=0 在平台边界且会移除父系验证过的 CP10k 再闭合不变量修复;γ=0.3 在 [0, 0.4] 平台内部且恰好满足 PLAN variogram 目标。--## 对照验证(数组级)--- **SMOOTH_STEPS=0 + GAMMA=0.75**(其余同父):输出与节点 27 预测**逐位一致**(`.X` 与坐标 array_equal True)——平滑模块关闭即父节点。-- SMOOTH_STEPS=0 + 提交 γ=0.3:输出与提交配置不同(平滑确实在运行)。-- `--ablate mechanism`:α=0 且平滑不执行,输出 = 锚阶段原样(copy_last,X 逐位一致;坐标经 write_t2 float32 舍入 ~1e-5,与父节点管线的舍入相同)。-- 确定性:seed 0/1/2 输出逐位相同(锚 n=24826 ≤ max_cells,分层 take 返回全部行)。-- 伪装视图安全:无绝对时间、无阶段名、无视图判断;NN 图、列缩放、速度、门控、PBC 界全部从输入现场计算。+几何均值总量比均匀线性缩放替代逐细胞线性总量回拉(γ=0.45):log 域近似恒定每细胞偏移,保住位移的跨基因 dp 排序;PLAN 的速度表达水平回归经 6 配置查分证否后按备选机制路径提交。++# 节点 31(improve,父 = 节点 29,proxy_noscale A 半 56.23)++## 实际提交的方法族与机制++- family_id: T2HX-01(copy_last 基座上的按型速度乘法外推),底物/门控/坐标冻结全部承自节点 29。+- **提交机制:几何均值再闭合(geometric re-closure)**,`VEC_RECLOSE_GEO=1`(默认)、`VEC_GAMMA=0.45`(默认)。+ 节点 24 以来的 γ 再闭合把每个位移后细胞的**线性总量**拉回其自身平滑后总量:由于拉回是逐细胞线性缩放,+ 高表达基因以加性 log 偏移吸收、低表达基因以乘性方式吸收,**跨基因 dp 排序被扭曲**(实测再闭合后+ spearman(dp, dt_approx) 从 0.57 掉到 0.39)。几何变体改为施加统一线性缩放+ `s_i = (r_med / r_i)^γ`(`r_i = tot_new_i / tot_old_i`,r_med = 全体中位数):log1p 域大值每细胞近似+ 平移同一常数,位移的基因排序大部分保留(γ=0.3 时 spearman_post 0.4624 > 父 0.3941),同时位移后线性+ 总量中位数仍落回未位移中位数(实测阶段的库容量不变量在中位数意义上保持)。零保持零、稀疏模式/坐标/+ 行序/细胞数/组成全部不变;PBC=10、软阈值 k=0.5、门控、平滑 ε=0.4 底物均不变。++## PLAN 机制(速度表达水平回归)——已证否++PLAN 要求逐型把 v_t 对锚阶段 log1p 表达水平 OLS 回归取残差(std 复原)以改善 de_score。已按 PLAN 实现+(`VEC_VEL_REGRESS`/`VEC_REGRESS_MODE`/`VEC_REGRESS_W`/`VEC_REGRESS_KEEPMEAN`,代码保留、默认关),+离线诊断:33 个细胞型中 28 型 R² < 0.05(PLAN 风险 1 的放弃线),仅 Forebrain 0.12 / Hindgut 0.095 /+Unknown 0.095 / Neural Tube 0.083 有可去趋势;回归前后速度 Spearman 0.92–1.00。6 次查分(≥3 种幅度组合、+共 20 次查分额度用满)de_score 全部低于父节点 0.1944,PLAN 首查目标 ≥0.20 未达成,de_direction 监控线+0.28 大多被击穿 → 按 improve 规则转备选机制(下表 #1–#6)。++**结论(供后续节点)**:速度与表达水平的共线分量携带真实 DE 信号而非纯 chance 伪影——去水平化+(回归残差、加性解码)一律降 de_score/de_direction;#11 的支撑掩码加性解码(level-free dp)使+de_direction 塌到 0.046,是本方向最强的证否证据。++## 全部 20 次查分(proxy_noscale A 半;父 = 56.23:de_score 0.1944 / de_dir 0.2837 / mmd_u 0.04669 / vario 0.03795 / nb_mmd 0.07569)++| # | 配置 | 榜分 | de_score | de_dir | mmd_u | vario | nb_mmd |+|---|---|---:|---:|---:|---:|---:|---:|+| 1 | 回归 type w=1 | 55.86 | 0.1806 | 0.2638 | 0.04562 | 0.03991 | 0.07936 |+| 2 | 回归 global w=1 | 55.84 | 0.1667 | 0.2523 | 0.04692 | 0.03875 | 0.07828 |+| 3 | 回归 type w=0.5 | 55.88 | 0.1806 | 0.2716 | 0.04655 | 0.03949 | 0.07921 |+| 4 | 回归 type w=−0.5(反向放大) | 55.81 | 0.1528 | 0.2758 | 0.04881 | 0.03773 | 0.07881 |+| 5 | 回归 type w=1 保均值 | 55.79 | 0.1806 | 0.2538 | 0.04610 | 0.04011 | 0.07917 |+| 6 | 回归 global w=0.5 | 55.87 | 0.1667 | 0.2703 | 0.04727 | 0.03874 | 0.07861 |+| 7 | 收缩 N0=150 | 55.63 | 0.1667 | 0.2839 | 0.04649 | 0.04124 | 0.08069 |+| 8 | 收缩 N0=30 | 55.88 | 0.1667 | 0.2888 | 0.04704 | 0.03938 | 0.07912 |+| 9 | 收缩 N0=50 | 55.91 | 0.1806 | 0.2908 | 0.04683 | 0.03974 | 0.07935 |+| 10 | 收缩 N0=400 | 54.89 | 0.1528 | 0.2187 | 0.04704 | 0.04380 | 0.08328 |+| 11 | 加性解码 α=0.5(支撑掩码) | 50.81 | −0.0139 | 0.0462 | 0.05509 | 0.05929 | 0.10479 |+| 12 | 幅度分层 q40/1.15/0.55(移植节点30) | 55.87 | 0.1806 | 0.2869 | 0.05019 | 0.03644 | 0.08029 |+| 13 | 幅度分层 q40/1.3/0.4 | 55.69 | 0.1667 | 0.2821 | 0.05148 | 0.03581 | 0.08128 |+| 14 | 线性再闭合基准=原始总量 | 55.76 | 0.1667 | 0.2678 | 0.04894 | 0.03834 | 0.07897 |+| 15 | 非对称 AUP1.15/ADN0.85 | 55.83 | 0.1528 | 0.2954 | 0.05049 | 0.03565 | 0.08044 |+| 16 | 非对称 AUP0.85/ADN1.15 | 55.24 | 0.1389 | 0.2491 | 0.04694 | 0.04294 | 0.08049 |+| 17 | 速度空间扩散 w=0.5 k=15 | 55.80 | 0.1667 | 0.2811 | 0.04566 | 0.04121 | 0.07907 |+| 18 | **几何再闭合 γ=0.3** | 56.18 | 0.1944 | 0.3132 | 0.04564 | 0.03949 | 0.07906 |+| 19 | **几何再闭合 γ=0.45(提交)** | **56.33** | **0.2222** | **0.3215** | **0.04542** | 0.03954 | 0.07932 |+| 20 | 几何再闭合 γ=0.15 | 56.07 | 0.1806 | 0.2999 | 0.04597 | 0.03941 | 0.07885 |++备选机制族(#7–#17):全局速度收缩(4 档幅度)、加性解码、幅度分层(2 档)、再闭合基准、方向非对称+(2 档)、速度空间扩散——全部 ≤ 55.91。几何再闭合是唯一超过父节点的机制(#18–#20,γ 单调上升)。++## 提交配置的分组变化(#19 vs 父)++- expression_change(父最弱组,57.02)→ **58.15**:de_score 0.1944→0.2222(+2 个量化步,全树最佳,+ 超过 PLAN 首查目标 0.20);de_direction 0.2837→0.3215(全树最佳,连续量、远超以往配置 ±0.01 的抖动)。+- cell_state 58.06 → 58.07:mmd_u 0.04669→0.04542(全树最佳),variogram 0.03795→0.03954(略差)。+- local_spatial 59.83 → 59.09:nb_mmd 0.07569→0.07932(唯一恶化项,−0.74 分,被表达组 +1.13 覆盖)。+- shape_scale 50.00 不变(proxy_noscale 固定 + 坐标冻结)。+- 总分 56.23 → 56.33(+0.10,在 ~1 分噪声内;但机制级证据是结构性的:dp 排序保持度 spearman_post+ 0.39→0.46,两个 DE 指标同创树内最佳且方向一致,非单指标尖峰)。++## 机制生效证据与对照++- 机制改变的细胞:全部 24,826 个锚细胞的表达被位移(moved_frac=1.0),几何再闭合改变其中每个细胞的+ 缩放因子(与线性再闭合逐细胞不同);坐标/行序/细胞数/零模式逐位不变(数组级验证)。+- 关闭对照:`--ablate <任意名>`(含 harness 将传入的 `VEC_VEL_REGRESS`,未识别名按主要机制=几何再闭合+ 处理)或 `VEC_RECLOSE_GEO=0` → 回到同 γ=0.45 的线性再闭合,输出与主运行不同(mechanism_active 可判)。+- `VEC_GAMMA=0.3 VEC_RECLOSE_GEO=0` 时输出与父节点 29 逐位一致(X 与坐标 array_equal=True,已验证);+ 回归/收缩/分层/扩散/加性解码全部默认关,默认输出 = #19 查分文件逐位一致(已验证)。 ## 验证过 / 未验证 -- 验证过:proxy_noscale A 半上的全部上表配置;平滑的伪批量复原、零模式、能量下降;平滑关 = 节点 27 逐位;ablate = copy_last;三种子确定。-- 未验证:B 半与真实 E10.5 外推(本榜本地尺子已知高估,历史 54.2→官网 49.6;判据按 PLAN 用指标级 raw——nb_mmd/variogram/mmd_u/de_direction 四项全部同向改善且超父节点,而非总分 +0.72);ε 在 (0.4, 0.6) 之间更细的网格;插值榜上的可迁移性。-- 运行时:CPU ~3 s,峰值内存 ~1.5 GB(EXECUTION.json gpu:false)。+- 已验证:默认输出逐位 = 已查分的 #19;seed 0/1/2 逐位一致(锚 24,826 ≤ max_cells 25,179,分层 take+ 返回全部行,机制无随机性);伪装视图(时间统一 +1、manifest 键序打乱、路径更换)输出逐位一致;+ vec-check 通过(主运行与 --ablate);运行 ~3s / <2GB(limits 30min/28GB 内);EXECUTION.json gpu:false。+- 未验证:γ>0.45(0.6/0.75)——γ 扫描在测试范围内单调上升,0.45 是已测最大值而非内点最优,额度用尽+ 无法外探,**后续节点可先试 γ=0.6**;B 半与官网外推榜的迁移(本地外推尺子已知高估,历史 54.2→49.6,+ +0.10 的总分差不可外推,但 de_score/de_direction/mmd_u 三项 raw 同向创树内最佳是更可信的信号);+ nb_mmd −0.0036 的代价在真实括号上是否更大。+- 单输入阶段/锚≠末输入退路同父:平滑与速度一并关闭,逐位 copy_last。 ## 知识来源 -无外部生物学知识:平滑、速度估计、门控均为纯算法部件,所有统计量(NN 图、型内均值、列缩放、总量中位数)从视图输入现场计算。未使用任何保留阶段/保留基因型的测量值。+无生物学先验知识被使用(sources=[]):本节点全部改动为算法级(再闭合的缩放几何),只依赖输入数据现场+计算的量(各细胞总量、中位总量比),不含任何由已发布阶段测量值硬编码的常数。++## 旋钮(默认 = 提交配置)++`VEC_RECLOSE_GEO`(1)、`VEC_GAMMA`(0.45);继承:`VEC_SMOOTH_STEPS`(2)、`VEC_SMOOTH_EPS`(0.4)、+`VEC_SMOOTH_K`(15)、`VEC_ALPHA`(1.0)、`VEC_K`(0.5)、`VEC_PBC`(10)、`VEC_MIXMODE`(rel)、+`VEC_MIXREL`(1.0)、`VEC_MIXEPS`(1.0)、`VEC_GATE_SPEARMAN`(0.3);已证否机制保留可复用:+`VEC_VEL_REGRESS`(0)、`VEC_REGRESS_MODE/W/KEEPMEAN/MINGENES`、`VEC_SHRINK_N0`(0)、`VEC_SHRINK_MODE`、+`VEC_DECODE`(mult)、`VEC_STRAT_Q`(0)/`UP`/`DN`、`VEC_VDIFF_W`(0)/`K`、`VEC_RECLOSE_REF`(smoothed)、+`VEC_AUP/ADN`(1.0)、`VEC_DEBUG`。diff --git a/solution/README.md b/solution/README.mdindex 01b140b..140a710 100644--- a/solution/README.md+++ b/solution/README.md@@ -1,8 +1,20 @@-# 空间平滑底物 + rel 速度乘法外推(T2:heart:val_extrap,T2HX-01,节点29)+# 几何均值再闭合 + 空间平滑底物 rel 速度乘法外推(T2:heart:val_extrap,T2HX-01,节点31) -copy_last 基座(坐标/行序/细胞数/组成冻结)上:锚阶段表达先在**坐标 15-NN 图上做两步支撑掩码扩散平滑**(ε=0.4,零模式逐位保留,逐基因列缩放精确复原伪批量,节点23/26 配方),再按共有细胞型的相对差速度 v_t=(m_a−m_p)/(m_p+1)(m=**未平滑**原始型内均值 log1p)做乘法位移 x′=x_smoothed·2^(α·v̂_t)(α=1,k=0.5 MAD 软阈值);门控(std 比 ≥0.01、spearman ≥0.3,dp 对原始锚伪批量)通过后按 γ=0.3 把每细胞线性总量拉回其平滑后自身总量,PBC=10×median(原始总量) 钳亮尾。单输入/锚≠末输入/`--ablate` 时逐位回退 copy_last(平滑也关闭)。+copy_last 基座(坐标/行序/细胞数/组成冻结)承自节点 29:锚阶段表达先在坐标 15-NN 图上做两步支撑掩码+扩散平滑(ε=0.4,零模式逐位保留,逐基因列缩放复原伪批量),再按共有细胞型的相对差速度+v_t=(m_a−m_p)/(m_p+1) 做乘法位移 x′=x_smoothed·2^(α·v̂_t)(α=1,k=0.5 MAD 软阈值),门控+(std 比 ≥0.01、spearman ≥0.3)通过后做再闭合与 PBC=10 钳亮尾。 -- 运行:`python run.py --data <view> --out <pred.h5ad> --seed <int>`;CPU ~3s、~1.5GB(`EXECUTION.json gpu:false`)。-- 旋钮(默认=提交配置):`VEC_SMOOTH_STEPS`(2)、`VEC_SMOOTH_EPS`(0.4)、`VEC_SMOOTH_K`(15)、`VEC_ALPHA`(1.0)、`VEC_K`(0.5)、`VEC_GAMMA`(0.3)、`VEC_PBC`(10.0)、`VEC_MIXMODE`(rel)、`VEC_MIXREL`(1.0)、`VEC_MIXEPS`(1.0)、`VEC_GATE_SPEARMAN`(0.3)、`VEC_DEBUG`。-- 对照:`VEC_SMOOTH_STEPS=0 VEC_GAMMA=0.75` 输出逐位 = 节点27。-- proxy_noscale A 半 **55.95**(父节点27 = 55.23);nb_mmd 0.07896、variogram 0.03872、mmd_u 0.04763、de_direction 0.2864 全部优于父节点。16 次查分记录见 METHOD.md。+**节点 31 改动**:γ 再闭合从"逐细胞线性总量回拉"换成**几何均值总量比的统一线性缩放**+`s_i=(r_med/r_i)^γ`,γ=0.45(0.15/0.3/0.45 单调扫描的已测最大值)。线性回拉按表达水平不均地吸收+缩放、扭曲跨基因 dp 排序(spearman_post 0.39);几何缩放在 log 域近似每细胞恒定偏移,保住位移的+基因排序(spearman_post 0.46)。proxy_noscale A 半 56.33(父 56.23):de_score 0.2222、+de_direction 0.3215、mmd_u 0.04542 均创树内最佳,nb_mmd 0.07932 略差于父 0.07569。++- 运行:`python run.py --data <view> --out <pred.h5ad> --seed <int>`;CPU ~3s、<2GB(`EXECUTION.json gpu:false`)。+- 关闭对照:`--ablate <任意名>` 或 `VEC_RECLOSE_GEO=0` → 同 γ 的线性再闭合;+ `VEC_GAMMA=0.3 VEC_RECLOSE_GEO=0` → 输出逐位 = 节点 29。+- 已证否(默认关,代码保留):速度表达水平回归(PLAN,6 配置全降 de_score)、全局速度收缩、+ 加性解码、幅度分层移植、方向非对称、速度空间扩散、原始总量再闭合基准——20 次查分明细见 METHOD.md。+- 确定性:seed 0/1/2 逐位一致;伪装视图(时间平移/键序打乱/换路径)逐位一致;单输入/锚≠末输入退路+ 逐位 copy_last。diff --git a/solution/run.py b/solution/run.pyindex f727353..db1c01f 100644--- a/solution/run.py+++ b/solution/run.py@@ -24,8 +24,9 @@ Mechanism (on by default, alpha = 1.0): Coordinates, row order and cell count are never modified. ---ablate <name> (any name) turns the mechanism off: output is bit-for-bit-copy_last (same anchor stage, same rows, same coordinates).+--ablate <name> (any name) turns THIS node's mechanism (the geometric-mean+re-closure, see (6) below) off and keeps the rest of the pipeline+unchanged (linear re-closure at the submitted gamma). Node 24 additions on top of node 21: @@ -67,6 +68,54 @@ Node 25 addition on top of node 24 (the submitted mechanism): de_direction 0.208 -> 0.228, variogram 0.0419 -> 0.0387, mmd_u 0.0575 -> 0.0566, neighborhood_mmd 0.0847 -> 0.0849 (flat). +Node 31 addition on top of node 29 (the submitted mechanism):++(6) Geometric-mean re-closure (VEC_RECLOSE_GEO, default 1; VEC_GAMMA+ default 0.45). The node-24 linear-total re-closure pulls each shifted+ cell's LINEAR total back toward its own smoothed total; because the+ pull-back is a per-cell linear scale, bright genes absorb it as an+ additive log shift while dim genes absorb it multiplicatively, which+ distorts the cross-gene dp ranking (spearman(dp, dt_approx) after+ re-closure 0.39 vs 0.57 before, measured). The geometric variant+ applies instead a uniform linear scale s_i = (r_med / r_i)**gamma with+ r_i = tot_new_i/tot_old_i: large log1p entries shift by an almost+ constant per-cell amount, the gene ranking of the displacement largely+ survives (spearman_post 0.46 at gamma=0.3), and the shifted linear+ total median still lands at the unshifted median (library-size+ invariant of measured stages preserved in the median). Zeros stay+ zero, sparsity pattern and coordinates untouched. Proxy A-half+ (20 queries): gamma 0.15/0.3/0.45 -> 56.07/56.18/56.33 vs node-29+ parent 56.23; at gamma=0.45 de_score 0.2222 (tree best, parent+ 0.1944), de_direction 0.3215 (parent 0.2837), mmd_u 0.04542 (parent+ 0.04669); nb_mmd 0.07932 slightly worse (parent 0.07569). gamma=0.45+ is the tested maximum of a monotone sweep (quota exhausted before+ 0.6 could be probed).++ Off-control: VEC_RECLOSE_GEO=0 or --ablate <any> reverts ONLY the+ re-closure to the parent's linear-total pull-back at the same gamma;+ VEC_VEL_REGRESS/VEC_SHRINK_N0/VEC_STRAT_Q/VEC_VDIFF_W/VEC_DECODE=add+ are all off by default (falsified alternatives, kept for reuse).+ With --ablate the pipeline is node 29 except gamma=0.45 in the linear+ re-closure.++ FALSIFIED (do not retry): (a) the PLAN's velocity expression-level+ regression (per-type/global OLS residual of v_t on anchor log1p+ pseudobulk, std-rescaled, 6 scored configs incl. w=0.5/1/-0.5 and+ keep-mean): de_score 0.1528-0.1806 < parent 0.1944 in ALL configs --+ measured per-type R^2 is 0.00-0.12, and the level-covariant part of+ the velocity carries real de signal, not just chance-corrected+ artefact. (b) support-masked additive decode in log1p space (level-free+ dp): de_direction collapses to 0.046 -- dp's level coupling is+ signal, not artefact. (c) shrinkage of per-type velocity toward the+ global pseudobulk velocity (N0 30-400): de_direction up to 0.2908 but+ nb_mmd/mmd_u down, total <= 55.91. (d) node-30 magnitude+ stratification ported onto this base: 55.87/55.69. (e) asymmetric+ AUP/ADN: best de_direction 0.2954 + best variogram 0.03565 at+ AUP1.15/ADN0.85 but de_score 0.1528, total 55.83. (f) spatial+ velocity diffusion on coordinate 15-NN: best mmd_u 0.04566 but+ nb_mmd 0.0791, total 55.80. (g) linear re-closure toward ORIGINAL+ (pre-smoothing) totals: 55.76.+ Node 29 addition on top of node 27 (the submitted mechanism): (5) Spatial support-masked diffusion smoothing of the anchor substrate@@ -128,9 +177,12 @@ Gates (std(dp) >= 0.01 * std(dt_approx), spearman(dp, dt_approx) >= 0.3) are computed on the PRE-renormalisation shift, exactly as in node 21, so the re-closure and clamp steps can never be blocked by them. -Experiment knobs (defaults = submitted configuration): VEC_SMOOTH_STEPS (2),+Experiment knobs (defaults = submitted configuration): VEC_VEL_REGRESS (1),+VEC_REGRESS_MODE (type), VEC_REGRESS_W (1.0), VEC_REGRESS_MINGENES (50),+VEC_SMOOTH_STEPS (2), VEC_SMOOTH_EPS (0.4), VEC_SMOOTH_K (15), VEC_ALPHA (1.0),-VEC_C (0.0 = pure multiplicative), VEC_K (0.5), VEC_GAMMA (0.3),+VEC_C (0.0 = pure multiplicative), VEC_K (0.5), VEC_GAMMA (0.45),+VEC_RECLOSE_GEO (1), VEC_PBC (10.0), VEC_MIXMODE (rel), VEC_MIXREL (1.0), VEC_MIXEPS (1.0), VEC_DOMAIN (log), VEC_SOFTD (0), VEC_CAPD (0), VEC_CVEL (-1 = legacy max(c,1)), VEC_VMEAN (log; used only in est mode), VEC_WMIX (0.0),@@ -158,7 +210,7 @@ from src.task2_spatial.view_io import ( ALPHA = float(os.environ.get("VEC_ALPHA", "1.0")) PSEUDOCOUNT = float(os.environ.get("VEC_C", "0.0")) SOFT_K = float(os.environ.get("VEC_K", "0.5"))-GAMMA = float(os.environ.get("VEC_GAMMA", "0.3"))+GAMMA = float(os.environ.get("VEC_GAMMA", "0.45")) DOMAIN = os.environ.get("VEC_DOMAIN", "log") # "log" (node 24) or "lin" (node 25) CAPD = float(os.environ.get("VEC_CAPD", "0.0")) # hard log-domain displacement cap (0 = off) SOFTD = float(os.environ.get("VEC_SOFTD", "0.0")) # soft (tanh) displacement knee, log1p units (0 = off)@@ -172,6 +224,21 @@ AUP = float(os.environ.get("VEC_AUP", "1.0")) # exponent multiplier for v>0 gen ADN = float(os.environ.get("VEC_ADN", "1.0")) # exponent multiplier for v<0 genes PBC = float(os.environ.get("VEC_PBC", "10.0")) # post-brightness clamp: max total / median original total (0 = off) GATE_SPEARMAN = float(os.environ.get("VEC_GATE_SPEARMAN", "0.3"))+VEL_REGRESS = os.environ.get("VEC_VEL_REGRESS", "0") not in ("0", "", "false", "False")+SHRINK_N0 = float(os.environ.get("VEC_SHRINK_N0", "0")) # shrinkage pseudo-count (0 = off, output = node 29)+SHRINK_MODE = os.environ.get("VEC_SHRINK_MODE", "min") # n_eff = "min"(n_a,n_b) or "prod" sqrt(n_a*n_b)+DECODE = os.environ.get("VEC_DECODE", "mult") # "mult" (parent) or "add": support-masked additive in log1p space+STRAT_Q = float(os.environ.get("VEC_STRAT_Q", "0.0")) # magnitude-stratification: top-|A*v| fraction boosted (0 = off)+STRAT_UP = float(os.environ.get("VEC_STRAT_UP", "1.15")) # multiplier for the top fraction+STRAT_DN = float(os.environ.get("VEC_STRAT_DN", "0.55")) # multiplier for the rest+RECLOSE_REF = os.environ.get("VEC_RECLOSE_REF", "smoothed") # gamma re-closure target totals: "smoothed" (parent) or "original" (pre-smoothing anchor totals)+RECLOSE_GEO = os.environ.get("VEC_RECLOSE_GEO", "1") not in ("0", "", "false", "False") # re-close toward the geometric-mean total ratio (uniform linear scale, log-domain library-size invariant)+VDIFF_W = float(os.environ.get("VEC_VDIFF_W", "0.0")) # spatial velocity diffusion weight (0 = off)+VDIFF_K = int(os.environ.get("VEC_VDIFF_K", "15")) # coordinate neighbours for the velocity diffusion+REGRESS_MODE = os.environ.get("VEC_REGRESS_MODE", "type") # "type" (per-type OLS) or "global" (pooled slope)+REGRESS_W = float(os.environ.get("VEC_REGRESS_W", "1.0")) # blend weight of the residual velocity (1 = pure residual)+REGRESS_MINGENES = int(os.environ.get("VEC_REGRESS_MINGENES", "50")) # types with fewer positive-pb genes skip regression+REGRESS_KEEPMEAN = os.environ.get("VEC_REGRESS_KEEPMEAN", "0") not in ("0", "", "false", "False") # re-add mean(v_t) to the rescaled residual SMOOTH_STEPS = int(os.environ.get("VEC_SMOOTH_STEPS", "2")) SMOOTH_EPS = float(os.environ.get("VEC_SMOOTH_EPS", "0.4")) SMOOTH_K = int(os.environ.get("VEC_SMOOTH_K", "15"))@@ -246,24 +313,36 @@ def spatial_smooth(Xa: np.ndarray, coords: np.ndarray, steps: int, eps: float, return Xs, info +def _ols_residual(v: np.ndarray, x: np.ndarray, coef: np.ndarray | None) -> tuple[np.ndarray, np.ndarray, float]:+ """OLS of v on [1, x]; returns (residual, coef, r2). coef=None -> fit."""+ A = np.vstack([np.ones_like(x), x]).T+ if coef is None:+ coef, *_ = np.linalg.lstsq(A, v, rcond=None)+ resid = v - A @ coef+ ss_tot = float(((v - v.mean()) ** 2).sum())+ r2 = 1.0 - float((resid ** 2).sum()) / ss_tot if ss_tot > 0 else 0.0+ return resid, coef, r2++ def type_velocity(Xa: np.ndarray, la: np.ndarray, Xb: np.ndarray, lb: np.ndarray,- c: float, k: float) -> tuple[np.ndarray, list]:+ c: float, k: float, regress: bool, shrink: bool) -> tuple[np.ndarray, list]: """Per-cell log2-domain pseudobulk fold-change velocity for anchor cells.""" V = np.zeros_like(Xa) types_a = np.asarray(la).astype(str) types_b = np.asarray(lb).astype(str) per_type = []+ raw: dict[str, tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]] = {} for t in sorted(set(types_a.tolist())): ia = np.flatnonzero(types_a == t) ib = np.flatnonzero(types_b == t) if len(ib) == 0:- per_type.append((t, len(ia), 0, 0.0, 0.0))+ per_type.append((t, len(ia), 0, 0.0, 0.0, None)) continue+ pb_a = Xa[ia].mean(axis=0) if MIXMODE == "rel": # PLAN literal mix: dimensionless displacement between the arith # log2 fold-change of the pseudobulks and the relative arithmetic # difference (pb_a - pb_p)/(pb_p + eps).- pb_a = Xa[ia].mean(axis=0) pb_p = Xb[ib].mean(axis=0) v_arith = np.log2(pb_a + c) - np.log2(pb_p + c) v_rel = (pb_a - pb_p) / (pb_p + MIXEPS)@@ -273,12 +352,85 @@ def type_velocity(Xa: np.ndarray, la: np.ndarray, Xb: np.ndarray, lb: np.ndarray # the arith log2-of-mean (pseudobulk fold-change) velocity. # WMIX = 0 is bit-for-bit the legacy estimator, WMIX = 1 pure arith. v_log = np.log2(Xa[ia] + c).mean(axis=0) - np.log2(Xb[ib] + c).mean(axis=0)- v_arith = np.log2(Xa[ia].mean(axis=0) + c) - np.log2(Xb[ib].mean(axis=0) + c)+ v_arith = np.log2(pb_a + c) - np.log2(Xb[ib].mean(axis=0) + c) w = 1.0 if VMEAN == "arith" else WMIX v_t = (1.0 - w) * v_log + w * v_arith+ raw[t] = (ia, ib, pb_a, v_t)++ # Alternative mechanism (node 31, submitted): shrink each type's velocity+ # toward the GLOBAL (all-cell) pseudobulk velocity with weight+ # s_t = n_eff/(n_eff + N0), n_eff = min(n_a, n_b) (SHRINK_MODE=prod:+ # sqrt(n_a*n_b)). Types measured with few cells in either stage have noisy+ # per-type velocities; the global velocity is estimated from all cells and+ # carries the coherent direction of change. N0 = 0 -> s_t = 1 -> identity+ # (bit-for-bit node 29). Types absent from prev keep v = 0 (parent+ # behaviour: no evidence, no displacement).+ if shrink:+ pb_a_all = Xa.mean(axis=0)+ pb_p_all = Xb.mean(axis=0)+ if MIXMODE == "rel":+ v_arith_g = np.log2(pb_a_all + c) - np.log2(pb_p_all + c)+ v_glob = (1.0 - MIXREL) * v_arith_g + MIXREL * (pb_a_all - pb_p_all) / (pb_p_all + MIXEPS)+ else:+ w = 1.0 if VMEAN == "arith" else WMIX+ v_log_g = np.log2(Xa + c).mean(axis=0) - np.log2(Xb + c).mean(axis=0)+ v_arith_g = np.log2(pb_a_all + c) - np.log2(pb_p_all + c)+ v_glob = (1.0 - w) * v_log_g + w * v_arith_g+ shrink_info = []+ for t, (ia, ib, pb_a, v_t) in raw.items():+ n_a, n_b = len(ia), len(ib)+ if SHRINK_MODE == "prod":+ n_eff = float(np.sqrt(n_a * n_b))+ else:+ n_eff = float(min(n_a, n_b))+ s_t = n_eff / (n_eff + SHRINK_N0)+ raw[t] = (ia, ib, pb_a, s_t * v_t + (1.0 - s_t) * v_glob)+ shrink_info.append((t, n_a, n_b, s_t))+ # types in the anchor but absent from prev never enter `raw`; the+ # parent leaves them at v = 0 -- keep that behaviour (V stays 0).+ if DEBUG:+ for t, n_a, n_b, s_t in shrink_info:+ print(f" shrink {t}: n_a={n_a} n_b={n_b} s_t={s_t:.4f}", flush=True)++ # Velocity expression-level regression (node 31). Global mode pools all+ # (gene, type) pairs to fit one slope; type mode fits each type separately.+ coef_global = None+ if regress and REGRESS_MODE == "global" and raw:+ xs = np.concatenate([pb_a for _, _, pb_a, _ in raw.values()])+ vs = np.concatenate([v_t for _, _, _, v_t in raw.values()])+ _, coef_global, _ = _ols_residual(vs, xs, None)+ if DEBUG:+ print(f"regress: mode=global slope={coef_global[1]:+.5f} intercept={coef_global[0]:+.5f}",+ flush=True)++ for t, (ia, ib, pb_a, v_t) in raw.items():+ rinfo = None+ n_pos = int((pb_a > 0).sum())+ if regress and n_pos < REGRESS_MINGENES:+ regress_t = False # PLAN risk 4: too few expressed genes -> skip+ else:+ regress_t = regress+ if regress_t:+ x_reg = pb_a+ if REGRESS_MODE == "global":+ resid, _, r2 = _ols_residual(v_t, x_reg, coef_global)+ else:+ resid, coef_t, r2 = _ols_residual(v_t, x_reg, None)+ sd_v = float(v_t.std())+ sd_r = float(resid.std())+ scale = sd_v / sd_r if sd_r > 1e-12 else 1.0+ v_res = resid * scale+ if REGRESS_KEEPMEAN:+ v_res = v_res + float(v_t.mean())+ v_new = (1.0 - REGRESS_W) * v_t + REGRESS_W * v_res+ from scipy.stats import spearmanr+ sp_pre_post = float(spearmanr(v_t, v_new).statistic)+ rinfo = {"r2": r2, "std_scale": scale, "spearman": sp_pre_post,+ "n_genes": int(v_t.size)}+ v_t = v_new v_t, zeroed = soft_threshold(v_t, k) V[ia] = v_t- per_type.append((t, len(ia), len(ib), float(np.linalg.norm(v_t)), zeroed))+ per_type.append((t, len(ia), len(ib), float(np.linalg.norm(v_t)), zeroed, rinfo)) return V, per_type @@ -290,9 +442,20 @@ def main() -> None: parser.add_argument("--ablate", default=None) args = parser.parse_args() - alpha = 0.0 if args.ablate is not None else ALPHA- pseudocount = PSEUDOCOUNT if args.ablate is None else 0.0- gamma = 0.0 if args.ablate is not None else GAMMA+ alpha = ALPHA+ pseudocount = PSEUDOCOUNT+ gamma = GAMMA+ # Off-control: --ablate <any> (the harness passes the PLAN's+ # VEC_VEL_REGRESS; unrecognised names are treated as the primary+ # mechanism, which for the SUBMITTED configuration is the+ # geometric-mean re-closure) disables regression/shrinkage/velocity+ # diffusion/geo-re-closure; everything else (smoothing, rel velocity,+ # soft threshold, alpha, gamma=0.45 linear re-closure, PBC, gates,+ # frozen coordinates/rows/composition) is untouched.+ regress = VEL_REGRESS and args.ablate is None+ shrink_on = SHRINK_N0 > 0.0 and args.ablate is None+ vdiff_w = VDIFF_W if args.ablate is None else 0.0+ reclose_geo = RECLOSE_GEO and args.ablate is None manifest = load_manifest(args.data) genes = panel_genes(args.data, manifest)@@ -326,7 +489,25 @@ def main() -> None: f"zero_pattern_preserved={sinfo.get('zero_pattern_preserved')} " f"col_scale_med={sinfo.get('col_scale_med', 1.0):.4f}", flush=True) c_vel = pseudocount if pseudocount > 0 else (CVEL if CVEL >= 0 else 1.0)- V, per_type = type_velocity(Xa, stage.labels[rows], Xb, prev.labels, c_vel, SOFT_K)+ V, per_type = type_velocity(Xa, stage.labels[rows], Xb, prev.labels, c_vel, SOFT_K, regress, shrink_on)+ if vdiff_w > 0:+ # Spatial velocity diffusion: blend each cell's type velocity+ # with the mean type velocity over its VDIFF_K nearest+ # COORDINATE neighbours, making the displacement field locally+ # coherent (targets neighborhood_mmd, the heaviest metric).+ from scipy import sparse+ from scipy.spatial import cKDTree+ m = V.shape[0]+ kk = int(min(VDIFF_K, max(m - 1, 1)))+ cpt = np.asarray(coords, dtype=np.float64)[:, :3]+ tree = cKDTree(cpt)+ _, vidx = tree.query(cpt, k=kk + 1)+ vnb = np.atleast_2d(vidx)[:, 1:]+ vrows = np.repeat(np.arange(m), vnb.shape[1])+ Wv = sparse.csr_matrix(+ (np.full(vrows.size, 1.0 / vnb.shape[1]), (vrows, vnb.ravel())),+ shape=(m, m))+ V = (1.0 - vdiff_w) * V + vdiff_w * (Wv @ V) pba = Xa.mean(axis=0) dt_approx = pba - Xb.mean(axis=0) if DOMAIN == "lin":@@ -338,6 +519,41 @@ def main() -> None: Xlin = np.expm1(Xs) * np.power(2.0, np.where(V > 0, alpha * AUP, alpha * ADN) * V) Xp = np.log1p(np.maximum(Xlin, 0.0)) Xraw = Xp+ elif DECODE == "add":+ # Support-masked ADDITIVE decode in log1p space: x' = x + A*v~+ # on positive entries, zeros stay exactly zero (sparsity+ # pattern bit-preserved). dp_gene ~= A*v~ * frac_positive,+ # i.e. the pseudobulk change is (nearly) free of the+ # expression-level factor that the multiplicative-in-log1p+ # decode carries (dp ~ x * (2**v - 1)); de_score's chance+ # correction subtracts exactly the level-driven ranking, so a+ # level-free dp should convert more of the velocity signal+ # into hit rate. Negative shifts that would push x below 0+ # are clipped at 0 (clip_frac monitored in DEBUG).+ A = np.where(V > 0, alpha * AUP, alpha * ADN)+ Xraw = Xs + np.where(Xs > 0, A * V, 0.0)+ Xp = np.maximum(Xraw, 0.0)+ Xp = np.where(Xs > 0, Xp, 0.0)+ elif STRAT_Q > 0:+ # Magnitude-stratified displacement (ported from node 30,+ # proven on the sibling branch): pool all gated (type, gene)+ # velocity entries, rank by |A*v| descending, the top+ # STRAT_Q fraction is boosted (x STRAT_UP) and the rest+ # compressed (x STRAT_DN); a single global factor restores the+ # total displacement magnitude (conservation). Reweights WHICH+ # genes carry the extrapolation without changing the velocity+ # estimator itself.+ A = np.where(V > 0, alpha * AUP, alpha * ADN)+ mag = np.abs(A * V)+ nz = mag > 0+ if nz.any():+ thr = float(np.quantile(mag[nz], 1.0 - STRAT_Q))+ boost = np.where(nz & (mag >= thr), STRAT_UP,+ np.where(nz, STRAT_DN, 1.0))+ f = float(mag[nz].sum() / max((mag * boost)[nz].sum(), 1e-12))+ A = A * boost * f+ Xraw = Xs * np.power(2.0, A * V)+ Xp = np.maximum(Xraw, 0.0) else: A = np.where(V > 0, alpha * AUP, alpha * ADN) if pseudocount > 0:@@ -376,9 +592,12 @@ def main() -> None: f"std(dp)/std(dt_approx)={std_ratio:.4f} " f"clip_frac={clip_frac:.4f} moved_frac={moved:.4f} spearman(dp,dt_approx)={sp:.4f}", flush=True)- for t, na, nb, vn, zfrac in per_type:- print(f" type {t}: n_anchor={na} n_prev={nb} |v_t|={vn:.4f} zeroed_frac={zfrac:.3f}",- flush=True)+ for t, na, nb, vn, zfrac, rinfo in per_type:+ line = f" type {t}: n_anchor={na} n_prev={nb} |v_t|={vn:.4f} zeroed_frac={zfrac:.3f}"+ if rinfo is not None:+ line += (f" regress_r2={rinfo['r2']:.4f} std_scale={rinfo['std_scale']:.3f}"+ f" spear_pre_post={rinfo['spearman']:.4f}")+ print(line, flush=True) if std_ratio < 0.01: if DEBUG: print("DE protection gate: fallback to copy_last", flush=True)@@ -395,18 +614,49 @@ def main() -> None: # gamma (0 = off, 1 = exact re-closure). Zeros stay zero. lin = np.expm1(Xp) tot_new = lin.sum(axis=1, keepdims=True)- tot_old = np.expm1(Xs).sum(axis=1, keepdims=True)- scale = np.power(np.divide(tot_old, np.maximum(tot_new, 1e-12),- out=np.ones_like(tot_new), where=tot_new > 1e-12), gamma)- Xp = np.log1p(lin * scale)- if DEBUG:- r = (tot_new / np.maximum(tot_old, 1e-12)).ravel()- dp2 = Xp.mean(axis=0) - pba- sp2 = float(np.corrcoef(_rank(dp2), _rank(dt_approx))[0, 1])- print(f"renorm: gamma={gamma} shift_tot_ratio median={np.median(r):.4f} "- f"iqr=[{np.percentile(r, 25):.3f},{np.percentile(r, 75):.3f}] "- f"std_ratio_post={np.std(dp2) / (np.std(dt_approx) + 1e-12):.4f} "- f"spearman_post={sp2:.4f}", flush=True)+ if reclose_geo:+ # Geometric-mean re-closure: instead of pulling each+ # cell's LINEAR total back (which distorts the+ # cross-gene dp ranking: bright genes get an additive+ # log shift, dim genes a multiplicative one), apply a+ # uniform linear scale s_i = (r_med/r_i)**gamma with+ # r_i = tot_new/tot_old. In log1p space large entries+ # shift by a constant per cell, so the gene ranking of+ # the displacement survives; the shifted linear-total+ # median lands at the unshifted median.+ tot_old_g = np.expm1(Xs).sum(axis=1, keepdims=True)+ r = tot_new / np.maximum(tot_old_g, 1e-12)+ r_med = float(np.median(r))+ sg = np.power(np.divide(np.full_like(r, r_med), np.maximum(r, 1e-12)), gamma)+ Xp = np.log1p(lin * sg)+ if DEBUG:+ dp2 = Xp.mean(axis=0) - pba+ sp2 = float(np.corrcoef(_rank(dp2), _rank(dt_approx))[0, 1])+ print(f"renorm_geo: gamma={gamma} r_med={r_med:.4f} "+ f"std_ratio_post={np.std(dp2) / (np.std(dt_approx) + 1e-12):.4f} "+ f"spearman_post={sp2:.4f}", flush=True)+ else:+ if RECLOSE_REF == "original":+ # Node-29 ANALYSIS suggestion: pull each shifted cell+ # back toward its OWN ORIGINAL (pre-smoothing) linear+ # total instead of the smoothed one, so the per-cell+ # library-size distribution of the measured anchor+ # stage is preserved exactly (smoothing + column scale+ # conserve only the global pseudobulk).+ tot_old = np.expm1(Xa).sum(axis=1, keepdims=True)+ else:+ tot_old = np.expm1(Xs).sum(axis=1, keepdims=True)+ scale = np.power(np.divide(tot_old, np.maximum(tot_new, 1e-12),+ out=np.ones_like(tot_new), where=tot_new > 1e-12), gamma)+ Xp = np.log1p(lin * scale)+ if DEBUG:+ r = (tot_new / np.maximum(tot_old, 1e-12)).ravel()+ dp2 = Xp.mean(axis=0) - pba+ sp2 = float(np.corrcoef(_rank(dp2), _rank(dt_approx))[0, 1])+ print(f"renorm: gamma={gamma} shift_tot_ratio median={np.median(r):.4f} "+ f"iqr=[{np.percentile(r, 25):.3f},{np.percentile(r, 75):.3f}] "+ f"std_ratio_post={np.std(dp2) / (np.std(dt_approx) + 1e-12):.4f} "+ f"spearman_post={sp2:.4f}", flush=True) if PBC > 0: # Post-brightness clamp: after re-closure, a heavy tail of # cells (types with strongly positive velocity) still carries
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k007 | Interval staging and held-out-window filtering of external data | notes/official/来件/virtualembryo.ai/rules.md |
| k026 | Canonicalise predicted 3D coordinates before submission | notes/pitfalls/04_scorer_invariance.md |
| k024 | World-model evaluation dimensions for state-transition predictors | notes/competition/07_biomedical_world_models.md |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | PLAN 的速度表达水平回归已实现但被证否(6 个配置 de_score 全部低于父 0.1944),实际提交的是备选机制:在节点 29 的平滑底物 + 按型 rel 速度乘法外推之上,把 γ 再闭合从「逐细胞线性总量回拉」换成「几何均值总量比的统一线性缩放 s_i=(r_med/r_i)^γ」,γ 由 0.3 提到 0.45;坐标/行序/细胞数/零模式/门控全部不变。 |
|---|---|
| 各组分数的变化 | cell_state:噪声内偏正:mmd_u raw 0.04669→0.04464(+0.14 分)与 variogram raw 0.03795→0.03880(−0.07 分)反向抵消,组 58.06→58.35(+0.29)。 expression_change:变好,但幅度在总分噪声内:de_score raw 0.1944→0.2361(skill 0.557→0.571,+0.18 分)、de_direction raw 0.2837→0.3213(skill 0.583→0.596,+0.16 分),组 57.02→58.38(+1.36);de_direction 是连续量、超过历史配置 ±0.01 抖动,de_score 涨约 3 个量化步(步长 ~0.0139),两项同向、是全树最佳。 local_spatial:噪声内偏负:neighborhood_mmd raw 0.07569→0.07625(−0.04 分),组 59.83→59.65(−0.18);skill 0.598>0.5,结构门仍为 1,未连带扣形状分。 shape_scale:不变:d2_shape 0.04911、occupancy_dice 0.8066、scale_log_ratio −0.4334 三项 raw 与父逐位相同(坐标冻结),组 50.00→50.00,全部在地板。 |
| family_id | T2HX-01 |
| 假设是否成立 | 否 |
| 经验 |
|
| mechanism_active | 是 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 8 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 9 次:bash 8、write 1 |
| 用时 | 2 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 32,030 · 输出 2,075 · 思考 4,187 |
| 任务(第一行) | 分析节点 n31 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/analyst.jsonl 30 KB /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 71 |
| 工具调用 | 共 72 次:bash 41、edit 27、read 2、write 2 |
| 用时 | 39 分 |
| token 数 | 输入 154,552 · 输出 27,837 · 思考 46,344 |
| 任务(第一行) | 按计划修改程序:速度表达水平回归校正改善DE排序 |
| 最后的回答(摘录) | Final state verified. Session summary: **做了什么**:按 PLAN 实现速度表达水平回归(逐型/全局 OLS 残差、std 复原、幅度混合 w=0.5/1/−0.5、保均值共 6 配置)——离线诊断显示 28/33 型 R²<0.05,6 次查分 de_score 全部低于父节点 0.1944,PLAN 证否。按 improve 规则转备选机制,又测了 5 个族(全局速度收缩 4 档、支撑掩码加性解码、节点30幅度分层移植 2 档、AUP/ADN 非对称 2 档、速度空间扩散、原始总量再闭合基准),全部 ≤55.91。最后发现结构性问题:线性总量 γ 回拉按表达水平不均地吸收缩放、扭曲 dp 排序(spearman_post 0.39),改为**几何均值总量比统一线性缩放**(log 域近似恒定偏移,spearman_post 0.46),γ 扫描 0.15/0.3/0.45 单调上升,提交 γ=0.45。 **查分结果**(20/20 额度用满):提交配置 proxy_noscale A 半 **56.33**(父 56.23);de_score **0.2222**、de_direction **0.3215**、mmd_u **0.04542** 均创全树最佳(表达组 57.02→58.15,为父节点最弱组),代价 nb_mmd 0.07569→0.07932。默认输出逐位=已查分文件;seed 0/1/2、伪装视图逐位一致;`--ablate` 关闭几何再闭合(输出改变,mechanism_active 可判);`VEC_GAMMA=0.3 VEC_RECLOSE_GEO=0` 逐位=父节点;vec-check 通过。 **下一步最值得试**:① γ=0.6/0.75(扫描在 0.45 处仍单调上升,是已测边界非内点最优);② 几何再闭合 × 平滑 ε 重耦合(nb_mmd 是唯一恶化项,ε 微调或许可回收);③ 本机制移植到插值两榜与全胚外推榜验证可迁移性;④ 用 B 半/官网复核——本地外推尺子已知高估,应以下一次官网提交验证 de_score/de_direction 增益是否兑现。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/engineer.jsonl 420 KB /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 12 分 |
| token 数 | 输入 20,849 · 输出 23,094 · 思考 8,192 |
| 任务(第一行) | 为节点 n31(改进,父节点 n29)写改进计划 PLAN.json |
| 最后的回答(摘录) | ✓
- mechanism_off_control ✓
可选:
- sources(不用,因为没有用 lit-search)
好,方案完成。
让我再检查一下合规性:
- 不用禁窗数据 ✓
- 不硬编码统计量 ✓
- 不针对打分器漏洞 ✓(回归校正是改进估计质量,不是利用漏洞)
- 单输入退路 ✓
- 时间和内存可行 ✓(回归是简单操作)
好。
最后,让我确保方案不是"只是调一个参数"。回归校正是一个结构改动(引入了新的处理步骤和公式),不是调参数。
好,我满意这个方案。
输出最终 JSON。
</think>
```json
{
"name": "速度表达水平回归校正改善DE排序",
"motivation": "节点29 expression_change 57.02 是四个非固定组分中最弱(cell_state 58.06、local_spatial 59.83);de_score raw 0.1944(skill 0.557)与 mmd_u 并列最低活跃指标。速度公式 (m_a−m_p)/(m_p+1) 的分母使速度与基因锚阶段表达水平系统性负相关,而 de_score 的 chance 校正恰好减去按 ±pb(ref) 排序的基线——部分本应贡献排序信号的速度方差被当作表达水平伪影扣掉。父节点 ANALYSIS 的 next_suggestions 第2条也指出 de_score 在 γ 平台上跳动(0.1528/0.1667/0.1806),说明排序信号尚未稳定释放。",
"approach": "1) 在速度估计后、软阈值前,对每型 t 的速度向量 v_t 关于 log1p(pb_anchor_t)(逐基因)做 OLS 线性回归,取残差 v_res_t;2) 残差按该型原速度的标准差重缩放(保持位移幅度尺度不变);3) 残差进入后续软阈值 k=0.5 → 乘法位移 α=1 → γ=0.3 再闭合 → PBC=10,管线其余不变(平滑 ε=0.4 底物、门控、坐标/行序/组成冻结);4) 先试按型回归;若 de_score 未升,再试全局池化回归(所有型基因合并拟合一条斜率);5) 单输入阶段 / 锚≠末输入退路同父节点:平滑与速度一并关闭,逐位 copy_last;6) vec-score 快筛:首查 de_score raw 目标 ≥0.20,同时监控 de_direction ≥0.28、mmd_u ≤0.048、nb_mmd ≤0.076,任一显著恶化即停止该方向。",
"expected_groups": ["expression_change"],
"risks": "1) 若真实发育变化本身与表达水平相关(如高表达基因确实在减速),回归会移除真实信号,de_score 反降——Engineer 应先打印回归 R²,R²<0.05 说明无趋势可去除,机制无效应尽早放弃并回退;2) 残差重缩放实现错误会改变速度幅度,需数组级验证每型标准差复原;3) 预期提升可能在 1 分噪声内,用种子 0/1/2 三次查分均值确认;4) 按型回归在小型(<30 基因有效表达)上可能过拟合,设最小基因数门限(如 50),低于则跳过该型回归。",
"family_id": "T2HX-01",
"mechanism": "逐型对基因速度向量关于锚阶段表达水平做线性回归取残差,去除速度与表达水平的系统性共线分量,让保留的速度只反映与表达水平无关的变化信号,从而在 de_score 的 chance 校正下获得更高命中率。",
"vs_constant_shift": "常数位移/全局组成重加权对所有细胞或所有型施加统一变化量;本机制在基因维度上逐型去除速度的表达水平共线分量,每个基因被不同校正(回归残差不同),改变的是'哪些基因被认为在变化'的排序结构,而非统一幅度或方向。",
"mechanism_evidence": "1) 回归 R² > 0(速度与表达水平确有共线分量可去除);2) 回归前后速度向量 Spearman 相关 < 1(机制实际改变了速度排序);3) de_score raw 从 0.1944 上升且 de_direction 不降;4) 全局 dp 与 dt 的秩偏相关(控制 pb(ref))改善;5) 若 R² ≈ 0 或回归前后速度相关 > 0.99,说明机制未有效运行。",
"mechanism_off_control": "环境变量 VEC_VEL_REGRESS=0 跳过回归步骤(速度保持原始值),其余管线不变,输出应与父节点 29 逐位一致(.X 与坐标 array_equal True)。",
"sources": []
}
``` |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/researcher.jsonl 93 KB /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/researcher.stderr |
审查员
| 角色 | 审查员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 6 |
| 工具调用 | 共 8 次:read 5、bash 2、write 1 |
| 用时 | 1 分 |
| token 数 | 输入 33,165 · 输出 1,254 · 思考 1,197 |
| 任务(第一行) | 审查节点 n31 的程序是否越界读取、写死目标、钻评分器漏洞 |
| 最后的回答(摘录) | REVIEW.json written |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/reviewer.jsonl 151 KB /home/spark-longxinyang/vec/runs/formal/20261003-172000-search-t2-heart-extrap-chain-12h/nodes/31/reviewer.stderr |