总览 · ← 返回运行 20261003-105537-search-t2-heart-extrap-g24-D
节点 n14
CollecTRI 调控方向先验逐基因符号微扰:已实现并实测,α=0.25 得 43.65(de_direction 原始 −0.0004≈0,方向先验无信号;variogram 0.058→0.172 严重受损),按 PLAN 停止规则以机制关闭态提交(VEC_ALPHA=0,输出逐位=copy_last,对照实测 50.00)。
| 运行?一次完整的自动搜索或 Agent 会话,有自己的锁定配置和证据包。 | 20261003-105537-search-t2-heart-extrap-g24-D |
|---|---|
| 父节点 | n12 |
| 子节点 | n16、n19 |
| 操作?种子:人写的起点;改进:在父节点上改;草稿:从头写;修复:修父节点的报错。 | 改进 |
| 状态 | 已打分 |
| 分数 | 搜索目标分 50.00(+0.0) · proxy_noscale 50.00(+0.0) |
| 审查 | 未审查 |
| 用时?从运行开始到结束(或到现在)的挂钟时间。 | 13 分 |
| 程序版本 | 0a2432bccc7d58783704f96652390b92b4514d1a (programs.git) |
方法说明?节点程序自带的 METHOD.md:这个程序做了什么、为什么。
来自 programs.git 0a2432bccc:solution/METHOD.md
CollecTRI 调控方向先验逐基因符号微扰:已实现并实测,α=0.25 得 43.65(de_direction 原始 −0.0004≈0,方向先验无信号;variogram 0.058→0.172 严重受损),按 PLAN 停止规则以机制关闭态提交(VEC_ALPHA=0,输出逐位=copy_last,对照实测 50.00)。
方法(PLAN:CollecTRI 调控方向先验驱动的逐基因符号微扰)
- 基座与父节点 12 对照相同:anchor=末观测阶段(
anchor_entry),n 夹到 [min_cells, max_cells],take按型分层抽样,X 与坐标原样输出。 - 机制(
VEC_ALPHA>0时启用):- 读
<view>/prior/tf_regulons/collectri_mouse.tsv.gz(TF→target,mor 符号);只用 TF 与 target 都在输出面板内的边(本视图 411 条边、94 个面板内 TF、覆盖 176/500 基因;TF 列 UniProt 型仅 7 个,匹配率风险解除,未触发 PLAN 风险 3 的放弃条件); - activity_t = anchor 输出细胞中 TF t 的平均表达;score_g = Σ_{t→g} sign(t→g)×activity_t;
- S = |score_g| > median(|score|)(median=0,S=176 个 score≠0 的基因);sign_g = sign(score_g),g∉S 时 0;
- X_new[:,g] = clip(X[:,g] + α·sign_g·std_g, 0, ∞),std_g = anchor 输出细胞的逐基因 std。
- 不依赖第二时间点,单输入视图天然兼容;不改坐标、细胞数、组成。
- 读
- 机制关闭对照(PLAN mechanism_off_control):
VEC_ALPHA=0(当前默认)跳过全部微扰,输出逐位等于 copy_last。
对照与实测(proxy_noscale,4 次查分)
- 对照 α=0:50.00,八项全部 skill=0.5(de_score/de_direction 原始 0,无变化保护生效)。✓ 与父节点对照逐位一致(同 seed 同基座代码路径)。
- α=0.25:43.65。机制证据核验:
- de_direction 原始 −0.0004 ≈ 0:CollecTRI 净调控输入与真实 E8.75→E9.5 变化方向的秩相关为零,方向先验假设被否证(PLAN 风险 1 成真);
- de_score 原始 −0.389:按 dp=α·sign_g·std_g 排序选出的"变化基因"比 chance 更差——符号场虽无方向信号,但幅度由 std_g 主导,把高 std 基因系统性推入 top 名单,反而低于随机;
- variogram 原始 0.0581→0.1721(组 35.8):逐基因常数位移虽不改细胞间成对差,但 clip(X+Δ,0,∞) 在低表达基因上截断,破坏了基因间共变结构;
- mmd_u 0.0586→0.0677、neighborhood_mmd 0.1145→0.1316:位移分布整体偏移,均劣化;
- 形状三项不变(机制不动坐标)。
- PLAN 停止规则"α=0.25 总分<50 → 立即以对照提交"触发,未再测 α=0.5(α 只会线性放大同一错误方向场与 clip 损伤)。
- 附加探索(非 PLAN,1 次查分):分层稀释输出细胞到 50%(12413 个)检验"细胞密度→15-NN 覆盖半径→neighborhood_mmd"假设:47.74,neighborhood_mmd 0.1145→0.1198 反而变差,且抽样噪声使 DE 脱离无变化保护(de_score −0.222)。真值阶段的邻域平均不比 anchor 全密度输出更平滑,密度假设被否证。该变体未写入 run.py。
结论与教训
- 本榜四个已试方向族全部否证:坐标/配对重排(node3/5/7/9/10/12)、速度/PCA 位移(node2/4/6/8/11)、CollecTRI 符号微扰(本节点)、细胞密度稀释(本节点)。de_direction≈0 说明"哪些基因将变"在本视图可用信息(面板表达 + 通用调控网络结构)里没有可提取的信号;任何非零 dp 都会同时付出 variogram/mmd_u/neighborhood_mmd 的分布损伤代价,而 DE 组收益为零或负——expression_change 组的"无变化保护=地板"实际上是本榜现有信息下的局部最优。
- 提交 = 对照(copy_last),预期榜分 50.00(B 半噪声内)。
验证过 / 没验证
- 验证过:对照=50.00 且与父节点对照八项原始值一致;α=0.25 全指标分解;同 seed 双跑输出逐位相同(确定性);vec-score status=scored(格式合规;vec-check 对本 client 拒绝该 task,无法直接跑);代码不读绝对时间/阶段名/board 字段,α=0 路径不读 prior,时间平移伪装下输出不变。
- 没验证:α=0.5(停止规则触发,方向已由 α=0.25 的 de_direction≈0 判定);sign 随机打乱对照(PLAN 证据 3——α=0.25 的 de_direction 本身已≈0,与打乱预期无异,省 1 次查分);仅对 score 连续值加权(非符号化)的微扰变体。
- 运行时 ~2s(对照路径),内存 <1 GB。
知识来源
- CollecTRI 转录因子调控网络(TF→target 激活/抑制符号):来自视图内
prior/tf_regulons/,属"不针对禁窗阶段的通用机制知识",不含任何保留阶段/基因型的测量信息。 - 无其他外部知识;未使用任何已发布阶段的尺寸、比例或表达统计常数。
下一步建议
- 本榜在"仅 anchor + 通用先验"的信息集下,50.00 可能已接近可达上限;建议停止微扰/重排家族的尝试。
- 若继续,唯一未动过且不依赖方向的量是输出细胞组成的再加权(composition 不参与排名指标,但影响 mmd_u/neighborhood_mmd 的分布位置)——但 node 系列已间接说明分布移动类操作在此榜全部劣化,预期收益低。
调研员的计划
| 名称 | CollecTRI 调控方向先验驱动的逐基因符号微扰(expression_change 组) |
|---|---|
| 动机 | 全部 14 个节点中,除 node5(52.74,已证为抽样运气)外均≤50。四组全在地板(50.00)。父节点 12 的 ANALYSIS 明确指出:坐标/配对类操作(T2HX-06 两次、T2HX-04、T2HX-03)已全部失败,唯一未试尽的方向是 expression_change 组(de_score=de_direction=0,因无变化保护 std(dp)=0)。node2/3/4/8 的速度/PCA 位移失败原因是方向来源(两时间点速度、PCA 轴)在外推榜无信号;但 prior/ 中的 CollecTRI 调控网络提供了独立于速度的方向先验,尚未被任何节点使用。 |
| 做法 | 步骤: 1. 基座与父节点相同:anchor=末观测阶段,n 夹到 [min_cells, max_cells],take 按型分层抽样,坐标原样输出。 2. 加载 prior/ 中 CollecTRI(TF→target, sign∈{+1,−1})。对每个 TF t,计算 activity_t = mean(X[:, t])(anchor 中该 TF 的平均表达)。对每个基因 g,计算调控净输入 score_g = Σ_{t→g} sign(t→g) × activity_t。取 |score_g| > median(|score|) 的基因作为受扰动集合 S(约 50% 基因)。 3. 对 g∈S,sign_g = sign(score_g);对 g∉S,sign_g = 0。逐基因标准差 std_g = std(X[:, g])。 4. 微扰:X_new[:, g] = clip(X[:, g] + α × sign_g × std_g, 0, +∞)。α 网格 {0.25, 0.5}(环境变量 VEC_ALPHA)。α=0 为关闭对照。 5. 单输入阶段退路:本方案只依赖 anchor 阶段的表达矩阵和 prior 网络,不需要第二个时间点,天然兼容单阶段。 6. 查分策略:先跑 α=0 对照确认=50.00(1 次查分);再跑 α=0.25(1 次);若 de_direction>0 且总分≥51 则跑 α=0.5(1 次);否则停止。共≤4 次查分。若 α=0.25 总分<50,立即以对照提交。 7. 关键约束:不改变坐标、不改变细胞数、不改变组成;微扰幅度≤0.5×std_g,保证 mmd_u/variogram/neighborhood_mmd 在噪声内。 |
| 风险 | 1) CollecTRI 的调控方向可能不预测 E8.5→E9.5 的真实变化方向(如某些基因在该阶段受其他机制主导),导致 de_direction<0、DE 组反降。Engineer 应在第一次 α=0.25 查分后立即检查 de_direction 原始值:若<0 则停止,以对照提交。2) 微扰可能轻微影响 mmd_u(分布偏移);α≤0.5×std 时预期影响<噪声(1分),若 mmd_u 组降>1 分则回落对照。3) prior/ 中 CollecTRI 格式或基因名与 panel 不完全匹配;Engineer 应先统计匹配率,若<30% 则方案退化为随机方向,应放弃并以对照提交。 |
代码改动?这个节点的程序和父节点程序的逐行差别:绿色是新增,红色是删除。
对比:父节点版本 c6ef840565。改动的文件:solution/METHOD.md +30 −26、solution/run.py +83 −142
diff --git a/solution/METHOD.md b/solution/METHOD.mdindex 8546109..44b383b 100644--- a/solution/METHOD.md+++ b/solution/METHOD.md@@ -1,41 +1,45 @@-表达kNN引导坐标置换(T2HX-06,node5复刻):机制已实现并实测,贪心2-opt交换49759对细胞-坐标配对使内部cosine-15NN目标下降,但neighborhood_mmd原始值反升(0.11445→0.1152)、d2_shape变差,总分49.85<地板50,按PLAN停止规则默认关闭(VEC_NSWAPS=0),提交输出逐位等于copy_last。+CollecTRI 调控方向先验逐基因符号微扰:已实现并实测,α=0.25 得 43.65(de_direction 原始 −0.0004≈0,方向先验无信号;variogram 0.058→0.172 严重受损),按 PLAN 停止规则以机制关闭态提交(VEC_ALPHA=0,输出逐位=copy_last,对照实测 50.00)。 -## 方法+## 方法(PLAN:CollecTRI 调控方向先验驱动的逐基因符号微扰) -1. 基座与父节点3完全相同:anchor=末观测阶段,n 夹到 [min_cells, max_cells],`take` 按型分层抽样,X 与坐标原样输出。-2. 机制层(T2HX-06,`VEC_NSWAPS>0` 时启用):- - 表达 kNN:完整表达矩阵 cosine,k=15(与评分 neighborhood_mmd 的 15-NN 对齐),另取 16 邻做候选;- - 空间 kNN:坐标 euclidean,缓存 pool=60 近邻;- - 候选对:表达 kNN 中不在空间 15-NN 内的 (i,j),去重后按 seed 洗牌;- - 贪心 2-opt:交换 i、j 坐标,Δ = 受影响细胞集(i、j、两者的空间近邻)各自"与空间 15-NN 表达的 cosine 距离和"的变化(候选池 = 静态 pool + 显式加入换位的 i/j),Δ<0 接受并交换 pool,无交换次数上限(修正 node10 的预算约束);迭代 3 轮,每轮重算空间 kNN。- - 输出保证:X 逐位不变,坐标点集(多重集)逐位不变(程序内校验),仅细胞-坐标配对改变。-3. 机制关闭对照(PLAN mechanism_off_control):`VEC_NSWAPS=0`(**当前默认**)跳过全部交换循环。+1. 基座与父节点 12 对照相同:anchor=末观测阶段(`anchor_entry`),n 夹到 [min_cells, max_cells],`take` 按型分层抽样,X 与坐标原样输出。+2. 机制(`VEC_ALPHA>0` 时启用):+ - 读 `<view>/prior/tf_regulons/collectri_mouse.tsv.gz`(TF→target,mor 符号);只用 TF 与 target 都在输出面板内的边(本视图 411 条边、94 个面板内 TF、覆盖 176/500 基因;TF 列 UniProt 型仅 7 个,匹配率风险解除,未触发 PLAN 风险 3 的放弃条件);+ - activity_t = anchor 输出细胞中 TF t 的平均表达;score_g = Σ_{t→g} sign(t→g)×activity_t;+ - S = |score_g| > median(|score|)(median=0,S=176 个 score≠0 的基因);sign_g = sign(score_g),g∉S 时 0;+ - X_new[:,g] = clip(X[:,g] + α·sign_g·std_g, 0, ∞),std_g = anchor 输出细胞的逐基因 std。+ - 不依赖第二时间点,单输入视图天然兼容;不改坐标、细胞数、组成。+3. 机制关闭对照(PLAN mechanism_off_control):`VEC_ALPHA=0`(**当前默认**)跳过全部微扰,输出逐位等于 copy_last。 -## 对照与实测(proxy_noscale,3 次查分)+## 对照与实测(proxy_noscale,4 次查分) -- 对照 VEC_NSWAPS=0:**50.00**,四组全 50,输出 = copy_last。✓(管线无副作用)-- 全量置换(3 轮,49759 次交换,412s,坐标多重集校验通过):**49.85**- - neighborhood_mmd 原始 0.11445 → **0.1152(升高,机制方向失败)**,local_spatial 49.84;- - d2_shape 0.04891 → 0.04944(变差),occupancy_dice 0.8148 → 0.8145(差 0.0003 < 0.002,按 PLAN 视为噪声),shape_scale 49.57;- - 表达两组、cell_state 逐位不变(机制只动配对)。-- PLAN 停止规则:"若 neighborhood_mmd 原始值未降,停止调参、以对照提交" → 触发,默认 VEC_NSWAPS=0。+- 对照 α=0:**50.00**,八项全部 skill=0.5(de_score/de_direction 原始 0,无变化保护生效)。✓ 与父节点对照逐位一致(同 seed 同基座代码路径)。+- α=0.25:**43.65**。机制证据核验:+ - de_direction 原始 **−0.0004 ≈ 0**:CollecTRI 净调控输入与真实 E8.75→E9.5 变化方向的秩相关为零,方向先验假设被否证(PLAN 风险 1 成真);+ - de_score 原始 **−0.389**:按 dp=α·sign_g·std_g 排序选出的"变化基因"比 chance 更差——符号场虽无方向信号,但幅度由 std_g 主导,把高 std 基因系统性推入 top 名单,反而低于随机;+ - variogram 原始 0.0581→**0.1721**(组 35.8):逐基因常数位移虽不改细胞间成对差,但 clip(X+Δ,0,∞) 在低表达基因上截断,破坏了基因间共变结构;+ - mmd_u 0.0586→0.0677、neighborhood_mmd 0.1145→0.1316:位移分布整体偏移,均劣化;+ - 形状三项不变(机制不动坐标)。+ - PLAN 停止规则"α=0.25 总分<50 → 立即以对照提交"触发,未再测 α=0.5(α 只会线性放大同一错误方向场与 clip 损伤)。+- 附加探索(非 PLAN,1 次查分):分层稀释输出细胞到 50%(12413 个)检验"细胞密度→15-NN 覆盖半径→neighborhood_mmd"假设:**47.74**,neighborhood_mmd 0.1145→0.1198 反而变差,且抽样噪声使 DE 脱离无变化保护(de_score −0.222)。真值阶段的邻域平均不比 anchor 全密度输出更平滑,密度假设被否证。该变体未写入 run.py。 -## 机制证据与结论(family T2HX-06)+## 结论与教训 -- 机制确实生效:改变了 49759 对细胞-坐标配对(约 2×细胞数的配对尝试中接受 ~1.6 万次/轮),内部目标(Σ cosine 距离到空间 15-NN)单调下降。-- 但内部目标与评分指标不同向:把表达相似的细胞搬成空间邻居会"锐化"预测的邻域平均表达分布,而真值 E9.5 的邻域平均分布并不更锐,MMD 反而变大。这解释了 node5(52.74)的 shape_scale 59.99 更可能来自行序改变导致的评分器子抽样差异(PLAN 风险 1),而非可复现的机制收益——本次实现中 occupancy_dice 变化 < 0.002(噪声),d2_shape 变差。-- node7/9(Dirichlet 能量目标)与本次(cosine-15NN 目标)两种目标函数都实测低于地板:坐标配对置换家族在无真值方向信息的外推榜上没有可靠收益。+- 本榜四个已试方向族全部否证:坐标/配对重排(node3/5/7/9/10/12)、速度/PCA 位移(node2/4/6/8/11)、CollecTRI 符号微扰(本节点)、细胞密度稀释(本节点)。de_direction≈0 说明"哪些基因将变"在本视图可用信息(面板表达 + 通用调控网络结构)里没有可提取的信号;任何非零 dp 都会同时付出 variogram/mmd_u/neighborhood_mmd 的分布损伤代价,而 DE 组收益为零或负——expression_change 组的"无变化保护=地板"实际上是本榜现有信息下的局部最优。+- 提交 = 对照(copy_last),预期榜分 50.00(B 半噪声内)。 ## 验证过 / 没验证 -- 验证过:对照=50.00 逐位等于 copy_last;全量置换 49.85 及四组分解;坐标多重集不变性(程序内 assert 级校验);确定性(固定 seed 的 rng 洗牌,无全局随机态)。-- 没验证:同型内限制的置换变体(时间不够);其他 k / 目标函数——但停止规则已触发,且两种目标(本节点与 node7/9)都失败,判断该家族不值得继续。-- 运行时 ~7s(默认对照路径);机制路径 ~8 分钟,仍在 30 分钟限制内。+- 验证过:对照=50.00 且与父节点对照八项原始值一致;α=0.25 全指标分解;同 seed 双跑输出逐位相同(确定性);vec-score status=scored(格式合规;vec-check 对本 client 拒绝该 task,无法直接跑);代码不读绝对时间/阶段名/board 字段,α=0 路径不读 prior,时间平移伪装下输出不变。+- 没验证:α=0.5(停止规则触发,方向已由 α=0.25 的 de_direction≈0 判定);sign 随机打乱对照(PLAN 证据 3——α=0.25 的 de_direction 本身已≈0,与打乱预期无异,省 1 次查分);仅对 score 连续值加权(非符号化)的微扰变体。+- 运行时 ~2s(对照路径),内存 <1 GB。 ## 知识来源 -无外部生物知识;15-NN 对齐来自评分规则简报的公开描述(neighborhood_mmd 定义)。+- CollecTRI 转录因子调控网络(TF→target 激活/抑制符号):来自视图内 `prior/tf_regulons/`,属"不针对禁窗阶段的通用机制知识",不含任何保留阶段/基因型的测量信息。+- 无其他外部知识;未使用任何已发布阶段的尺寸、比例或表达统计常数。 ## 下一步建议 -置换家族两次独立实现(Dirichlet、cosine-15NN)均低于地板,建议放弃 T2HX-06;外推榜唯一未试尽的方向是 expression_change 组:父节点已证明速度外推无信号,剩下的是用 prior(Reactome/CollecTRI)构造符号级方向假设并只做秩一致的保守调整,或直接接受 copy_last 保底。+- 本榜在"仅 anchor + 通用先验"的信息集下,50.00 可能已接近可达上限;建议停止微扰/重排家族的尝试。+- 若继续,唯一未动过且不依赖方向的量是输出细胞组成的再加权(composition 不参与排名指标,但影响 mmd_u/neighborhood_mmd 的分布位置)——但 node 系列已间接说明分布移动类操作在此榜全部劣化,预期收益低。diff --git a/solution/run.py b/solution/run.pyindex e610b14..3ddbd56 100644--- a/solution/run.py+++ b/solution/run.py@@ -1,25 +1,37 @@ #!/usr/bin/env python3-"""T2 extrapolation: expression-kNN-guided greedy 2-opt coordinate permutation.--Mechanism (family T2HX-06, replication of node 5): on the anchor (last observed)-stage output, find pairs of cells that are similar in expression (cosine kNN,-k=15, aligned with the neighborhood_mmd metric's 15-NN definition) but not-already spatial neighbours, and greedily swap their coordinates when the swap-reduces the total cosine distance between every cell's expression and its-spatial 15-NN expressions. The expression matrix is bitwise unchanged and the-coordinate point multiset is unchanged; only the cell-coordinate pairing-changes.--VEC_NSWAPS=0 disables all swaps (mechanism-off control: output bitwise equals-copy_last). No absolute stage names, times or sizes are used; view-independent.+"""T2 extrapolation: CollecTRI regulatory-direction prior driving a bounded+per-gene sign perturbation of the copy_last anchor output.++Base (identical to parent node 12 control / node 1 copy_last): anchor = last+observed stage, n clipped to [min_cells, max_cells], stratified-by-celltype+sampling via ``take``, coordinates passed through unchanged.++Mechanism (family "other", PLAN CollecTRI direction prior):+ 1. Load CollecTRI (TF -> target, mor sign) from <view>/prior/tf_regulons/.+ 2. For each TF present in the output panel, activity_t = mean anchor+ expression of gene t.+ 3. For each panel gene g: score_g = sum over edges (t->g, t in panel) of+ sign(t->g) * activity_t.+ 4. Perturbed set S = genes with score_g != 0 (equivalently |score_g| above+ the median of |score| when most panel genes are unregulated).+ sign_g = sign(score_g) for g in S, else 0.+ 5. X_new[:, g] = clip(X[:, g] + alpha * sign_g * std_g, 0, inf),+ std_g = per-gene std over the output cells of the anchor.+ 6. alpha = 0 (VEC_ALPHA=0) is the mechanism-off control: output bitwise+ equals copy_last. No second time point is required; single-input views+ work unchanged.++View-independent: no absolute stage names, times, sizes or hardcoded+constants from published stages. Deterministic given --seed. """ from __future__ import annotations import argparse+import gzip import os import sys-import time+from pathlib import Path import numpy as np @@ -32,12 +44,41 @@ from src.task2_spatial.view_io import ( write_t2, ) -KNN_K = 15 # spatial neighbourhood size (matches metric definition)-POOL = 60 # cached spatial neighbours per cell for delta evaluation-EXPR_K = 16 # expression kNN incl. self-ROUNDS = int(os.environ.get("VEC_ROUNDS", "3"))-NSWAPS = int(os.environ.get("VEC_NSWAPS", "0")) # proxy test: permutation harmful (49.85 < 50), default off per PLAN stop-rule-EPS = 1e-9+# Proxy measurement (proxy_noscale): alpha=0.25 scored 43.65 (de_direction raw+# -0.0004 ~ 0: CollecTRI net regulatory input carries no directional signal for+# this extrapolation; de_score -0.389; variogram 0.058->0.172 destroyed by the+# per-gene constant shift). PLAN stop-rule -> default off (= copy_last).+ALPHA = float(os.environ.get("VEC_ALPHA", "0"))+++def collectri_scores(view: str, genes: list[str], tf_mean: dict[str, float]):+ """score_g = sum_{t->g, t measured} sign * activity_t, per panel gene."""+ gidx = {g: i for i, g in enumerate(genes)}+ path = Path(view) / "prior" / "tf_regulons" / "collectri_mouse.tsv.gz"+ scores = np.zeros(len(genes), dtype=np.float64)+ n_edges = 0+ if not path.exists():+ return scores, n_edges+ with gzip.open(path, "rt") as f:+ header = f.readline().rstrip("\n").split("\t")+ i_tf = header.index("tf")+ i_tg = header.index("target")+ i_mor = header.index("mor")+ for line in f:+ p = line.rstrip("\n").split("\t")+ tf = p[i_tf]+ tg = p[i_tg]+ if tf not in tf_mean or tg not in gidx:+ continue+ try:+ mor = float(p[i_mor])+ except ValueError:+ continue+ if mor == 0.0:+ continue+ scores[gidx[tg]] += np.sign(mor) * tf_mean[tf]+ n_edges += 1+ return scores, n_edges def main() -> None:@@ -59,129 +100,29 @@ def main() -> None: X = stage.X[rows].toarray().astype(np.float32) coords = np.ascontiguousarray(stage.coords[rows], dtype=np.float64)[:, :3]- n_cells = X.shape[0]-- if NSWAPS > 0 and n_cells > KNN_K + 2:- t0 = time.time()- from sklearn.neighbors import NearestNeighbors-- nn_e = NearestNeighbors(n_neighbors=min(EXPR_K, n_cells), metric="cosine").fit(X)- _, eidx = nn_e.kneighbors(X)-- Xn = X.astype(np.float64)- nrm = np.linalg.norm(Xn, axis=1, keepdims=True)- nrm[nrm == 0] = 1.0- Xn = Xn / nrm- G = Xn @ Xn.T # cosine similarity- np.fill_diagonal(G, -1.0)- del Xn-- P = coords.copy()- pool = np.zeros((n_cells, POOL), dtype=np.int64)- nswaps = 0- k = min(KNN_K, n_cells - 1)-- for rd in range(ROUNDS):- nn_s = NearestNeighbors(n_neighbors=min(POOL, n_cells)).fit(P)- _, sidx = nn_s.kneighbors(P)- pool[:, : sidx.shape[1]] = sidx- snbr_set = [set(r[:KNN_K].tolist()) for r in sidx]-- # candidate pairs: expression-similar but not already spatial neighbours- seen = set()- cands = []- for i in range(n_cells):- row_e = eidx[i]- row_s = snbr_set[i]- for jj in row_e:- j = int(jj)- if j == i or j in row_s:- continue- key = (i, j) if i < j else (j, i)- if key not in seen:- seen.add(key)- cands.append(key)- cands = np.array(cands, dtype=np.int64)- rng.shuffle(cands)- print(f"[diag] round {rd}: {len(cands)} candidate pairs, setup {time.time()-t0:.1f}s", file=sys.stderr)-- ar_n = np.arange(n_cells, dtype=np.int64)- acc_this_round = 0- for pair in cands:- if nswaps >= NSWAPS:- break- i = int(pair[0])- j = int(pair[1])- pi = P[i].copy()- pj = P[j].copy()- si = pool[i].copy()- sj = pool[j].copy()- A = np.union1d(si, sj)- A = A[(A != i) & (A != j)]- m = A.shape[0]-- # ---- cost for i and j themselves (candidates = partner's pool) ----- def _self_cost(pos, Cp, Gx):- Cp = Cp[(Cp != i) & (Cp != j)]- d = np.sqrt(((P[Cp] - pos) ** 2).sum(1))- s = Gx[Cp]- d = np.concatenate([[0.0], d]) # self, distance 0- s = np.concatenate([[1.0], s]) # self, similarity 1- kk = min(k, d.shape[0])- sel = np.argpartition(d, kk - 1)[:kk]- return float(kk - s[sel].sum())-- pre_i = _self_cost(pi, si, G[i])- pre_j = _self_cost(pj, sj, G[j])- post_i = _self_cost(pj, sj, G[i])- post_j = _self_cost(pi, si, G[j])-- # ---- cost for affected bystanders A (positions unchanged) ----- PA = P[A]- CA = pool[A] # m x POOL- mask = (CA == i) | (CA == j) | (CA == A[:, None])- Dp = np.sqrt(((P[CA] - PA[:, None, :]) ** 2).sum(2))- Dp[mask] = np.inf- Sp = G[A[:, None], CA]- Sp[mask] = -1.0- dAi = np.sqrt(((PA - pi) ** 2).sum(1))- dAj = np.sqrt(((PA - pj) ** 2).sum(1))- sAi = G[A, i][:, None]- sAj = G[A, j][:, None]- d0 = np.zeros((m, 1))- s1 = np.ones((m, 1))-- def _bystander(di_col, dj_col):- D = np.hstack([Dp, di_col, dj_col, d0])- S = np.hstack([Sp, sAi, sAj, s1])- kk = min(k, D.shape[1])- sel = np.argpartition(D, kk - 1, axis=1)[:, :kk]- return float((kk - S[np.arange(m)[:, None], sel].sum(1)).sum())-- pre_A = _bystander(dAi[:, None], dAj[:, None])- post_A = _bystander(dAj[:, None], dAi[:, None])-- delta = (post_i + post_j + post_A) - (pre_i + pre_j + pre_A)- if delta < -EPS:- P[i] = pj- P[j] = pi- pool[i] = sj- pool[j] = si- nswaps += 1- acc_this_round += 1-- print(f"[diag] round {rd}: accepted {acc_this_round}, total {nswaps}, {time.time()-t0:.1f}s", file=sys.stderr)- if acc_this_round == 0:- break-- coords = np.ascontiguousarray(P, dtype=np.float64)- src_coords = np.ascontiguousarray(stage.coords[rows], dtype=np.float64)[:, :3]- for c in range(3):- if not np.array_equal(np.sort(coords[:, c]), np.sort(src_coords[:, c])):- print("[diag] WARNING: coordinate multiset changed!", file=sys.stderr)- print(f"[diag] permutation done: {nswaps} swaps, {time.time()-t0:.1f}s", file=sys.stderr)++ if ALPHA != 0.0:+ gset = set(genes)+ tf_mean = {+ g: float(X[:, i].mean())+ for i, g in enumerate(genes)+ if g in gset+ }+ scores, n_edges = collectri_scores(args.data, genes, tf_mean)+ nz = scores != 0.0+ med = float(np.median(np.abs(scores)))+ perturbed = nz & (np.abs(scores) > med) if med > 0 else nz+ sign = np.zeros(len(genes), dtype=np.float32)+ sign[perturbed] = np.sign(scores[perturbed]).astype(np.float32)+ std = X.std(axis=0).astype(np.float32)+ X = np.clip(X + (ALPHA * sign * std)[None, :], 0.0, None).astype(np.float32)+ print(+ f"[diag] alpha={ALPHA} edges_used={n_edges} perturbed={int(perturbed.sum())}"+ f"/{len(genes)} median_abs={med:.4f}",+ file=sys.stderr,+ ) else:- print("[diag] control (NSWAPS=0): output = copy_last", file=sys.stderr)+ print("[diag] control (VEC_ALPHA=0): output = copy_last", file=sys.stderr) write_t2(args.out, X, coords, genes, seed=args.seed)
调研来源?调研员查到并用到的知识条目和文献检索结果(只列标题和编号)。
用到的知识库条目
| 编号 | 标题 | 出处 |
|---|---|---|
| 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 |
| k016 | Degenerate-solution checks for population predictions | notes/handover/02_知识学习路线.md |
分析结果?分析员写的 ANALYSIS.json:改了什么、各组分数怎么变、假设是否成立、经验和下一步建议。
| 改了什么 | 把 solution/run.py 从父节点的表达kNN坐标置换换成 CollecTRI 调控方向先验的逐基因符号微扰:读 prior/tf_regulons/collectri_mouse.tsv.gz,只用面板内 TF→target 边(411 条,覆盖 176/500 基因),score_g=Σ sign(mor)×mean(TF),X_new=clip(X+α·sign_g·std_g,0,∞),α 由 VEC_ALPHA 控制。实际提交的是机制关闭态 VEC_ALPHA=0(α=0.25 探针只有 43.65),所以交付输出逐位等于 copy_last,与父节点相同。 |
|---|---|
| 各组分数的变化 | cell_state:无变化:50.00→50.00,mmd_u 0.05832、variogram 0.05806 与父节点逐位相同(skill 0.500)。 expression_change:无变化:50.00→50.00,de_score 与 de_direction 原始值均为 0(skill 0.500,各 6.25 分 = 地板),无变化保护照旧生效。 local_spatial:无变化:50.00→50.00,neighborhood_mmd 0.1126(skill 0.500,12.50 分)。 shape_scale:无变化:50.00→50.00,d2_shape 0.04911、occupancy_dice 0.8066、scale_log_ratio −0.4334 全部与父节点一致(skill 0.500,门=1)。 |
| family_id | other |
| 假设是否成立 | 否 |
| 经验 |
|
| mechanism_active | 否 |
| 下一步建议 |
|
对话摘要?每个角色和大模型对话的统计:轮数、工具调用、用时、token 数和最后的回答摘录;原始记录只给路径。
只给统计和最后回答的摘录;完整对话请到原始记录位置里列出的文件看。
分析员
| 角色?调研员写计划、工程师改代码、分析员解读分数、审查员检查作弊。 | 分析员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数?大模型一共回复了几轮(每轮可以调用多个工具)。 | 4 |
| 工具调用?大模型调用读文件、执行命令等工具的次数,按工具名统计。 | 共 4 次:bash 3、write 1 |
| 用时 | 不到 1 分 |
| token 数?输入 / 输出(含思考)的 token 数,来自接口返回的用量。 | 输入 17,946 · 输出 1,574 · 思考 626 |
| 任务(第一行) | 分析节点 n14 的打分结果,写 ANALYSIS.json |
| 最后的回答(摘录) | ANALYSIS.json written |
| 原始记录位置?完整对话记录在 Spark 上的文件路径;看板不复制原始内容。 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/14/analyst.jsonl 13 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/14/analyst.stderr |
工程师
| 角色 | 工程师 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 22 |
| 工具调用 | 共 26 次:bash 20、read 3、write 2、edit 1 |
| 用时 | 9 分 |
| token 数 | 输入 55,612 · 输出 7,940 · 思考 8,853 |
| 任务(第一行) | 按计划修改程序:CollecTRI 调控方向先验驱动的逐基因符号微扰(expression_change 组) |
| 最后的回答(摘录) | **做了什么**:按 PLAN 实现了 CollecTRI 调控方向先验的逐基因符号微扰(411 条面板内 TF→target 边、176/500 基因受扰动,α 环境开关,α=0 为关闭对照);另加试了细胞密度稀释假设。 **查分结果**(4/20 次):α=0.25 → **43.65**(de_direction 原始 −0.0004≈0,方向先验无信号;de_score −0.389;variogram 0.058→0.172 被 clip 截断严重破坏);密度稀释 50% → 47.74(neighborhood_mmd 反升);对照 α=0 → **50.00**(八项全在地板,与父节点逐位一致)。PLAN 停止规则触发,提交机制关闭态(=copy_last),已验证确定性、格式合规、视图无关。 **下一步最值得试**:本榜四个方向族(坐标配对、速度/PCA 位移、调控先验微扰、密度)均已否证,de_direction≈0 表明现有信息集下"哪些基因将变"不可提取,50 大概率是局部最优;若必须继续,只剩输出组成的类型级再加权一条未直接试过,但同类分布移动操作全部劣化,预期收益低——建议控制器把预算转向其他榜。 |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/14/engineer.jsonl 135 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/14/engineer.stderr |
调研员
| 角色 | 调研员 alibaba-token-plan-cn/qwen3.8-max |
|---|---|
| 调用次数 | 1 次 |
| 轮数 | 1 |
| 工具调用 | 共 0 次:— |
| 用时 | 3 分 |
| token 数 | 输入 15,557 · 输出 1,312 · 思考 7,174 |
| 任务(第一行) | 为节点 n14(改进,父节点 n12)写改进计划 PLAN.json |
| 最后的回答(摘录) | 骤:\n1. 基座与父节点相同:anchor=末观测阶段,n 夹到 [min_cells, max_cells],take 按型分层抽样,坐标原样输出。\n2. 加载 prior/ 中 CollecTRI(TF→target, sign∈{+1,−1})。对每个 TF t,计算 activity_t = mean(X[:, t])(anchor 中该 TF 的平均表达)。对每个基因 g,计算调控净输入 score_g = Σ_{t→g} sign(t→g) × activity_t。取 |score_g| > median(|score|) 的基因作为受扰动集合 S(约 50% 基因)。\n3. 对 g∈S,sign_g = sign(score_g);对 g∉S,sign_g = 0。逐基因标准差 std_g = std(X[:, g])。\n4. 微扰:X_new[:, g] = clip(X[:, g] + α × sign_g × std_g, 0, +∞)。α 网格 {0.25, 0.5}(环境变量 VEC_ALPHA)。α=0 为关闭对照。\n5. 单输入阶段退路:本方案只依赖 anchor 阶段的表达矩阵和 prior 网络,不需要第二个时间点,天然兼容单阶段。\n6. 查分策略:先跑 α=0 对照确认=50.00(1 次查分);再跑 α=0.25(1 次);若 de_direction>0 且总分≥51 则跑 α=0.5(1 次);否则停止。共≤4 次查分。若 α=0.25 总分<50,立即以对照提交。\n7. 关键约束:不改变坐标、不改变细胞数、不改变组成;微扰幅度≤0.5×std_g,保证 mmd_u/variogram/neighborhood_mmd 在噪声内。",
"expected_groups": ["expression_change"],
"risks": "1) CollecTRI 的调控方向可能不预测 E8.5→E9.5 的真实变化方向(如某些基因在该阶段受其他机制主导),导致 de_direction<0、DE 组反降。Engineer 应在第一次 α=0.25 查分后立即检查 de_direction 原始值:若<0 则停止,以对照提交。2) 微扰可能轻微影响 mmd_u(分布偏移);α≤0.5×std 时预期影响<噪声(1分),若 mmd_u 组降>1 分则回落对照。3) prior/ 中 CollecTRI 格式或基因名与 panel 不完全匹配;Engineer 应先统计匹配率,若<30% 则方案退化为随机方向,应放弃并以对照提交。",
"family_id": "other",
"mechanism": "CollecTRI 调控网络的净激活/抑制输入为每个基因提供发育方向先验(+1=预期上调,−1=预期下调),按此符号对表达做有界微扰,使伪批量变化方向与真实发育变化产生秩相关,从而突破无变化保护(std(dp)=0)并在 de_score/de_direction 上获得正分。",
"vs_constant_shift": "旧实现(node2 damped_shift、node3/4/8 速度位移)的方向来源是数据驱动的两时间点速度或 PCA 投影,在外推榜上已证无信号;本方案方向来源是 CollecTRI 调控网络结构先验(TF→target 的激活/抑制符号 × TF 表达水平),不依赖第二个时间点,且是逐基因独立方向(非全局统一方向)。旧实现是全局或按型统一位移向量,本方案是 sign_g∈{+1,0,−1} 的逐基因符号场,不同基因方向不同。",
"mechanism_evidence": "1) de_direction 原始值从 0 变为正数(若方向正确);2) de_score 原始值从 0 变为正数;3) 对照实验:将 sign_g 随机打乱(保持 |S| 不变),de_direction 应回到≈0(秩相关消失);4) mmd_u/variogram/neighborhood_mmd 变化<噪声(证明微扰未破坏分布);5) 受扰动基因集合中,上调基因(sign=+1)的 dp>0、下调基因(sign=−1)的 dp<0(方向一致性校验)。",
"mechanism_off_control": "VEC_ALPHA=0 时跳过全部微扰,输出逐位等于 copy_last。同一 run.py 只需设环境变量 VEC_ALPHA=0 即可关闭。预期差别:关闭时 de_score=de_direction=0(无变化保护),总分=50.00;开启时 DE 两项应为非零值(正或负取决于方向是否正确)。",
"sources": []
} |
| 原始记录位置 | /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/14/researcher.jsonl 5 KB /home/spark-longxinyang/vec/runs/formal/20261003-105537-search-t2-heart-extrap-g24-D/nodes/14/researcher.stderr |