生物医学网络科学Biomedical Network Science
研究问题、可复现分析与敏感性分析03 / 16

可复算的分析

阅读
约 3 分钟

两个概念

可复算(reproducible):用相同的数据、相同的代码和步骤,得到相同的结果。可重复(replicable):用新的数据、按相同的方法,得到一致的结论。任何计算分析至少要做到可复算;有条件时,用第二个数据集或子样本检验可重复性。

可复算看似是最低要求,实际上并不容易达到。Stodden 等(2018)随机抽取 Science 在 2011 年实行数据与代码政策后发表的 204 篇计算类论文,向作者索取材料:只拿到了其中 44% 的数据和代码,能复现结果的为 26%。Trisovic 等(2022)在干净环境中重新运行 Harvard Dataverse 上 2000 多个复现数据包中的 9000 多个 R 脚本,74% 的文件初次运行即报错,经自动清理代码后仍有 56% 报错。这些数字说明:“代码已共享”不等于“结果可复算”。

Sandve 等的十条规则

Sandve 等(2013)的十条规则至今仍是计算可复算性的基本框架。下面按其要点给出网络分析中的对应做法:

规则要点 网络分析中的做法
1. 记录每个结果是怎样产生的 每张图、每个数值都能追溯到一个脚本和一组参数
2. 避免手工处理数据 不在 Excel 里手改基因名;ID 映射写成代码并保存映射表
3. 存档所用外部程序的确切版本 记录 networkx、igraph、bctpy、bootnet 等的版本;数据库同样要记版本
4. 对自己的脚本做版本控制 用 Git,每个结果对应一个提交号
5. 尽量用标准格式保存中间结果 保存邻接矩阵、边列表(如 .npz、.csv、GraphML),而不只保存最终图
6. 有随机性的分析要记录随机种子 Louvain、bootstrap、度保持随机化都要记录种子(见随机性控制)
7. 保存图背后的原始数值 每张敏感性曲线都保存对应的数值表
8. 输出分层次的结果 汇总表 → 每个参数组合的结果 → 单次运行的日志
9. 把文中陈述与具体结果对应起来 正文中的每个数值都能在结果文件中找到
10. 公开脚本、运行记录和结果 见数据与代码共享

七条日常做法

  1. 原始数据只读:下载的原始文件不手工修改,所有清洗步骤写在代码里。
  2. 记录数据版本:数据库名称、版本号和下载日期写进 README,例如“STRING v12.0,2026-11-10 下载,人类 9606,综合置信度 ≥ 700”。数据库会更新,不记版本就无法复算。
  3. 用脚本,不用鼠标:Cytoscape、Gephi 适合可视化和探索,但关键数值结果应由脚本生成。确需手工操作时,逐步写进实验记录。
  4. 固定随机种子:Louvain、随机网络、bootstrap、置换检验都有随机性。固定种子是为了可复算;报告结论时则要跑多个种子,说明结论不依赖于某一个种子(见敏感性分析与替代解释)。
  5. 记录环境:requirements.txt 或 environment.yml 写明 Python/R 和关键包版本(例如 networkx 3.x 的 Louvain 实现与旧版不同),详见计算环境与工作流。
  6. 版本控制:用 Git 管理代码和文档,每完成一步就提交一次,提交说明写清“做了什么”。
  7. 一键重跑:最终发布前,从原始数据出发运行一遍完整流程,确认所有图表都能重新生成。

推荐的项目目录(与 The Turing Way 所说的“研究纲要”(research compendium)思路一致):

project/
├── README.md          # 问题、数据来源与版本、运行方法
├── LICENSE            # 代码许可;数据另行说明
├── environment.yml    # 或 requirements.txt + 锁定文件
├── data/raw/          # 原始数据(只读,不提交大文件,写明下载方式)
├── data/processed/    # 由代码生成
├── code/              # 01_clean.py, 02_build_network.py, 03_analysis.py ...
├── results/           # 图表与数值结果,由代码生成
└── report/            # 报告与幻灯片

溯源记录

溯源(provenance)指每个结果从哪些输入、经过哪些步骤、在什么环境下得到。最轻量的做法是每次运行时自动写一个“运行清单”:软件版本、参数、随机种子,以及输入与输出文件的 SHA-256 哈希。哈希相同说明文件逐字节相同;换机器后输出哈希改变,就可以按清单逐项排查是数据、参数还是软件版本变了(见本专题代码示例“运行清单”)。