# DeepGraph 免费验证案例 · AML 跨队列一致性初检

**提交方向**：AML 耐药相关候选靶点（提交人从我们给出的两个选项里选定「跨队列一致性初检」）
**交付时间**：2026-08-26
**这一轮真跑了**：TCGA-LAML 全基因组发现（20530 基因）→ BeatAML 真实临床标签复制，
外加 1000 次标签置换零模型。纯 CPU。

---

## 0. 结论（先说结果）

**在 TCGA-LAML 筛出的 200 个候选里，有 25 个在 BeatAML 独立复制成功**
（方向一致 + FDR<0.10）。零模型跑 1000 次，**95.5% 的置换给出 0 个，没有一次达到 25**
（经验 p < 0.001）。把复制阈值从 FDR<0.10 收紧到 <0.05，仍有 22 个留下。

关键在于：**两个队列的"耐药"定义完全不同** —— TCGA 用的是生存分位数代理，
BeatAML 用的是真实的诱导治疗反应（难治 vs 完全缓解）。方向仍然一致，说明信号不依赖
某一种耐药操作化方式。这正是「跨队列一致性」这条路想要的判据。

## 1. 复制成功的基因（按 BeatAML 效应量排序，前 12）

| 基因 | TCGA Δ(耐药−敏感) | BeatAML Δ(难治−完全缓解) | BeatAML FDR |
|---|---:|---:|---:|
| SYTL4 | +3.04 | +0.91 | 0.025 |
| TCF15 | +2.46 | +0.85 | 0.058 |
| DDIT4 | +2.14 | +0.80 | 0.029 |
| RHPN1 | +1.52 | +0.57 | 0.033 |
| PTP4A3 | +2.11 | +0.55 | 0.024 |
| SLC29A2 | +1.36 | +0.54 | 0.011 |
| EFCAB10 | -0.57 | -0.46 | 0.097 |
| NRBP2 | +1.18 | +0.42 | 0.033 |
| PARP3 | +1.07 | +0.36 | 0.011 |
| ST8SIA4 | -0.56 | -0.35 | 0.013 |
| DTWD2 | -0.63 | -0.31 | 0.048 |
| TGIF1 | -0.51 | -0.27 | 0.025 |

完整 25 个见 `work/results.json` 的 `replicated` 字段。

## 2. 判定规则（跑之前写死，见 `claims.json`）

- **发现层**：TCGA-LAML，耐药代理 = 总生存下四分位且已故（35 例），
  敏感代理 = 上四分位（43 例）；Mann-Whitney U + BH，取 FDR 最小的 200 个
- **复制层**：BeatAML，难治 178 例 vs 完全缓解 302 例；
  只检验那 200 个，方向一致且 FDR<0.10 记为复制成功
- **零模型**：两队列各自标签置换 1000 次，重复整套流程
- **推翻条件**：实际复制数 ≤ 零模型 95 分位，或复制成功 < 5 个 → 两条都没触发

## 3. 这些数**不**支持什么（请务必看这一节）

1. **发现层本身很弱。** TCGA 那 200 个候选里，最小 FDR 是 0.044。
   它们是「最像的 200 个」，**不是「已经确证的 200 个」**。真正起筛子作用的是复制这一步。
   拿单个候选去讲故事之前，请先看它在第 1 节的表里有没有。
2. **不是 Venetoclax/Azacitidine 专属耐药。** 公开队列里拿不到这两个药的反应标签。
   本轮用的是诱导治疗反应（BeatAML）和生存代理（TCGA）。它们与这两个药的耐药**相关但不等同**。
3. **分母是 150 不是 200。** 200 个候选里 cBioPortal 认得 166 个，其中 150 个在 BeatAML 有表达数据。
   缺的那些是基因符号版本差异造成的，与耐药无关，但复制率应按 150 计。
4. **生存代理不等于耐药。** TCGA 那一侧用生存分位数划分，混杂年龄、体能状态、移植与否等因素。
5. **不做功能验证、不做临床决策建议。**

## 4. 我们怎么确认这不是程序错误

交付前做了五项敌意复核（`work/adversarial_check.py`），其中一项抓到了真问题：

**第一版跑出来"复制 0 个"** —— 因为取临床标签时用了 `patientId`，而表达矩阵用的是 `sampleId`，
两边对不上，队列 B 直接空掉。这个 bug 会伪造出一个"复制不了"的假结论。
修好后才有本报告的数字。其余四项：样本 ID 交集核对、方向符号逐条核、
缺失基因是否与结果相关、阈值收紧后剩多少。

## 5. 下一步：三个真正值得追的方向

1. **把耐药定义换成你关心的药。** 如果你手上有 Venetoclax/Azacitidine 的反应数据（哪怕几十例），
   把它接到同一套流程上，这 25 个基因里哪些还站得住，会立刻清楚。
2. **加第三个队列做三重复制。** 两个队列一致已经不容易，三个一致基本就能进正文。
3. **对这 25 个做机制层筛选**（通路富集、已知药靶注释、表达特异性），
   把"统计上复制"收敛成"值得做实验"的少数几个。

这三条都属于付费轮。

## 6. 随附材料

- `work/fetch_cohorts.py`：取两个队列的分组标签（cBioPortal 公开 API）
- `work/experiment.py`：发现 + 复制 + 零模型全流程
- `work/adversarial_check.py`：第 4 节那五项复核
- `work/plot_results.py` / `work/figs/replication.png`
- `claims.json`：跑之前写死的预测与判定规则（含一次设计调整的记录）
- `work/results.json`：每个数字的唯一回查源

数据来源：UCSC Xena 的 TCGA-LAML 表达矩阵、cBioPortal 的 BeatAML (OHSU 2018)，
均为匿名可直接访问的公开资源。本轮不需要提交人提供任何数据、代码或稿件。
