总览 · ← 返回运行 20261002-202908-search-t1-scr-D
节点 n5 在终选来历上
在父节点 per-type EB 位移之后,把每型位移向量投影到输入数据自身协变结构的 top-k PC 子空间再混合(k=25, β=1.0, HVG 8000),修复 covariation。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261002-202908-search-t1-scr-D |
|---|---|
| 父节点 | n4 |
| 子节点 | n8、n13 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 54.83(+0.4) · X3 54.83(+0.4) · 3 次复测均分 55.54 |
| 审查 | 未审查 |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 17 分 |
| 程序版本 | 97bb03e43e41a7b1aeb9009de9867e1c4dd9fd82 (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 97bb03e43e:solution/METHOD.md
在父节点 per-type EB 位移之后,把每型位移向量投影到输入数据自身协变结构的 top-k PC 子空间再混合(k=25, β=1.0, HVG 8000),修复 covariation。
方法(family: other / 父节点 4 + 低秩协变投影,PLAN 指定的 improve 部件)
完整保留父节点 4 的机制:copy_last 抽样 + 按 celltype 的最后两输入阶段基因均值差 δ_c + 基因级 EB 收缩 λ=δ²/(δ²+σ²(1/n1+1/n2)) + 时间缩放 α·r(α=1.5,r 只用相对时间差,clip [0,3])+ 只作用已有非零元 + max(0,·)。单输入视图严格退化 copy_last。
新增一步(本节点机制):
- 合并两个输入阶段的全部细胞(X3:1379+2174),用独立 rng 流抽 ≤3000 个(不影响 sample_rows 的抽样序列,β=0 时输出与父节点逐元素一致,已验证)。
- 按合并样本的逐基因方差取 top-8000 HVG,dense 化(3000×8000)并减基因均值(中心化,避免第一 PC 是均值方向,PLAN 风险 4)。
scipy.sparse.linalg.svds取前 k=25 个右奇异向量 V(8000×25,正交列,固定 v0 保证确定)。V 完全由视图输入数据驱动,无任何固定统计量。- 每型缩放后的位移 Δ_c = α·r·λ·δ_c:Δ̃_c = V(VᵀΔ_c)(限制在 HVG 上),混合 Δ_final = (1−β)Δ_c + β Δ̃_c;β=1.0 时非 HVG 基因位移为 0,HVG 基因位移取协调化方向。
- 其余(非零元施加、max(0,·)、写盘)与父节点完全相同。
参数:--proj-k 25 --proj-beta 1.0 --proj-hvg 8000 --proj-cells 3000(默认值,可用环境变量 VEC_PROJ_* 覆盖);--proj-beta 0 或 --proj-k 0 为机制关闭对照(完全旁路 SVD,输出与父节点逐元素一致)。
机制生效证据(mechanism_evidence,PLAN 要求)
- 每型 ||Δ̃||/||Δ|| 与 corr(Δ,Δ̃)(k=25,hvg8000):0.29–0.90 / 0.28–0.89,跨型有差异(SV-CM 0.90、IFT-CM 0.76、Endocardium 0.54、aSHF 0.29),非全 0/全 1 → 投影真实改变位移方向且保留大部分幅度(位移主要沿共表达程序,非纯噪声)。
- 四组分随 (k,β) 的变化符合 PLAN 预期:covariation 随 β 单调回升(k=25:45.3→46.0→47.2→47.8 @ β=0.25/0.5/0.75/1.0),cell_state 缓降(62.8→61.3),de_recovery 持平;k=8 过度(de_recovery 掉到 48.2),k=40 不足(covar 只到 46.9)→ k=25 是平台中部。
- 输出 nnz 比例 6.07%(父节点 6.05%),稀疏结构未破坏;mmd_u 0.0245(父 0.0241,对照 copy_last 0.034),细胞仍被移动。
- β=0 对照输出与父节点 4 逐元素一致((A!=B).nnz==0),强于 0.1 分容差要求。
查分记录(X3 A 半;seed0 除非注明;父节点 β=0:seed0 52.91 / seed1 53.80)
| 配置 | seed0 | seed1 | 均值 |
|---|---|---|---|
| k25 β1.0 hvg3000 | 53.36 | 53.94 | 53.65 |
| k15 β0.75 norm-preserving | 53.37 | 54.17 | 53.77 |
| k25 β1.0 hvg8000(提交) | 53.48 | 54.40 | 53.94 |
完整网格(seed0,hvg3000):k15 β∈{0.25,0.5,0.75,1.0} = 53.12/53.18/53.32/53.17;k25 = 53.14/53.19/53.23/53.36;k40 = 53.06/53.15/52.99/52.97;k8 β1.0 = 52.31;norm-preserving β1.0:k15 53.17、k25 53.27。共 20 次查分(额度用尽,k15 β1.0 hvg8000 未测)。
提交配置分组变化(相对父节点,seed0/seed1):covariation 45.32→47.65 / 45.55→47.65(+2.3/+2.1,两个 seed 一致,机制目标达成,接近节点 1 的 48.44);direction 49.62→50.72 / 51.20→52.36(+1.1);de_recovery 50.48→50.96 / 50.00→50.48(持平);cell_state 62.76→61.76 / 64.64→63.87(−1.0/−0.8);总分 +0.57/+0.60。
诚实评估:总分增益 ~+0.6 < 2 分噪声阈值,单看不算"进步";但 covariation +2.3 在两个 seed 和全部 16 个网格点上一致(β 单调),是结构性修复而非噪声。cell_state 的小幅代价来自 β=1 时非 HVG 基因位移归零。
验证过 / 没验证
- 验证:X3 vec-check ok;seed 0 双跑逐元素一致;β=0 对照 == 父节点输出(逐元素);最终默认参数输出 == 已查分的 k25_b1.0_h8000 预测(逐元素);运行 10s / 峰值内存远低于 28GB 限制;纯 CPU(EXECUTION.json gpu:false 不变)。
- 视图无关:只用相对时间差与视图数据;SVD 抽样用独立 rng 流
default_rng([seed, 0x5EED]),与视图路径/字段顺序/时间平移无关。 - 没验证:final 视图(r=1,有效位移减半,k/β 最优点可能漂移);proxy/proxy2;单输入退化路径代码未变(父节点已验证,本次未重跑);B 半真值。
- norm-preserving 变体(投影后按 ||Δ||/||Δ̃|| 恢复幅度)未超过普通混合,未采用。
知识来源
- 全部沿用父节点:标签改名词表(方法卡 §标签);EB 收缩公式(标准经验贝叶斯)。
- 新增部分只用视图内两个输入阶段的表达数据做 PCA,无外部数据、无 prior/、无禁窗信息、无固定统计量。
调研员的计划
| 名称 | 低秩投影协调 per-type EB 位移,修复 covariation |
|---|---|
| 动机 | 父节点 4 的四个分组中 covariation 45.90 最弱,且是唯一净损项(相对节点 1 的 48.44 下降 2.54);cell_state 65.64、de_recovery 51.85 已大幅领先,direction 50.46 仅 +1.26(噪声内)。covariation 损失的可解释结构原因:基因级 EB 收缩 λ_g=δ_g²/(δ_g²+σ²(1/n1+1/n2)) 对每个基因独立计算,只看该基因自己的 δ 与噪声,完全忽略基因间共变。结果是共表达程序里的基因被差异化收缩(有的保留全位移、相邻基因被缩到 0),逐基因独立噪声叠加 max(0,·) 截断,破坏了表达矩阵的共变结构(METHOD.md 记录稠密版 covariation 崩到 11.7、稀疏版仍 -3.3@α=1.5)。方向库允许'通路收缩/图平滑只作为 improve 部件',故本节点保留父节点机制,只修这一个结构问题。 |
| 做法 | 在父节点 run.py 的 EB 收缩之后、加位移之前插入一步:把每型的收缩位移向量 Δ_c=λ·δ_c 投影到数据自身协变结构张成的低秩子空间,再与原向量混合。步骤:(1) 合并两个输入阶段细胞,随机抽 ≤3000 个细胞、取方差最大的 2000–3000 个 HVG(或全基因面板,视内存而定,float32 3000×18k≈216MB 可接受),用 scipy.sparse.linalg.svds 取前 k 个右奇异向量 V(genes×k),不做逐基因标准化以免噪声基因主导;(2) 对每型 Δ_c 计算投影 Δ̃_c=V@(V.T@Δ_c);(3) 混合 Δ_final=(1-β)·Δ_c+β·Δ̃_c;(4) 其余完全沿用父节点:α=1.5、时间缩放 r、只作用非零元、max(0,·)、单输入退化 copy_last。参数初值与搜索:k 默认 25,网格 {15,25,40};β 默认 0.5,网格 {0,0.25,0.5,0.75,1.0}。用 vec-score 先跑 β=0(应复现父节点 ~52.9@A半)与 (k=25,β=0.5) 两点确认管线,再扫网格;前 2 名配置用 seed 1 复验,差距 <2 分视为噪声。查询预算 ≤20 次,SVD 一次性、秒级,总耗时仍在秒量级。若最优配置总分不超父节点(B半 54.45 对应 A半约 52.9),如实报告并保留父节点行为。 |
| 风险 | (1) 投影过强(k 太小或 β=1)会抹掉 de_recovery/cell_state 依赖的逐基因特异性位移,总分反降——Engineer 必须看四组分逐项变化而非只看总分,若 cell_state 掉 >3 分立即减小 β 或增大 k。(2) 协变方向由 PC 主导,若 δ 本身几乎不在前 k 个 PC 上(投影后范数 <30%),说明位移主要是不协调噪声,此时 β 应取大;反之取小,报告 ||Δ̃||/||Δ|| 作判据。(3) 真实可回收空间只有 ~2.5 分(45.9→48.4),在噪声边缘——需双 seed 确认,单点 +1 不算成功。(4) svds 在未中心化稀疏矩阵上第一主成分可能只是均值方向——若发现 V 的第一列近似常数,跳过它或先减基因均值(密集 1×n_genes,代价小)。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 1c84075fcf。改动的文件:solution/METHOD.md +32 −37、solution/README.md +6 −4、solution/run.py +87 −19
diff --git a/solution/METHOD.md b/solution/METHOD.mdindex b80f125..248461a 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,53 +1,48 @@-按细胞类型算 E(k-1)→E(k) 的基因均值差,做基因级 EB 收缩后按时间比例 α·r 只在非零元上加位移(保稀疏),外推到目标阶段。+在父节点 per-type EB 位移之后,把每型位移向量投影到输入数据自身协变结构的 top-k PC 子空间再混合(k=25, β=1.0, HVG 8000),修复 covariation。 -## 方法(family: other / per-type damped displacement + EB shrinkage)+## 方法(family: other / 父节点 4 + 低秩协变投影,PLAN 指定的 improve 部件) -在 copy_last(父节点 1)基础上加机制:+完整保留父节点 4 的机制:copy_last 抽样 + 按 celltype 的最后两输入阶段基因均值差 δ_c + 基因级 EB 收缩 λ=δ²/(δ²+σ²(1/n1+1/n2)) + 时间缩放 α·r(α=1.5,r 只用相对时间差,clip [0,3])+ 只作用已有非零元 + max(0,·)。单输入视图严格退化 copy_last。 -1. 读最后两个输入阶段(视图无关:只遍历 `manifest["inputs"]`,按 `time` 排序;只有 1 个输入时严格退化为 copy_last)。-2. 对两阶段都出现的每个 `celltype` c,算逐基因伪批量差 δ_c,g = mean_g(stage2|c) − mean_g(stage1|c)(log 空间)。-3. 基因级经验贝叶斯收缩:λ = δ²/(δ² + σ²·(1/n1+1/n2)),σ² 为两阶段组内方差均值;收缩后 Δ = λ·δ。-4. stage2 独有类型用静态词表映射找 stage1 亲本(V-CM ← LV-CM+RV-CM 合并;Endocardium/BEC ← Endothelium),映射不到用全局(所有细胞)δ;这是官方 T1 词汇的改名/拆分知识(方法卡 §标签),不涉及任何保留阶段测量。-5. 输出细胞 = 最后阶段细胞抽样(同 copy_last,`target_n_cells`),每个细胞在其类型位移上做 x_new = max(0, x + α·r·Δ),**只作用于已有非零元**(CSR data 原位修改),稀疏零结构不变。-6. r = (t_target − t_last)/(t_last − t_prev),clip 到 [0,3],只用相对时间差(视图平移不变)。X3 上 r=2(E9.0→E9.5 是 E8.75→E9.0 间隔的 2 倍),final 视图上 r=1,单输入视图 r 不适用(退化)。-7. α 默认 1.5(A 半上网格 {0,0.05,…,3} 选出,见下)。+新增一步(本节点机制): -## 关键实现发现+1. 合并两个输入阶段的全部细胞(X3:1379+2174),用独立 rng 流抽 ≤3000 个(不影响 sample_rows 的抽样序列,β=0 时输出与父节点逐元素一致,已验证)。+2. 按合并样本的逐基因方差取 top-8000 HVG,dense 化(3000×8000)并减基因均值(中心化,避免第一 PC 是均值方向,PLAN 风险 4)。+3. `scipy.sparse.linalg.svds` 取前 k=25 个右奇异向量 V(8000×25,正交列,固定 v0 保证确定)。V 完全由视图输入数据驱动,无任何固定统计量。+4. 每型缩放后的位移 Δ_c = α·r·λ·δ_c:Δ̃_c = V(VᵀΔ_c)(限制在 HVG 上),混合 Δ_final = (1−β)Δ_c + β Δ̃_c;β=1.0 时非 HVG 基因位移为 0,HVG 基因位移取协调化方向。+5. 其余(非零元施加、max(0,·)、写盘)与父节点完全相同。 -稠密加位移(对所有基因、含零元)会把 nnz 从 6% 涨到 28.5%,variogram 从 0.0016 涨到 0.0102,covariation 从 48.6 崩到 11.7(α=1 稠密版总分 42.6,**低于**对照)。改成只在非零元上加位移后 covariation 基本保住(45.3–47.6),总分大幅上升。这是本节点相对 PLAN 的主要修正。+参数:`--proj-k 25 --proj-beta 1.0 --proj-hvg 8000 --proj-cells 3000`(默认值,可用环境变量 VEC_PROJ_* 覆盖);`--proj-beta 0` 或 `--proj-k 0` 为机制关闭对照(完全旁路 SVD,输出与父节点逐元素一致)。 -## 查分记录(X3 A 半,seed 0,除非注明)+## 机制生效证据(mechanism_evidence,PLAN 要求) -| 变体 | 总分 | de_rec | dir | cell_state | covar |-|---|---|---|---|---|---|-| 对照 α=0(=copy_last) | 47.62 | 43.09 | 49.12 | 49.51 | 48.59 |-| 稠密 α=0.5 | 43.54 | 49.53 | 49.37 | 50.94 | 17.67 |-| 稀疏 α=0.25 | 49.28 | 47.32 | 49.34 | 51.75 | 47.97 |-| 稀疏 α=0.5 | 50.79 | 50.48 | 49.44 | 54.28 | 47.61 |-| 稀疏 α=1.0 | 52.14 | 50.48 | 49.64 | 59.25 | 46.69 |-| **稀疏 α=1.5(提交)** | **52.91** | 50.48 | 49.62 | 62.76 | 45.32 |-| 稀疏 α=2.0 | 52.97 | 50.48 | 49.61 | 64.14 | 43.50 |-| 稀疏 α=3.0 | 51.16 | 50.48 | 49.62 | 60.95 | 39.23 |-| 稀疏 α=1.5, seed 1 | 53.80 | 50.00 | 51.20 | 64.64 | 45.55 |+- 每型 ||Δ̃||/||Δ|| 与 corr(Δ,Δ̃)(k=25,hvg8000):0.29–0.90 / 0.28–0.89,跨型有差异(SV-CM 0.90、IFT-CM 0.76、Endocardium 0.54、aSHF 0.29),非全 0/全 1 → 投影真实改变位移方向且保留大部分幅度(位移主要沿共表达程序,非纯噪声)。+- 四组分随 (k,β) 的变化符合 PLAN 预期:covariation 随 β 单调回升(k=25:45.3→46.0→47.2→47.8 @ β=0.25/0.5/0.75/1.0),cell_state 缓降(62.8→61.3),de_recovery 持平;k=8 过度(de_recovery 掉到 48.2),k=40 不足(covar 只到 46.9)→ k=25 是平台中部。+- 输出 nnz 比例 6.07%(父节点 6.05%),稀疏结构未破坏;mmd_u 0.0245(父 0.0241,对照 copy_last 0.034),细胞仍被移动。+- β=0 对照输出与父节点 4 逐元素一致((A!=B).nnz==0),强于 0.1 分容差要求。 -α=1.5 与 2.0 差 0.06(噪声内),取 1.5 因 covariation 损失更小、更稳。相对对照 +5.3,远超 2 分噪声。+## 查分记录(X3 A 半;seed0 除非注明;父节点 β=0:seed0 52.91 / seed1 53.80) -## 机制生效证据(mechanism_off_control)+| 配置 | seed0 | seed1 | 均值 |+|---|---|---|---|+| k25 β1.0 hvg3000 | 53.36 | 53.94 | 53.65 |+| k15 β0.75 norm-preserving | 53.37 | 54.17 | 53.77 |+| **k25 β1.0 hvg8000(提交)** | **53.48** | **54.40** | **53.94** | -- 对照(α=0,同一程序):47.62 ≈ copy_last 47.92(B 半 vs A 半差异,在 0.5 容差内),确认管线本身无偏。-- λ 分布有区分度:各类型 f(λ>0.5) 在 0.08–0.24,中位 λ≈0(多数基因被收缩掉,非全 1/全 0)。-- 每类型 |λδ|>0.1 的基因数 368–3916(主类型 IFT-CM 737、Endocardium 584、Unknown 368),位移非平凡。-- 四组分变化(α=0 → 1.5):de_recovery 43.1→50.5,cell_state 49.5→62.8,direction 49.1→49.6,covariation 48.6→45.3(−3.3,超过 PLAN 预期的 −1,但总分净增;α=1.0 时 covariation 只 −1.9)。-- 输出稀疏度不变:nnz 比例 6.05%(对照 6.09%),细胞确实被移动(mmd_u 0.0344→0.0241,向真值靠近)。+完整网格(seed0,hvg3000):k15 β∈{0.25,0.5,0.75,1.0} = 53.12/53.18/53.32/53.17;k25 = 53.14/53.19/53.23/53.36;k40 = 53.06/53.15/52.99/52.97;k8 β1.0 = 52.31;norm-preserving β1.0:k15 53.17、k25 53.27。共 20 次查分(额度用尽,k15 β1.0 hvg8000 未测)。++提交配置分组变化(相对父节点,seed0/seed1):covariation 45.32→47.65 / 45.55→47.65(+2.3/+2.1,两个 seed 一致,机制目标达成,接近节点 1 的 48.44);direction 49.62→50.72 / 51.20→52.36(+1.1);de_recovery 50.48→50.96 / 50.00→50.48(持平);cell_state 62.76→61.76 / 64.64→63.87(−1.0/−0.8);总分 +0.57/+0.60。++**诚实评估**:总分增益 ~+0.6 < 2 分噪声阈值,单看不算"进步";但 covariation +2.3 在两个 seed 和全部 16 个网格点上一致(β 单调),是结构性修复而非噪声。cell_state 的小幅代价来自 β=1 时非 HVG 基因位移归零。 ## 验证过 / 没验证 -- 验证:X3 视图 vec-check ok;seed 0 双跑逐元素一致(确定);seed 1 分数 53.80;单输入合成视图(只留 input_0)跑通且 vec-check ok(copy_last 退路);`EXECUTION.json {"gpu": false}`(纯 CPU,秒级)。-- 没验证:final 视图(E8.5+E9.5→E10.5,r=1,有效位移只有 X3 的一半,α 最优值可能不同——但节点分数只按 X3);proxy2;B 半真值。-- α 是在 X3 A 半上选的,A/B 半差异可能让最优点漂移,但 α∈[1.0,2.0] 都在 52+ 的平台区,稳健。+- 验证:X3 vec-check ok;seed 0 双跑逐元素一致;β=0 对照 == 父节点输出(逐元素);最终默认参数输出 == 已查分的 k25_b1.0_h8000 预测(逐元素);运行 10s / 峰值内存远低于 28GB 限制;纯 CPU(EXECUTION.json gpu:false 不变)。+- 视图无关:只用相对时间差与视图数据;SVD 抽样用独立 rng 流 `default_rng([seed, 0x5EED])`,与视图路径/字段顺序/时间平移无关。+- 没验证:final 视图(r=1,有效位移减半,k/β 最优点可能漂移);proxy/proxy2;单输入退化路径代码未变(父节点已验证,本次未重跑);B 半真值。+- norm-preserving 变体(投影后按 ||Δ||/||Δ̃|| 恢复幅度)未超过普通混合,未采用。 ## 知识来源 -- 标签改名/拆分(Endothelium→Endocardium/BEC,LV/RV-CM→V-CM):任务书方法卡「T1 卡:E10.5 v1 §标签」,属通用词汇知识,不含保留阶段测量。-- EB 收缩公式 δ²/(δ²+σ²/n):标准经验贝叶斯(PLAN 指定)。-- 未使用 external/、prior/ 数据;未使用任何禁窗内信息。+- 全部沿用父节点:标签改名词表(方法卡 §标签);EB 收缩公式(标准经验贝叶斯)。+- 新增部分只用视图内两个输入阶段的表达数据做 PCA,无外部数据、无 prior/、无禁窗信息、无固定统计量。diff --git a/solution/README.md b/solution/README.mdindex 46d99f4..622d58b 100644--- a/solution/README.md+++ b/solution/README.md@@ -1,5 +1,7 @@-# per-type EB-shrunk displacement (sparse-only)+# per-type EB displacement + low-rank covariation projection -copy_last 基础上:按 celltype 算最后两个输入阶段的基因均值差,EB 收缩(λ=δ²/(δ²+σ²(1/n1+1/n2))),-乘 α·r(α 默认 1.5,r=外推时间/输入间隔)后只加在输出细胞的已有非零元上(保稀疏结构),max(0,·) 截断。-单输入视图严格退化为 copy_last;`--alpha 0` 为机制关闭对照。详见 METHOD.md。+父节点 4(copy_last + 按 celltype 的 EB 收缩位移,只作用非零元)之上加一步:+每型位移向量投影到输入数据自身协变结构的 top-k PC 子空间(合并两输入阶段 ≤3000 细胞、+top-8000 HVG、中心化、svds k=25),Δ_final=(1−β)Δ+βΔ̃,β=1.0。+修复父节点 covariation 净损(45.3→47.7)。`--proj-beta 0` 为机制关闭对照(输出与父节点逐元素一致)。+单输入视图退化 copy_last。详见 METHOD.md。diff --git a/solution/run.py b/solution/run.pyindex 8903ba9..03c8e3d 100644--- a/solution/run.py+++ b/solution/run.py@@ -1,29 +1,33 @@ #!/usr/bin/env python3-"""Per-type damped displacement with gene-level empirical-Bayes shrinkage.--Base: copy_last (output = cells of the latest input stage, subsampled).-Mechanism: for every cell type present in the two latest input stages, compute-the per-gene pseudobulk mean shift delta_g = mean(stage2|c) - mean(stage1|c) in-log space, shrink it with gene-level EB weights- lambda_g = delta_g^2 / (delta_g^2 + sigma_g^2 (1/n1 + 1/n2)),-and move each output cell by x_new = max(0, x + alpha * r * lambda * delta),-where r = (t_target - t_last) / (t_last - t_prev) rescales the observed step to-the extrapolation horizon (relative times only -> view independent).--Types present only in stage2 are matched to stage1 parents via a static-label-vocabulary map (general lineage knowledge, see METHOD.md); unmatched-types fall back to the global (all-cell) pseudobulk delta.-With a single input stage the program reduces exactly to copy_last.---alpha 0 disables the mechanism entirely (control, == copy_last).+"""Per-type EB-shrunk displacement + low-rank covariation projection.++Base (parent node 4): copy_last + per-type gene-mean shift between the two+latest input stages, gene-level EB shrinkage, time rescale alpha*r, applied at+existing nonzeros only, max(0, .).++New mechanism (this node): each type's shrunk displacement vector+Delta_c = alpha*r*lambda*delta_c is projected onto the top-k principal+directions V of the input data's own gene covariance (cells of both input+stages, centered, top-HVG subset), and mixed back:+ Delta_final = (1-beta)*Delta_c + beta * V (V^T Delta_c).+This makes the displacement move along coordinated co-expression programs+instead of perturbing every gene independently, targeting the covariation+regression of the parent. beta=0 or k=0 bypasses the projection entirely and+reproduces the parent element-wise.++View independence: V is computed from the view's own input matrices; only+relative time differences are used. Single input stage -> exact copy_last. """ from __future__ import annotations import argparse import os+import sys import numpy as np from scipy import sparse+from scipy.sparse.linalg import svds from src.task1_temporal.view_io import ( inputs_by_time,@@ -64,6 +68,33 @@ def group_means(X: sparse.csr_matrix, labels: np.ndarray, groups: dict[str, np.n return out +def covariation_basis(Xa: sparse.csr_matrix, Xb: sparse.csr_matrix,+ k: int, n_hvg: int, n_cells: int, rng: np.random.Generator):+ """Top-k right singular vectors of the centered, HVG-restricted pool of+ cells from both input stages. Returns (hvg_idx, V) with V orthonormal+ (n_hvg, k)."""+ X = sparse.vstack([Xa.tocsr(), Xb.tocsr()], format="csr")+ n = X.shape[0]+ if n_cells < n:+ sel = rng.choice(n, size=n_cells, replace=False)+ sel.sort()+ X = X[sel]+ # per-gene variance over the pooled sample (sparse-friendly)+ m1 = np.asarray(X.mean(axis=0), dtype=np.float64).ravel()+ m2 = np.asarray(X.multiply(X).mean(axis=0), dtype=np.float64).ravel()+ var = np.maximum(m2 - m1 * m1, 0.0)+ g = int(min(n_hvg, X.shape[1]))+ hvg = np.argpartition(-var, g - 1)[:g]+ hvg.sort()+ D = np.asarray(X[:, hvg].todense(), dtype=np.float64)+ D -= D.mean(axis=0, keepdims=True)+ kk = int(min(k, min(D.shape) - 1))+ v0 = rng.standard_normal(min(D.shape))+ _, _, Vt = svds(D, k=kk, v0=v0)+ V = np.ascontiguousarray(Vt[::-1].T) # (g, kk), descending singular values+ return hvg, V++ def main() -> None: parser = argparse.ArgumentParser() parser.add_argument("--data", required=True)@@ -71,6 +102,16 @@ def main() -> None: parser.add_argument("--seed", type=int, default=0) parser.add_argument("--alpha", type=float, default=float(os.environ.get("VEC_ALPHA", "1.5")))+ parser.add_argument("--proj-k", type=int,+ default=int(os.environ.get("VEC_PROJ_K", "25")))+ parser.add_argument("--proj-beta", type=float,+ default=float(os.environ.get("VEC_PROJ_BETA", "1.0")))+ parser.add_argument("--proj-hvg", type=int,+ default=int(os.environ.get("VEC_PROJ_HVG", "8000")))+ parser.add_argument("--proj-cells", type=int,+ default=int(os.environ.get("VEC_PROJ_CELLS", "3000")))+ parser.add_argument("--proj-norm", action="store_true",+ default=os.environ.get("VEC_PROJ_NORM", "") == "1") parser.add_argument("--no-time-scale", action="store_true", default=os.environ.get("VEC_NO_TIME_SCALE", "") == "1") args = parser.parse_args()@@ -83,6 +124,8 @@ def main() -> None: last = read_stage(args.data, entries[-1], genes) rows = sample_rows(last.n_obs, target_n_cells(manifest, last.n_obs), rng) + use_proj = args.proj_k > 0 and args.proj_beta != 0.0+ if len(entries) >= 2 and args.alpha != 0.0: prev = read_stage(args.data, entries[-2], genes) lab1 = labels_of(prev)@@ -130,12 +173,33 @@ def main() -> None: r = float(np.clip((t_tgt - t_last) / (t_last - t_prev), 0.0, CAP_R)) scale = args.alpha * r - # shift only the sampled output cells, at existing nonzeros only- # (preserves the sparse zero structure -> covariation intact)+ # low-rank covariation basis from the two input stages (own rng stream,+ # keeps the sample_rows draw above identical to the parent)+ hvg = V = None+ if use_proj:+ rng_proj = np.random.default_rng(np.array([args.seed, 0x5EED], dtype=np.int64))+ hvg, V = covariation_basis(prev.X.tocsr(), last.X.tocsr(),+ args.proj_k, args.proj_hvg,+ args.proj_cells, rng_proj)++ beta = float(args.proj_beta)+ diag = [] Xs = last.X[rows].tocsr() labs = lab2[rows] for t in np.unique(labs):- d = (scale * delta_for(str(t))).astype(np.float32)+ d = scale * delta_for(str(t))+ if use_proj:+ dv = d[hvg]+ tilde = V @ (V.T @ dv)+ nd, nt = float(np.linalg.norm(dv)), float(np.linalg.norm(tilde))+ if args.proj_norm and nt > 0:+ tilde *= nd / nt+ corr = float(np.corrcoef(dv, tilde)[0, 1]) if nd > 0 and nt > 0 else 0.0+ diag.append((str(t), int((labs == t).sum()), nt / max(nd, 1e-12), corr))+ df = (1.0 - beta) * d+ df[hvg] += beta * tilde+ d = df+ d = d.astype(np.float32) tmask = np.flatnonzero(labs == t) for i in tmask: lo, hi = Xs.indptr[i], Xs.indptr[i + 1]@@ -143,6 +207,10 @@ def main() -> None: cols = Xs.indices[lo:hi] Xs.data[lo:hi] = np.maximum(Xs.data[lo:hi] + d[cols], 0.0) X = Xs+ if use_proj and diag:+ print("proj diag (type, n_cells, ||proj||/||d||, corr):", file=sys.stderr)+ for row in diag:+ print(" %-16s %4d %.3f %.3f" % row, file=sys.stderr) else: X = last.X[rows]
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| k018 | Damped per-type shift: shrinkage alpha on the observed delta | notes/plan/cards/T1.md |
| k031 | Offline OT toolkit in the sandbox: moscot TemporalProblem, wot OTModel, POT, geomloss | 10.1038/s41586-024-08453-2 (moscot); 10.1016/j.cell.2019.01.006 (Waddington-OT) |
| k041 | Within-stage pseudotime and graph toolkit offline: scanpy DPT/PAGA/Leiden, Palantir, CellRank 2 | 10.1186/s13059-019-1663-x (PAGA); 10.1038/s41587-019-0068-4 (Palantir); 10.1038/s41592-024-02303-9 (CellRank 2) |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 在父节点 4(copy_last + per-type EB 收缩位移,只作用非零元)之后插入一步低秩协变投影:合并两输入阶段 ≤3000 细胞、top-8000 HVG、中心化后 svds 取 k=25 个 PC,每型位移 Δ_final=(1−β)Δ+βV(VᵀΔ),提交 β=1.0;β=0/k=0 完全旁路并逐元素复现父节点(独立 rng 流保证抽样序列不变)。 |
|---|---|
| 各组分数的变化 | cell_state:变坏:-1.30(65.64→64.34),在噪声内但与 PLAN 预期一致(β=1 时非 HVG 基因位移归零),满足 PLAN 约束 <2 分 covariation:变好:+2.30(45.90→48.20),略超 2 分噪声线,且 Engineer 报告两 seed(+2.3/+2.1)与 16 个网格点随 β 单调一致,可判定为结构性修复 de_recovery:噪声内:+0.49(51.85→52.34) direction:噪声内:+0.76(50.46→51.22) 总分:噪声内:+0.38(54.45→54.83);代价:耗时 1.4→8.6s,内存 0.34→0.71GB,仍远低于限制 |
| family_id | other |
| 假设是否成立 | 是 |
| 经验 |
|
| mechanism_active | 是 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 3 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 2 次:bash 1、write 1 |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 10,994 · 输出 1,266 · 思考 907 |
| 任务(第一行) | 分析节点 n5 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261002-202908-search-t1-scr-D/nodes/5/analyst.jsonl 7 KB /home/spark-longxinyang/vec/runs/formal/20261002-202908-search-t1-scr-D/nodes/5/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 22 |
| 工具调用 | 共 27 次:bash 19、write 3、edit 3、read 2 |
| 用时 | 13 分 |
| token 数 | 输入 56,708 · 输出 10,758 · 思考 11,593 |
| 任务(第一行) | 按计划修改程序:低秩投影协调 per-type EB 位移,修复 covariation |
| 最后的回答(摘录) | 完成。 **做了什么**:按 PLAN 在父节点 4(per-type EB 位移)后插入低秩协变投影——合并两输入阶段 ≤3000 细胞、top-8000 HVG、中心化后 svds 取 k=25 个 PC,每型位移 Δ_final=(1−β)Δ+βV(VᵀΔ),提交 β=1.0。扫了 16 个 (k,β,hvg,norm) 配置,用满 20 次查分。 **查分结果**(X3 A 半):提交配置 seed0 53.48 / seed1 54.40(均值 53.94 vs 父 53.36)。covariation 45.3→47.7(两 seed 一致 +2.2,β 单调,机制目标达成),direction +1.1,de_recovery 持平,cell_state −0.9;总分 +0.6 在 2 分噪声内,但分组修复是结构性的。β=0 对照与父节点输出逐元素一致;确定性、单输入退化、vec-check 全通过;运行 7s。 **下一步最值得试**:(1) β=1 时非 HVG 基因位移归零导致 cell_state 小损——试"非 HVG 基因保留 (1−β')Δ、HVG 用投影"的两段式,或 hvg=12000+;(2) 与节点 2/3 的 OT 耦合组合(direction 组分两边都弱,~50);(3) final 视图 r=1 时重新校准 α。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261002-202908-search-t1-scr-D/nodes/5/engineer.jsonl 129 KB /home/spark-longxinyang/vec/runs/formal/20261002-202908-search-t1-scr-D/nodes/5/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 2 分 |
| token 数 | 输入 13,369 · 输出 1,422 · 思考 4,105 |
| 任务(第一行) | 为节点 n5(改进,父节点 n4)写改进计划 PLAN.json |
| 最后的回答(摘录) | 程序里的基因被差异化收缩(有的保留全位移、相邻基因被缩到 0),逐基因独立噪声叠加 max(0,·) 截断,破坏了表达矩阵的共变结构(METHOD.md 记录稠密版 covariation 崩到 11.7、稀疏版仍 -3.3@α=1.5)。方向库允许'通路收缩/图平滑只作为 improve 部件',故本节点保留父节点机制,只修这一个结构问题。",
"approach": "在父节点 run.py 的 EB 收缩之后、加位移之前插入一步:把每型的收缩位移向量 Δ_c=λ·δ_c 投影到数据自身协变结构张成的低秩子空间,再与原向量混合。步骤:(1) 合并两个输入阶段细胞,随机抽 ≤3000 个细胞、取方差最大的 2000–3000 个 HVG(或全基因面板,视内存而定,float32 3000×18k≈216MB 可接受),用 scipy.sparse.linalg.svds 取前 k 个右奇异向量 V(genes×k),不做逐基因标准化以免噪声基因主导;(2) 对每型 Δ_c 计算投影 Δ̃_c=V@(V.T@Δ_c);(3) 混合 Δ_final=(1-β)·Δ_c+β·Δ̃_c;(4) 其余完全沿用父节点:α=1.5、时间缩放 r、只作用非零元、max(0,·)、单输入退化 copy_last。参数初值与搜索:k 默认 25,网格 {15,25,40};β 默认 0.5,网格 {0,0.25,0.5,0.75,1.0}。用 vec-score 先跑 β=0(应复现父节点 ~52.9@A半)与 (k=25,β=0.5) 两点确认管线,再扫网格;前 2 名配置用 seed 1 复验,差距 <2 分视为噪声。查询预算 ≤20 次,SVD 一次性、秒级,总耗时仍在秒量级。若最优配置总分不超父节点(B半 54.45 对应 A半约 52.9),如实报告并保留父节点行为。",
"expected_groups": ["covariation", "de_recovery"],
"risks": "(1) 投影过强(k 太小或 β=1)会抹掉 de_recovery/cell_state 依赖的逐基因特异性位移,总分反降——Engineer 必须看四组分逐项变化而非只看总分,若 cell_state 掉 >3 分立即减小 β 或增大 k。(2) 协变方向由 PC 主导,若 δ 本身几乎不在前 k 个 PC 上(投影后范数 <30%),说明位移主要是不协调噪声,此时 β 应取大;反之取小,报告 ||Δ̃||/||Δ|| 作判据。(3) 真实可回收空间只有 ~2.5 分(45.9→48.4),在噪声边缘——需双 seed 确认,单点 +1 不算成功。(4) svds 在未中心化稀疏矩阵上第一主成分可能只是均值方向——若发现 V 的第一列近似常数,跳过它或先减基因均值(密集 1×n_genes,代价小)。",
"family_id": "other",
"mechanism": "把每型 EB 收缩后的基因位移向量投影到输入数据自身协变结构(低秩 PC 子空间)张成的方向上,使位移沿共表达程序协调移动而非逐基因独立扰动,β 控制协调化强度。",
"vs_constant_shift": "常数位移对每型所有基因加同一标量、不利用任何基因间结构;本方案位移仍是型×基因特异的(继承 δ_c 与 EB 权重),且投影方向完全由输入两阶段的基因共变数据驱动,随视图数据变化,不含任何固定统计量或禁窗信息。",
"mechanism_evidence": "Engineer 应报告:(1) 每型 ||Δ̃_c||/||Δ_c|| 与逐基因 corr(Δ_c, Δ̃_c),应介于 0 和 1 之间且跨型有差异(非全 0/全 1),证明投影真实改变了位移方向;(2) 四组分随 (k,β) 的矩阵——预期 covariation 随 β 单调或单峰回升、cell_state/de_recovery 基本持平;(3) 输出 nnz 比例仍 ≈6.05%、mmd_u 仍低于对照,确认稀疏性与细胞移动未被破坏;(4) β=0 时逐元素等于父节点输出。",
"mechanism_off_control": "同一程序加 --proj-beta 0(或 --proj-k 0):混合系数 β=0 时 Δ_final≡Δ_c,投影步骤被旁路,输出应与父节点 4(α=1.5)逐元素一致、分数在 0.1 容差内(A半 ~52.9)。预期打开机制后(β>0):covariation 上升 ≥1.5 分而 cell_state 损失 <2 分;若关闭与打开输出完全相同,说明投影未运行,需检查 V 是否退化。",
"sources": []
}
``` |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261002-202908-search-t1-scr-D/nodes/5/researcher.jsonl 5 KB /home/spark-longxinyang/vec/runs/formal/20261002-202908-search-t1-scr-D/nodes/5/researcher.stderr |