Virtual Embryo Challenge更新于 10-03 21:24(北京时间) / 每 5 分钟更新

总览 · ← 返回运行 20261003-043412-search-t2-heart-interp-g24-D-s1

节点 n12

在父节点10实现跨类型表达相关匹配对齐(matched-align)替代exact-name作Procrustes地标;机制激活(22匹配对)但shape_scale未提升(55.2–56.2 vs 56.21),按PLAN回退关闭,提交=父节点行为。

运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。20261003-043412-search-t2-heart-interp-g24-D-s1
父节点n10
子节点n14
操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。改进
状态已打分
分数搜索目标分 63.01(+0.0) · proxy 63.01(+0.0)
审查未审查
用时?从运行开始到结束(或到现在)的挂钟时间。25 分
程序版本79854afc0c59cfb6ebabf099846d1b2cf5dc4b33 (programs.git)

方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。

来自 programs.git 79854afc0c:solution/METHOD.md

在父节点10实现跨类型表达相关匹配对齐(matched-align)替代exact-name作Procrustes地标;机制激活(22匹配对)但shape_scale未提升(55.2–56.2 vs 56.21),按PLAN回退关闭,提交=父节点行为。

方法族与实现

PLAN 指定家族 T2HI-01(插值:对齐 → logit 组成插值 → 共有类型内 k-NN 簇抽样 + 逐细胞表达凸组合,坐标 hold)。本节点按 PLAN 新增 matched_align 子机制:把 Procrustes 对齐地标从 exact-name 共有类型换成跨类型表达相关贪心匹配对。核心家族机制(INTERP_ENABLED=1, EXPR_INTERP=1, COORD_MODE=hold, 簇抽样 K=25/C=10)全部保持打开。

matched_align 实现(solution/run.py):

  1. 各侧按 celltype 算 pseudobulk 平均表达(每侧 ≥ MATCH_MIN_CELLS 细胞的类型)。
  2. 计算 a-型 × b-型 Pearson 相关矩阵,按相关从高到低贪心选匹配对(每型至多用一次,r ≥ MATCH_R),权重 = min(两侧该型细胞数)。
  3. 用匹配对质心做 Procrustes:xy Kabsch(允许反射),z 不旋转、符号由匹配质心 z 相关定。
  4. 匹配对 < 3 → 回退 exact-name align_pair(其内部再回退 PCA)。
  5. 开关 T2_MATCHED_ALIGN=1/0;另有 T2_MATCH_R、T2_MATCH_MIN_CELLS、T2_MATCH_WEIGHT(count/corr/corr2)、T2_MATCH_ZFLIP 供搜索。

机制生效证据(实际改变了什么)

机制确实激活并改变输出(非空转)。proxy 上 r≥0.3 时贪心匹配到 22 对(远超回退阈值 3),含大量生物合理的跨类型匹配:Endo↔Great Artery Endoth(0.863)、V-CM↔V-CM(0.851)、JCF↔Peri(0.844)、Intra-Endoth-2↔BEC(0.812)、Lateral FG↔Foregut(0.812)、IFT-CM↔A-CM(0.807)、d-CSE↔SE(0.77)、pPHM↔aPHM(0.751) 等。相比 exact-name 仅 5 个共有类型(NCC/Peri/V-CM/aPHM/pPHM)。匹配地标改变了作用于全部细胞坐标的整体刚体+反射变换:det、xy 旋转、以及 z 符号判定(matched 给出 z_flipped=True,exact-name 为 False)都随之改变,因此每个细胞的落点随位置而异——不是常数位移,也不是组成重加权。

对照结果(A 半,seed 0,官方评分器)

配置boardshape_scalelocal_spatialcell_stateexpr_change
提交:matched OFF(=父节点10)62.5956.2163.6665.7364.77
matched ON r0.3 count(z-flip)62.3955.2363.8165.7364.77
matched ON r0.3 count(no z-flip)62.3655.4563.4965.7364.77
matched ON r0.7(11 对)62.5155.6763.8965.7364.77
matched ON weight=corr62.3955.2863.8065.7364.77
matched ON weight=corr2(最佳)62.5656.1963.5765.7364.77

关闭对照:T2_MATCHED_ALIGN=0 与父节点10输出逐位一致(X 与 spatial_3D 均 array_equal=True),board 62.59、shape_scale 56.21,符合 PLAN 的 mechanism_off_control 预期。

结论:机制生效但未带来收益。 所有 matched-ON 配置的 shape_scale(55.2–56.2)均不高于父节点 exact-name 的 56.21;board 全部 ≤ 62.59。最佳的 corr2 加权(用 r² 压低可疑低相关对)仅把 shape_scale 拉回 56.19 ≈ 父节点,board 62.56 仍在噪声内略低。PLAN 的成功判据是「shape_scale 提升 > 1 且总分不降」——未满足,故按 PLAN 明确指示「否则回退 0」,提交 T2_MATCHED_ALIGN=0。

为什么不奏效(与节点8的差异)

节点8在 node7(mix 组成、shape_scale 52.78)上把地标换成 matched-align 得到 +3.15(→55.93)。但本父节点10(logit 组成 + coord=hold)的 exact-name 对齐已经达到 shape_scale 56.09/56.21,即 matched-align 在节点8 上换来的水平,node10 用 5 个空间可靠的同名类型就已达到。matched-align 再叠加只会在饱和点上波动:表达相关匹配把空间上并不对应的类型(如 Unknown↔OFT-CM、Allantois↔Branch Arch、Peri↔ST)也拉来当地标,Kabsch 为对齐这些表达相似但位置不符的质心而扭动 xy 旋转,反而不如同名地标稳。这正是 PLAN 风险 #1(与节点8/11 重叠、增益已被父节点吸收)的实现。

附加搜索:簇抽样参数(均 matched OFF)

顺带扫了 local_spatial 的最大杠杆——簇抽样 KNN_K × N_CLUSTERS(父=25×10):

K×Cboardshape_scalelocal_spatial
25×10(父)62.5956.2163.66
50×1062.5855.0164.04
25×2062.5755.2063.90
25×561.6351.5065.10
40×861.9551.8564.93
15×1061.3150.7964.39

shape_scale 对 K 极敏感,K=25/C=10 是尖峰最优;增大 K 或改 C 都以 shape 换 local,总分不升反降。父节点已坐在该前沿最优处,无免费改进。

已验证 / 未验证

已验证:(1) proxy 全流程跑通(~2s,纯 CPU,峰值内存远低于 limits),vec-check ok;(2) 提交默认(无环境变量)与父节点10逐位一致,seed 0 两次逐位相同,np.random.default_rng(seed),无全局随机;(3) matched ON/OFF 对照如上,机制激活时确实改变 22 对地标、xy 旋转与 z 符号(改变全部细胞坐标),OFF 时回退父节点;(4) 视图无关:matched_align/matched_landmarks 只用 coords、labels、X,不读 board/mode/path、不用绝对时间;t 由 interp_bracket 用时间差算,统一平移不变;默认 OFF 路径 = 父节点(已证视图无关)。

未验证 / 风险:(1) matched-align 在 final(31 共有类型) 上是否更有价值未测——proxy 仅 5 个同名类型,matched 的 22 对里很多是跨类型,若 final 同名类型已足够多,matched 的边际收益可能仍为负;本节点据 proxy 判其不奏效并关闭。(2) shape_scale 受目标 RMS 制约:两端 log-线性给 346,proxy 真值 E8.75≈217(心脏尺度非单调 354→217→335),scale_log_ratio≈0.467 是 shape 的主惩罚,无法从括号两端推出更小的目标,matched-align 不改 RMS 故对此无能为力——这是方法卡已知弱点,未硬调 scale_damp 到 proxy 真值(会破坏视图无关)。(3) 未在 final/伪装视图实跑,仅代码层面论证视图无关。

生物学知识来源

未引入外部文献/数据库/检索知识,也未用保留阶段或保留基因型的任何信息。细胞类型名、表达、坐标全部来自视图给定的官方输入阶段(proxy: E8.25_late、E9.5,均在允许范围;目标 E8.75 未使用)。跨类型表达相关匹配、Pearson 相关、Kabsch/Procrustes、贪心匹配均为通用统计/几何方法,不含针对禁窗阶段的先验。未读 external/ 与 prior/。

下一步

  1. matched-align 在本 base 饱和,不要再在 node10 系上重试同款对齐(本节点已证伪);若要验证它在多类型场景的价值,应在 final-like(多共有类型)视图上单独测,而非 proxy。
  2. shape_scale 被目标 RMS 卡死:真正需要的是不使用真值的更好 RMS 估计(如 RMS 随 log 细胞数/阶段间隔的回归、或对称验证的 SCALE_DAMP),但要警惕过拟合 proxy 的非单调 dip。
  3. local_spatial/expr 的前沿已被父节点占满;若要突破,需换机制(如容量约束/双向互匹配的表达插值、或亚型细分以在多类型下激活 expr interp),而非调簇参数。

调研员的计划

名称在 T2HI-01 框架引入跨类型表达相关匹配对齐,修复最弱组 shape_scale
动机父节点10四组分 shape_scale=56.09 最弱(比最高 cell_state 66.54 低 10.45),ANALYSIS 归因于 exact-name 共有类型对齐较弱+目标 RMS 估偏。同树节点8已实证:把 Procrustes 对齐地标从 exact-name 换成跨类型表达相关贪心匹配对(Pearson r≥0.3、每侧≥30细胞),在 mix+簇抽样下使 shape_scale 52.78→55.93(+3.15,远超 T2 噪声~1),是全部增益来源。父节点10仍用 exact-name 对齐、未吸收该有效部件,故最弱组有明确、可解释且已被验证的结构问题可修,且不与已失败改法重复。
做法在父节点10的 run.py 新增 matched_align 模块(移植/按节点8描述重写):对齐阶段计算两侧各型 pseudobulk 表达,按 Pearson 相关贪心选跨类型匹配对(初值 r≥0.3、每侧≥30 细胞、权重=min(两侧该型细胞数)),用匹配对质心做 Procrustes(xy Kabsch 允许反射,z 不旋转、符号由匹配质心 z 相关决定);匹配对<3 回退 exact-name,再回退 PCA。logit 组成插值、k-NN 簇抽样、逐细胞表达凸组合全部保持不变,只换对齐地标。开关 T2_MATCHED_ALIGN=1/0。单输入/外推退路不变(分层复制 anchor)。搜索范围小而快:r∈{0.25,0.3,0.4}×每侧最小细胞数∈{20,30}。用 vec-score 先跑 proxy seed0:仅当 shape_scale 提升>1 且总分不降才提交,否则回退 0。
风险1) 与节点11(节点8后续)可能重叠——Engineer 应先确认节点11是否已用同款对齐;2) proxy 只有5个共有类型,表达相关匹配对可能<3 而触发回退,导致机制未激活——必须打印实际匹配对数与是否回退;3) 节点10的 logit 组成插值改变配额,理论上与对齐独立,但若交互异常应先对齐后抽样验证;4) 30分钟时限紧,移植后先用单侧抽样子集确认对齐收敛再全量跑。

代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。

对比:父节点版本 47ac7bd258。改动的文件:solution/METHOD.md +46 −24、solution/run.py +137 −6

diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 751f688..142c49c 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,44 +1,66 @@-T2HI-01 draft:对齐后按 logit 插值类型组成,共有类型内用 k-NN 区域生长抽样并对每个细胞与对侧表达最近邻做伪批量凸组合插值,坐标保留真实对齐位置。+在父节点10实现跨类型表达相关匹配对齐(matched-align)替代exact-name作Procrustes地标;机制激活(22匹配对)但shape_scale未提升(55.2–56.2 vs 56.21),按PLAN回退关闭,提交=父节点行为。  ## 方法族与实现 -实现 PLAN 指定的 **T2HI-01** 家族:插值括号两侧阶段 → 对齐 → logit 组成插值 → 共有类型内逐细胞最近邻伪批量插值。核心机制在 `solution/run.py`,由常量/环境开关控制,提交时**全部打开**(`INTERP_ENABLED=1`, `EXPR_INTERP=1`, `COORD_MODE=hold`)。+PLAN 指定家族 **T2HI-01**(插值:对齐 → logit 组成插值 → 共有类型内 k-NN 簇抽样 + 逐细胞表达凸组合,坐标 hold)。本节点按 PLAN 新增 **matched_align** 子机制:把 Procrustes 对齐地标从 exact-name 共有类型换成**跨类型表达相关贪心匹配对**。核心家族机制(`INTERP_ENABLED=1`, `EXPR_INTERP=1`, `COORD_MODE=hold`, 簇抽样 K=25/C=10)全部保持打开。 -流程:-1. `vio.interp_bracket(manifest)` 取目标两侧最近输入 (a, b) 与 `t=(target−a)/(b−a)`;不被括号(外推/单输入)则退路为分层复制 anchor 阶段到 [min,max],不崩。-2. **坐标对齐**:`frame.align_pair(..., "procrustes")`(xy Kabsch 允许反射,z 符号按共有类型质心相关定向,z 不旋转),两侧再 `scale_to_rms` 到 log-线性目标 RMS(`scale_damp=1`)。-3. **logit 组成插值(机制核心之一)**:共有类型(两侧各 ≥5 细胞)用 `q=sigmoid((1−t)·logit(p_a)+t·logit(p_b))`;单侧类型按该侧权重 `×(1−t)` 或 `×t`;归一化后按总细胞数 `N=interp_count`(log-线性,夹到 [min,max])分配每型配额(带上限+余额重分配)。-4. **类型内最近邻伪批量插值(机制核心之二)**:共有类型按配额从两侧各用 **k-NN 贪心区域生长**(`KNN_K=25`、约 `N_CLUSTERS=10` 个空间连续簇)抽细胞;对每个抽出细胞,在**同类型对侧**的表达 PCA(前 `PCA_DIM=50` 维)空间找最近邻,做凸组合 `x=(1−t)·x_self + t·x_nn`(产生连续过渡的合成细胞,非整细胞混抽)。单侧类型直接取真实细胞。-5. 合并 → `_jitter` 去重 → `scale_to_rms(target_rms)` → `write_t2` 输出(表达+`spatial_3D`)。+matched_align 实现(`solution/run.py`):+1. 各侧按 celltype 算 pseudobulk 平均表达(每侧 ≥ `MATCH_MIN_CELLS` 细胞的类型)。+2. 计算 a-型 × b-型 Pearson 相关矩阵,按相关从高到低**贪心**选匹配对(每型至多用一次,r ≥ `MATCH_R`),权重 = min(两侧该型细胞数)。+3. 用匹配对质心做 Procrustes:xy Kabsch(允许反射),z 不旋转、符号由匹配质心 z 相关定。+4. 匹配对 < 3 → 回退 exact-name `align_pair`(其内部再回退 PCA)。+5. 开关 `T2_MATCHED_ALIGN=1/0`;另有 `T2_MATCH_R`、`T2_MATCH_MIN_CELLS`、`T2_MATCH_WEIGHT`(count/corr/corr2)、`T2_MATCH_ZFLIP` 供搜索。 -## 关键参数+## 机制生效证据(实际改变了什么) -`MIN_TYPE_CELLS=5`, `KNN_K=25`, `N_CLUSTERS=10`, `PCA_DIM=50`, `SCALE_DAMP=1.0`, `COUNT_DAMP=1.0`。坐标:`COORD_MODE=hold`(抽出细胞保留自己所在阶段的对齐坐标,不插值坐标)。+机制**确实激活并改变输出**(非空转)。proxy 上 r≥0.3 时贪心匹配到 **22 对**(远超回退阈值 3),含大量生物合理的跨类型匹配:Endo↔Great Artery Endoth(0.863)、V-CM↔V-CM(0.851)、JCF↔Peri(0.844)、Intra-Endoth-2↔BEC(0.812)、Lateral FG↔Foregut(0.812)、IFT-CM↔A-CM(0.807)、d-CSE↔SE(0.77)、pPHM↔aPHM(0.751) 等。相比 exact-name 仅 5 个共有类型(NCC/Peri/V-CM/aPHM/pPHM)。匹配地标改变了作用于**全部细胞坐标**的整体刚体+反射变换:det、xy 旋转、以及 z 符号判定(matched 给出 z_flipped=True,exact-name 为 False)都随之改变,因此每个细胞的落点随位置而异——不是常数位移,也不是组成重加权。 -## 机制生效证据+## 对照结果(A 半,seed 0,官方评分器) -proxy 上共有类型 5 个(NCC, Peri, V-CM, aPHM, pPHM),**2972 / 17616 ≈ 17% 细胞的表达被逐细胞插值改动**(其余为单侧真实细胞)。打印见 stderr `[interp] ... interp_cells=2972`。四组分(A 半,seed 0):--| 配置 | board | expr_change | cell_state | shape_scale | local_spatial |+| 配置 | board | shape_scale | local_spatial | cell_state | expr_change | |---|---:|---:|---:|---:|---:|-| **提交(机制全开, coord=hold)** | **62.59** | 64.77 | 65.73 | 56.21 | 63.66 |-| 对照 `INTERP_ENABLED=0`(=seed mix 混抽真实细胞) | 59.07 | 63.83 | 65.93 | 53.07 | 53.46 |-| 消融 `EXPR_INTERP=0`(仅 logit 组成+簇抽样+真实表达) | 62.92 | 65.09 | 66.49 | 56.21 | 63.90 |-| `COORD_MODE=interp`(表达+坐标都插值) | 61.57 | 64.77 | 65.73 | 53.18 | 62.61 |-| 参考:当前最佳 node 7(簇抽样 mix) | 62.61 | 64.90 | 67.58 | 52.78 | 65.20 |+| **提交:matched OFF(=父节点10)** | **62.59** | **56.21** | 63.66 | 65.73 | 64.77 |+| matched ON r0.3 count(z-flip) | 62.39 | 55.23 | 63.81 | 65.73 | 64.77 |+| matched ON r0.3 count(no z-flip) | 62.36 | 55.45 | 63.49 | 65.73 | 64.77 |+| matched ON r0.7(11 对) | 62.51 | 55.67 | 63.89 | 65.73 | 64.77 |+| matched ON weight=corr | 62.39 | 55.28 | 63.80 | 65.73 | 64.77 |+| matched ON weight=corr2(最佳) | 62.56 | 56.19 | 63.57 | 65.73 | 64.77 |++**关闭对照**:`T2_MATCHED_ALIGN=0` 与父节点10输出**逐位一致**(X 与 spatial_3D 均 `array_equal=True`),board 62.59、shape_scale 56.21,符合 PLAN 的 mechanism_off_control 预期。++**结论:机制生效但未带来收益。** 所有 matched-ON 配置的 shape_scale(55.2–56.2)均**不高于**父节点 exact-name 的 56.21;board 全部 ≤ 62.59。最佳的 corr2 加权(用 r² 压低可疑低相关对)仅把 shape_scale 拉回 56.19 ≈ 父节点,board 62.56 仍在噪声内略低。PLAN 的成功判据是「shape_scale 提升 > 1 且总分不降」——**未满足**,故按 PLAN 明确指示「否则回退 0」,提交 `T2_MATCHED_ALIGN=0`。++## 为什么不奏效(与节点8的差异)++节点8在 node7(mix 组成、shape_scale 52.78)上把地标换成 matched-align 得到 +3.15(→55.93)。但本父节点10(logit 组成 + coord=hold)的 exact-name 对齐**已经达到 shape_scale 56.09/56.21**,即 matched-align 在节点8 上换来的水平,node10 用 5 个空间可靠的同名类型就已达到。matched-align 再叠加只会在饱和点上波动:表达相关匹配把**空间上并不对应**的类型(如 Unknown↔OFT-CM、Allantois↔Branch Arch、Peri↔ST)也拉来当地标,Kabsch 为对齐这些表达相似但位置不符的质心而扭动 xy 旋转,反而不如同名地标稳。这正是 PLAN 风险 #1(与节点8/11 重叠、增益已被父节点吸收)的实现。++## 附加搜索:簇抽样参数(均 matched OFF)++顺带扫了 local_spatial 的最大杠杆——簇抽样 KNN_K × N_CLUSTERS(父=25×10):++| K×C | board | shape_scale | local_spatial |+|---|---:|---:|---:|+| 25×10(父) | 62.59 | 56.21 | 63.66 |+| 50×10 | 62.58 | 55.01 | 64.04 |+| 25×20 | 62.57 | 55.20 | 63.90 |+| 25×5 | 61.63 | 51.50 | 65.10 |+| 40×8 | 61.95 | 51.85 | 64.93 |+| 15×10 | 61.31 | 50.79 | 64.39 | -对照结果:机制全开 **62.59 vs 关闭 59.07(+3.5)**,主要来自 local_spatial(簇抽样保留局部邻域 53.46→63.66)与 shape_scale(coord=hold 保真实坐标 53.07→56.21)。关闭后确实回到 seed mix 水平(≈59),证明代码路径激活且机制改变输出。+shape_scale 对 K 极敏感,K=25/C=10 是尖峰最优;增大 K 或改 C 都以 shape 换 local,总分不升反降。父节点已坐在该前沿最优处,无免费改进。  ## 已验证 / 未验证 -**已验证**:(1) proxy 全流程跑通(~4s,纯 CPU),`vec-check` ok;(2) seed 0 两次逐位一致(X 与坐标),`np.random.default_rng(seed)`,无全局随机;(3) 机制开关对照如上;(4) 视图无关:`t` 只用时间**差**(括号两端),目标 RMS/组成/配额全部现场从数据算,无绝对时间分支、无写死细胞数/阶段名/视图名,时间统一平移不改变输出。未读 `external/` 与 `prior/`,只用视图给的两个官方输入阶段,无保留阶段/基因型信息。+**已验证**:(1) proxy 全流程跑通(~2s,纯 CPU,峰值内存远低于 limits),`vec-check` ok;(2) 提交默认(无环境变量)与父节点10**逐位一致**,seed 0 两次逐位相同,`np.random.default_rng(seed)`,无全局随机;(3) matched ON/OFF 对照如上,机制激活时确实改变 22 对地标、xy 旋转与 z 符号(改变全部细胞坐标),OFF 时回退父节点;(4) 视图无关:matched_align/matched_landmarks 只用 coords、labels、X,不读 board/mode/path、不用绝对时间;t 由 `interp_bracket` 用时间**差**算,统一平移不变;默认 OFF 路径 = 父节点(已证视图无关)。 -**未验证 / 风险**:(1) proxy 仅 5 个共有类型,类型内表达插值几乎退化——消融显示 `EXPR_INTERP=0` 反而略高(62.92 vs 62.59,差 0.33 << 噪声 ~2,属噪声内),说明 proxy 上增益主要来自 logit 组成插值+簇抽样,表达插值近乎中性;按 PLAN,表达插值是家族定义机制、在 final(31 共有类型)预期作用更大,故**提交保持打开**,未因 proxy 噪声关掉。(2) 坐标:PLAN 建议坐标也插值,但 proxy 上 coord=interp 明显更差(61.57),故改 hold(保真实对齐坐标)——这是相对 PLAN 的实证偏离,final 上是否仍 hold 更好未验证。(3) 目标 RMS 用两端 log-线性(346),proxy 真值 E8.75≈217,`scale_log_ratio=0.467` 偏弱,但两端都大、无法从括号推出更小的目标,属方法卡已知弱点,未针对 proxy 硬调 `scale_damp`(会破坏视图无关)。(4) 未在 final/伪装视图实跑,仅代码层面论证视图无关。+**未验证 / 风险**:(1) matched-align 在 **final(31 共有类型)** 上是否更有价值未测——proxy 仅 5 个同名类型,matched 的 22 对里很多是跨类型,若 final 同名类型已足够多,matched 的边际收益可能仍为负;本节点据 proxy 判其不奏效并关闭。(2) shape_scale 受目标 RMS 制约:两端 log-线性给 346,proxy 真值 E8.75≈217(心脏尺度非单调 354→217→335),scale_log_ratio≈0.467 是 shape 的主惩罚,**无法从括号两端推出更小的目标**,matched-align 不改 RMS 故对此无能为力——这是方法卡已知弱点,未硬调 scale_damp 到 proxy 真值(会破坏视图无关)。(3) 未在 final/伪装视图实跑,仅代码层面论证视图无关。  ## 生物学知识来源 -未引入外部文献/数据库知识;细胞类型名、表达、坐标全部来自视图给定的官方输入阶段(proxy: E8.25_late, E9.5,均在允许范围,目标 E8.75 未使用)。logit 组成插值、k-NN 区域生长、表达 PCA 最近邻伪批量插值均为通用统计/几何方法,不含针对禁窗阶段的先验。+未引入外部文献/数据库/检索知识,也未用保留阶段或保留基因型的任何信息。细胞类型名、表达、坐标全部来自视图给定的官方输入阶段(proxy: E8.25_late、E9.5,均在允许范围;目标 E8.75 未使用)。跨类型表达相关匹配、Pearson 相关、Kabsch/Procrustes、贪心匹配均为通用统计/几何方法,不含针对禁窗阶段的先验。未读 `external/` 与 `prior/`。  ## 下一步 -final(31 共有类型)上验证表达插值是否真正提升 cell_state;试 coord=interp vs hold 在多类型下谁更好;组成插值可试线性 vs logit 的取舍。+1. matched-align 在本 base 饱和,**不要再在 node10 系上重试同款对齐**(本节点已证伪);若要验证它在多类型场景的价值,应在 final-like(多共有类型)视图上单独测,而非 proxy。+2. shape_scale 被目标 RMS 卡死:真正需要的是**不使用真值**的更好 RMS 估计(如 RMS 随 log 细胞数/阶段间隔的回归、或对称验证的 SCALE_DAMP),但要警惕过拟合 proxy 的非单调 dip。+3. local_spatial/expr 的前沿已被父节点占满;若要突破,需换机制(如容量约束/双向互匹配的表达插值、或亚型细分以在多类型下激活 expr interp),而非调簇参数。diff --git a/solution/run.py b/solution/run.pyindex f6d347d..565ec2f 100644--- a/solution/run.py+++ b/solution/run.py@@ -21,21 +21,144 @@ from scipy.spatial import cKDTree from scipy.spatial.distance import cdist  from src.task2_spatial import view_io as vio-from src.task2_spatial.frame import align_pair, log_interp, rms_radius, scale_to_rms+from src.task2_spatial.frame import (+    align_pair,+    center,+    kabsch,+    log_interp,+    rms_radius,+    scale_to_rms,+) from src.task2_spatial.methods import _jitter from src.task2_spatial.sample import interp_count, take  INTERP_ENABLED = os.environ.get("T2HI_INTERP", "1") != "0" COORD_MODE = os.environ.get("T2HI_COORD", "hold")  # interp | hold EXPR_INTERP = os.environ.get("T2HI_EXPR", "1") != "0"  # blend shared-type expr toward NN+# matched-align: replace exact-name Procrustes landmarks with cross-type+# expression-correlation greedy matched pairs. Empirically REJECTED on this base+# (see METHOD.md): node-10 exact-name align already saturates shape_scale, and+# expression-correlation landmarks distort the in-plane rotation. Submitted OFF+# per the PLAN criterion (fall back to 0 when shape_scale does not improve >1).+# Set T2_MATCHED_ALIGN=1 to re-enable the implemented mechanism for comparison.+MATCHED_ALIGN = os.environ.get("T2_MATCHED_ALIGN", "0") != "0"+MATCH_R = float(os.environ.get("T2_MATCH_R", "0.3"))+MATCH_MIN_CELLS = int(os.environ.get("T2_MATCH_MIN_CELLS", "30"))+MATCH_ZFLIP = os.environ.get("T2_MATCH_ZFLIP", "1") != "0"  # diagnostic: apply matched z-sign decision+MATCH_WEIGHT = os.environ.get("T2_MATCH_WEIGHT", "count")  # count | corr | corr2 MIN_TYPE_CELLS = 5-KNN_K = 25-N_CLUSTERS = 10+KNN_K = int(os.environ.get("T2_KNN_K", "25"))+N_CLUSTERS = int(os.environ.get("T2_N_CLUSTERS", "10")) PCA_DIM = 50 SCALE_DAMP = 1.0 COUNT_DAMP = 1.0  +def _type_pseudobulk(X, labels: np.ndarray, min_cells: int):+    """Mean log-expression per cell type with >= min_cells; returns {label: (vec, count)}."""+    labs = np.asarray(labels).astype(str)+    out = {}+    for lab in np.unique(labs):+        idx = np.flatnonzero(labs == lab)+        if idx.size >= min_cells:+            vec = np.asarray(X[idx].mean(axis=0), dtype=np.float64).ravel()+            out[str(lab)] = (vec, idx)+    return out+++def matched_landmarks(coords_a, coords_b, labels_a, labels_b, X_a, X_b,+                      r_thresh: float, min_cells: int, weight: str = "count"):+    """Greedy cross-type expression-correlation matching -> paired centroids + weights.++    Returns (ca, cb, w, pairs) where ca/cb are (m, 3) centroids of matched a/b+    types, w is the per-pair weight, and pairs is a list of (label_a, label_b, r).+    Types are matched at most once each. weight: count=min(n_a,n_b);+    corr=count*r; corr2=count*r^2 (downweights low-confidence matches).+    """+    pb_a = _type_pseudobulk(X_a, labels_a, min_cells)+    pb_b = _type_pseudobulk(X_b, labels_b, min_cells)+    keys_a = sorted(pb_a)+    keys_b = sorted(pb_b)+    if not keys_a or not keys_b:+        return (np.zeros((0, 3)), np.zeros((0, 3)), np.zeros(0), [])+    A = np.stack([pb_a[k][0] for k in keys_a])+    B = np.stack([pb_b[k][0] for k in keys_b])+    Ac = A - A.mean(axis=1, keepdims=True)+    Bc = B - B.mean(axis=1, keepdims=True)+    An = Ac / (np.linalg.norm(Ac, axis=1, keepdims=True) + 1e-12)+    Bn = Bc / (np.linalg.norm(Bc, axis=1, keepdims=True) + 1e-12)+    C = An @ Bn.T  # (na, nb) Pearson correlation+    order = np.dstack(np.unravel_index(np.argsort(-C, axis=None), C.shape))[0]+    used_a, used_b = set(), set()+    pairs, ca, cb, w = [], [], [], []+    for i, j in order:+        r = float(C[i, j])+        if r < r_thresh:+            break+        if i in used_a or j in used_b:+            continue+        used_a.add(int(i))+        used_b.add(int(j))+        ka, kb = keys_a[i], keys_b[j]+        ia = pb_a[ka][1]+        ib = pb_b[kb][1]+        pairs.append((ka, kb, r))+        ca.append(coords_a[ia].mean(axis=0))+        cb.append(coords_b[ib].mean(axis=0))+        cnt = float(min(ia.size, ib.size))+        if weight == "corr":+            wv = cnt * r+        elif weight == "corr2":+            wv = cnt * r * r+        else:+            wv = cnt+        w.append(wv)+    if not pairs:+        return (np.zeros((0, 3)), np.zeros((0, 3)), np.zeros(0), [])+    return np.stack(ca), np.stack(cb), np.array(w, dtype=np.float64), pairs+++def matched_align(coords_a, coords_b, labels_a, labels_b, X_a, X_b,+                  r_thresh: float, min_cells: int, apply_zflip: bool = True,+                  weight: str = "count"):+    """Procrustes-align b onto a using matched-pair centroids (z held, xy Kabsch+    with reflection). Falls back to exact-name align_pair when < 3 matched pairs.+    Both clouds are returned in a common centred frame, rescaled to nothing here+    (caller applies target RMS). Diagnostic dict reports matched-pair details.+    """+    ca, cb, w, pairs = matched_landmarks(+        coords_a, coords_b, labels_a, labels_b, X_a, X_b, r_thresh, min_cells, weight+    )+    a = center(coords_a)+    b = center(coords_b)+    info = {"align": "matched", "n_matched": int(len(pairs))}+    # recompute centroids in the centred frame+    if len(pairs) >= 3:+        ca_c = ca - coords_a.mean(axis=0)+        cb_c = cb - coords_b.mean(axis=0)+        r, _, _ = kabsch(cb_c[:, :2], ca_c[:, :2], w, allow_reflection=True)+        by = b[:, :2] @ r+        ay = a[:, :2]+        za = ca_c[:, 2] - np.average(ca_c[:, 2], weights=w)+        zb = cb_c[:, 2] - np.average(cb_c[:, 2], weights=w)+        z_dot = float(np.dot(za, zb))+        flip = bool(z_dot < 0) and apply_zflip+        bz = -b[:, 2] if flip else b[:, 2]+        out_a = np.column_stack([ay, a[:, 2]])+        out_b = np.column_stack([by, bz])+        info.update(det=float(np.linalg.det(r)), z_flipped=bool(flip),+                    z_dot=z_dot, fallback=None,+                    pairs=[(pa, pb, round(pr, 3)) for pa, pb, pr in pairs])+        return center(out_a), center(out_b), info+    # not enough matched pairs -> exact-name procrustes (which itself -> PCA)+    aligned_a, aligned_b, info2 = align_pair(coords_a, coords_b, labels_a, labels_b, "procrustes")+    info2["align"] = "matched"+    info2["n_matched"] = int(len(pairs))+    info2["fallback"] = "exact_name" if info2.get("n_shared_types", 0) >= 3 else "pca"+    info2["pairs"] = [(pa, pb, round(pr, 3)) for pa, pb, pr in pairs]+    return aligned_a, aligned_b, info2++ def cluster_take(coords: np.ndarray, n: int, rng: np.random.Generator) -> np.ndarray:     """Greedy k-NN region growth: ~N_CLUSTERS spatially contiguous blocks totalling n cells."""     m = len(coords)@@ -153,7 +276,13 @@ def run(view: str, out: str, seed: int) -> None:     t = float(t)      # align + rescale both stages to the log-linear target RMS-    aligned_a, aligned_b, info = align_pair(sa.coords, sb.coords, sa.labels, sb.labels, "procrustes")+    if MATCHED_ALIGN:+        aligned_a, aligned_b, info = matched_align(+            sa.coords, sb.coords, sa.labels, sb.labels, sa.X, sb.X,+            MATCH_R, MATCH_MIN_CELLS, MATCH_ZFLIP, MATCH_WEIGHT,+        )+    else:+        aligned_a, aligned_b, info = align_pair(sa.coords, sb.coords, sa.labels, sb.labels, "procrustes")     rms_a, rms_b = rms_radius(sa.coords), rms_radius(sb.coords)     target_rms = log_interp(rms_a, rms_b, t, SCALE_DAMP)     ca = scale_to_rms(aligned_a, target_rms)@@ -265,8 +394,10 @@ def run(view: str, out: str, seed: int) -> None:     coords = scale_to_rms(_jitter(coords, rng), target_rms)     print(         f"[interp] t={t:.3f} n={len(expr)} shared={len(shared)} {shared} "-        f"interp_cells={n_interp_cells} align_types={info.get('n_types')} "-        f"rms={rms_radius(coords):.1f}",+        f"interp_cells={n_interp_cells} align={info.get('align')} "+        f"n_matched={info.get('n_matched')} fallback={info.get('fallback')} "+        f"n_types={info.get('n_shared_types')} z_flipped={info.get('z_flipped')} "+        f"pairs={info.get('pairs')} rms={rms_radius(coords):.1f}",         file=sys.stderr,     )     vio.write_t2(out, expr, coords.astype(np.float32), genes, seed=seed)

调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。

用到的知识库条目

编号标题出处
k007Interval staging and held-out-window filtering of external datanotes/official/来件/virtualembryo.ai/rules.md
k024World-model evaluation dimensions for state-transition predictorsnotes/competition/07_biomedical_world_models.md
k023Time-split validation with a held-out intermediate or next time pointnotes/handover/02_知识学习路线.md

分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。

改了什么在父节点10 的 run.py 中新增 matched_align 子模块(跨类型 pseudobulk Pearson 相关贪心匹配对作 Procrustes 地标,含 T2_MATCHED_ALIGN/T2_MATCH_R/T2_MATCH_MIN_CELLS/T2_MATCH_WEIGHT/T2_MATCH_ZFLIP 开关,KNN_K 与 N_CLUSTERS 改为可环境变量覆盖),并按 PLAN 判据在提交时设为 OFF——提交产物与父节点10 逐位一致,故所有分组变化均为 +0.00。
各组分数的变化cell_state:噪声内(66.54 → 66.54,+0.00,提交=父节点)
expression_change:噪声内(65.25 → 65.25,+0.00,提交=父节点)
local_spatial:噪声内(64.17 → 64.17,+0.00)
shape_scale:噪声内(56.09 → 56.09,+0.00);Engineer 自测 matched-ON 各配置 shape_scale 仅 55.2–56.2,均不高于 exact-name 的 56.21,即目标组未被改善
family_idT2HI-01
假设是否成立否
经验
  1. 在 base=shape_scale 已达 56.09 的 T2HI-01(logit 组成插值 + coord=hold + K25/C10 簇抽样)上引入跨类型表达相关 matched-align(22 对地标):机制确实改变了全部细胞坐标(det、xy 旋转、z 符号均变),但 shape_scale 只在 55.2–56.2 波动、board ≤62.59,增益为零——同一部件在 shape_scale=52.78 的 node7 上值 +3.15,说明其收益依赖 base 的对齐质量,移植到更强 base 前必须先量化 base 的该组余量。
  2. 在 proxy(仅 5 个同名共有类型)上,表达相关匹配会把空间不对应的类型对(如 Unknown↔OFT-CM、Allantois↔Branch Arch、Peri↔ST)也拉来当 Procrustes 地标,Kabsch 为拟合这些质心而扭动 xy 旋转,反而不如只用 5 个同名地标稳;用 r² 加权(weight=corr2)压低低相关对可把 shape_scale 拉回 56.19 ≈ exact-name,但仍不超噪声。
  3. matched-align 只改几何变换、不改 target_rms;当 shape_scale 的主惩罚来自 RMS 估计偏差(log-线性给 346 vs proxy 真值 E8.75≈217,scale_log_ratio≈0.467)时,任何对齐地标替换都无法提升该组——先诊断惩罚来源是缩放还是姿态,再选对齐类改法。
  4. 在 K25/C10 base 上扫簇抽样参数(50×10、25×20、25×5、40×8、15×10):local_spatial 与 shape_scale 呈明确此消彼长(如 25×5 使 local 65.10 但 shape 51.50,board 61.63),25×10 是该前沿的尖峰,调簇参数无免费改进。
  5. 把新机制实现为默认 OFF 的环境变量开关 + 提交前用 proxy 官方评分器做 ON/OFF 对照(并验证 OFF 与父节点 array_equal),能在机制无效时零成本保住父节点分数,本节点因此没有负分损失。
mechanism_active否
下一步建议
  1. 针对 shape_scale:不要再在 node10 系重试任何对齐地标替换(exact-name / matched-align 已双双饱和于 56.09–56.21);改攻 target_rms 估计——用视图给定的多个允许输入阶段拟合 RMS ~ log(细胞数) 与 RMS ~ 阶段间隔 的关系外推目标 RMS(禁用真值、保持时间平移不变),先只做 A 半 seed0 对照,shape_scale 提升 >1 才提交。
  2. 针对 shape_scale 的备选(若不引入新回归):对 SCALE_DAMP 做对称验证式搜索(在两个不同括号端点组合上各自最优的 damp 是否一致),只接受跨端点稳定的 damp 值,避免过拟合 proxy 的非单调 dip(354→217→335)。
  3. 针对 cell_state/expression_change:换机制而非调参——把逐细胞表达凸组合改为容量约束/双向互匹配(每侧细胞与对侧最近邻做一对一或带容量上限的匹配后再插值),并把 PCA_DIM=50 的近邻空间换成亚型细分后的同亚型近邻,先在 proxy 上验证 interp_cells 比例与被改动细胞数是否上升。

对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。

只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。

分析员

角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。分析员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数?大模型一共回复了几轮(每轮可以调用多个工具)。4
工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。共 3 次:bash 2、write 1
用时不到 1 分
token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。输入 14,034 · 输出 1,413 · 思考 249
任务(第一行)分析节点 n12 的打分结果,写 ANALYSIS.json
最后的回答(摘录)
ANALYSIS.json written
原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。/home/spark-longxinyang/vec/runs/formal/20261003-043412-search-t2-heart-interp-g24-D-s1/nodes/12/analyst.jsonl 12 KB
/home/spark-longxinyang/vec/runs/formal/20261003-043412-search-t2-heart-interp-g24-D-s1/nodes/12/analyst.stderr

工程师

角色工程师 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数40
工具调用共 41 次:bash 19、edit 14、read 7、write 1
用时18 分
token 数输入 82,034 · 输出 14,729 · 思考 19,953
任务(第一行)按计划修改程序:在 T2HI-01 框架引入跨类型表达相关匹配对齐,修复最弱组 shape_scale
最后的回答(摘录)
All checks pass. Submission is complete and verified.

**做了什么**:按 PLAN 在父节点10 (T2HI-01) 实现了 matched_align 子机制——用跨类型表达相关贪心匹配对(Pearson r≥阈值、每侧≥min细胞、权重=min细胞数)的质心替代 exact-name 共有类型作 Procrustes 地标(xy Kabsch 允许反射、z 符号由匹配质心定、<3对回退 exact-name→PCA),带 `T2_MATCHED_ALIGN` 开关。机制确实激活:proxy 上匹配到 22 对(含 Endo↔Great Artery Endoth 0.863、JCF↔Peri 0.844 等合理跨类型对),改变了作用于全部细胞坐标的整体变换。

**查分结果**(A半 seed0,用了 11/20 次):机制虽生效但**不奏效**。所有 matched-ON 配置 shape_scale 55.2–56.2 均不高于父节点 exact-name 的 56.21,board 全部 ≤62.59(最佳 corr2 加权 62.56 仅打平)。顺带扫的簇参数(K×C)也证实父节点 25×10 是尖峰最优,增大 K 以 shape 换 local、总分反降。按 PLAN 判据(shape 提升>1 且总分不降才提交)**未满足 → 回退 `T2_MATCHED_ALIGN=0`**。提交默认与父节点10逐位一致(62.59),deterministic、vec-check ok、视图无关。

**根因**:节点8 在 node7(shape 52.78)上靠 matched-align +3.15,但 node10 的 exact-name 对齐已达 56.09——增益已被父节点吸收(PLAN 风险#1 应验);表达相关匹配把空间不对应的类型也拉来当地标,反而扭动 xy 旋转。

**下一步最值得试**:(1) 不要再在 node10 系重试同款对齐(已证伪);(2) shape_scale 真正被目标 RMS 卡死(346 vs 真值217,心脏尺度非单调),需**不用真值**的更好 RMS 估计(RMS~log细胞数/阶段间隔回归),但警惕过拟合 proxy 的 dip;(3) 换机制而非调参——容量约束/双向互匹配的表达插值,或亚型细分以在多类型下激活 expr interp。
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-043412-search-t2-heart-interp-g24-D-s1/nodes/12/engineer.jsonl 248 KB
/home/spark-longxinyang/vec/runs/formal/20261003-043412-search-t2-heart-interp-g24-D-s1/nodes/12/engineer.stderr

调研员

角色调研员 alibaba-token-plan-cn/qwen3.8-max
调用次数1 次
轮数1
工具调用共 0 次:—
用时5 分
token 数输入 12,362 · 输出 5,928 · 思考 8,192
任务(第一行)为节点 n12(改进,父节点 n10)写改进计划 PLAN.json
最后的回答(摘录)
了符合"父节点所属方法族",写T2HI-01。并在mechanism里说清楚。

我认为方案合理。输出。

实际上再想:题目强调"针对最弱的一组"。我的方案针对shape_scale(最弱),符合。

还有一个担心:节点8的对齐改进是在没有组成插值的情况下。节点10有组成插值。引入表达相关对齐后,是否会有负面交互?例如表达相关匹配对可能选中不同表达状态的类型,对齐后与组成插值的配额不一致。但应该问题不大,因为对齐只影响坐标,组成插值影响细胞数量分配,两者独立。

好,确定。输出。

我会保持输出只有这个JSON。
</think>

```json
{
  "name": "在 T2HI-01 框架引入跨类型表达相关匹配对齐,修复最弱组 shape_scale",
  "motivation": "父节点10四组分 shape_scale=56.09 最弱(比最高 cell_state 66.54 低 10.45),ANALYSIS 归因于 exact-name 共有类型对齐较弱+目标 RMS 估偏。同树节点8已实证:把 Procrustes 对齐地标从 exact-name 换成跨类型表达相关贪心匹配对(Pearson r≥0.3、每侧≥30细胞),在 mix+簇抽样下使 shape_scale 52.78→55.93(+3.15,远超 T2 噪声~1),是全部增益来源。父节点10仍用 exact-name 对齐、未吸收该有效部件,故最弱组有明确、可解释且已被验证的结构问题可修,且不与已失败改法重复。",
  "approach": "在父节点10的 run.py 新增 matched_align 模块(移植/按节点8描述重写):对齐阶段计算两侧各型 pseudobulk 表达,按 Pearson 相关贪心选跨类型匹配对(初值 r≥0.3、每侧≥30 细胞、权重=min(两侧该型细胞数)),用匹配对质心做 Procrustes(xy Kabsch 允许反射,z 不旋转、符号由匹配质心 z 相关决定);匹配对<3 回退 exact-name,再回退 PCA。logit 组成插值、k-NN 簇抽样、逐细胞表达凸组合全部保持不变,只换对齐地标。开关 T2_MATCHED_ALIGN=1/0。单输入/外推退路不变(分层复制 anchor)。搜索范围小而快:r∈{0.25,0.3,0.4}×每侧最小细胞数∈{20,30}。用 vec-score 先跑 proxy seed0:仅当 shape_scale 提升>1 且总分不降才提交,否则回退 0。",
  "expected_groups": ["shape_scale", "local_spatial"],
  "risks": "1) 与节点11(节点8后续)可能重叠——Engineer 应先确认节点11是否已用同款对齐;2) proxy 只有5个共有类型,表达相关匹配对可能<3 而触发回退,导致机制未激活——必须打印实际匹配对数与是否回退;3) 节点10的 logit 组成插值改变配额,理论上与对齐独立,但若交互异常应先对齐后抽样验证;4) 30分钟时限紧,移植后先用单侧抽样子集确认对齐收敛再全量跑。",
  "family_id": "T2HI-01",
  "mechanism": "核心机制:以跨类型表达相关贪心匹配对的质心作为 Procrustes 对齐地标(替代 exact-name 共有类型),让两侧在表达相似而非仅同名的区域对齐,改善作用于全部细胞坐标的整体刚体+反射+缩放变换,从而更准确地定位目标形状。",
  "vs_constant_shift": "它不是对每个型加一个常位移向量、也不是全局组成重加权;而是改变对齐地标集合,进而改变作用于所有细胞的统一几何变换(旋转/平移/反射/缩放),每个细胞坐标的变化由全局对齐决定、随位置而异,不是统一常数偏移。",
  "mechanism_evidence": "Engineer 打印:实际选中匹配对数、各对 Pearson r、是否触发回退;并对比 matched-align 与 exact-name 两配置下的 shape_scale、local_spatial 与总分(A 半、多 seed)。匹配对数≥3 且 shape_scale 较 exact-name 提升>1(超噪声)即证明机制生效。",
  "mechanism_off_control": "T2_MATCHED_ALIGN=0 时回退父节点 exact-name 对齐、其余逻辑不变,预期输出与父节点10逐位一致(分数≈63.01、shape_scale≈56.09);若关闭后分数不变,说明机制未运行。",
  "sources": []
}
```
原始记录位置/home/spark-longxinyang/vec/runs/formal/20261003-043412-search-t2-heart-interp-g24-D-s1/nodes/12/researcher.jsonl 24 KB
/home/spark-longxinyang/vec/runs/formal/20261003-043412-search-t2-heart-interp-g24-D-s1/nodes/12/researcher.stderr