TDC(Therapeutics Data Commons,Huang 等,2021)的核心设计理念是:不按机器学习任务类型组织数据,而按药物研发的实际阶段组织。这个看似简单的转变,让基准与真实决策的距离大大缩短。
三层组织结构
| 层级 | 问题 | 示例任务 |
|---|---|---|
| 单实例预测 | 给定一个分子,预测其性质 | ADMET、毒性、溶解度 |
| 多实例预测 | 给定分子对/分子-蛋白,预测关系 | DTI、药物相互作用、协同 |
| 生成 | 生成满足条件的新分子 | 分子设计、逆合成、抗体设计 |
在此之上,任务还按研发阶段标注:靶点发现 → 苗头筛选 → 先导优化 → 临床前 → 临床。这个标注让使用者能问「我在这个阶段需要什么模型」,而非「我有什么数据可以拿来刷分」。
基本使用
pip install PyTDC
# ---- ADMET 任务 ----
from tdc.single_pred import ADME
data = ADME(name="Caco2_Wang")
split = data.get_split(method="scaffold", seed=42,
frac=[0.7, 0.1, 0.2])
train, valid, test = split["train"], split["valid"], split["test"]
print(train.head())
print(f"训练 {len(train)}, 测试 {len(test)}")
# 查看所有可用的 ADME 数据集
from tdc.utils import retrieve_dataset_names
print(retrieve_dataset_names("ADME"))
# ---- 毒性任务 ----
from tdc.single_pred import Tox
data = Tox(name="hERG")
# ---- DTI 任务 ----
from tdc.multi_pred import DTI
data = DTI(name="BindingDB_Kd")
data.harmonize_affinities(mode="max_affinity") # 处理重复测量
data.convert_to_log(form="binding") # 转成 pKd
split = data.get_split(method="cold_split",
column_name="Drug") # 【冷启动划分】
# ---- 生成任务 ----
from tdc.generation import MolGen
data = MolGen(name="ZINC")
# ---- Benchmark 组(标准化评测)----
from tdc.benchmark_group import admet_group
group = admet_group(path="data/")
predictions_list = []
for seed in [1, 2, 3, 4, 5]: # 【必须跑多个种子】
predictions = {}
for benchmark in group:
name = benchmark["name"]
train_val, test = benchmark["train_val"], benchmark["test"]
train, valid = group.get_train_valid_split(
benchmark=name, split_type="default", seed=seed)
# ... 训练你的模型 ...
y_pred = my_model.predict(test["Drug"])
predictions[name] = y_pred
predictions_list.append(predictions)
results = group.evaluate_many(predictions_list)
# 返回每个任务的均值与标准差 —— 这是正确的报告方式
print(results)
划分方式:TDC 的重要设计
# TDC 提供多种划分,选对了才有意义
#
# random
# 随机划分 —— 【几乎总是会高估性能】
# 只用于快速调试
#
# scaffold
# 按 Bemis-Murcko 骨架划分
# → 测试模型对新骨架的泛化(见 167)
#
# cold_split
# 【多实例任务专用】
# cold drug: 测试集的药物在训练集中完全没出现
# cold protein: 测试集的蛋白在训练集中完全没出现
# cold both: 两者都没出现(最严格)
#
# → 这是 DTI 任务【最重要的划分方式】
# → 很多 DTI 论文用随机划分,
# 结果实际上是「记住了这个药物的平均活性」(见 139)
#
# temporal / time
# 按时间划分,模拟真实的部署场景
# → 【最接近生产环境】
#
# combination
# 组合划分
#
# 选择原则:
# 问「模型在生产中会遇到什么样的新数据?」
# → 新骨架 → scaffold
# → 新靶点 → cold protein
# → 未来的数据 → temporal
相对 MoleculeNet 的改进
| MoleculeNet | TDC | |
|---|---|---|
| 组织方式 | 按 ML 任务类型 | 按研发阶段 |
| 任务数 | 17 个数据集 | 数十个任务、上百个数据集 |
| 划分 | 随机/骨架 | + 冷启动、时间划分 |
| 多实例任务 | 少 | 丰富(DTI、DDI、协同) |
| 生成任务 | 无 | 有(含逆合成、抗体) |
| 评测规范 | 较松 | Benchmark Group 强制多种子 |
| 持续维护 | 较少更新 | 活跃 |
TDC 也有的局限
- 数据质量仍取决于原始来源:TDC 是聚合平台,它整理了数据但无法修复原始数据中的测定差异与标注错误;
- 部分数据集仍然很小:几百到一两千个分子的任务不少,统计功效有限;
- 实验体系的异质性:同一个「溶解度」任务的数据可能来自不同实验室、不同方法——模型可能在学习「数据来源」而非化学(见 156《AI ADMET 预测模型》);
- 刷榜仍然可能:有排行榜的地方就有过拟合排行榜的动机(见 169《Benchmark 陷阱》);
- 不能替代自家数据的验证:TDC 上表现好的模型,在你的化学空间上不一定好。
正确的使用姿势
# TDC 适合做什么:
#
# 1) 【方法开发阶段的横向比较】
# 在多个任务上比较不同方法,看普遍性
#
# 2) 【建立基线的参考值】
# 知道某类任务的合理性能范围
# → 如果你在自家数据上做 hERG 预测得到 AUC 0.95,
# 而 TDC 上最好的模型才 0.85,
# 那你的评测很可能有问题
#
# 3) 【快速原型验证】
# 新想法先在标准任务上试,成本低
#
# 4) 【教学与学习】
# 了解领域有哪些任务
#
# TDC 【不适合】做什么:
#
# 1) 证明某个方法在你的项目上更好
# → 必须用自家数据验证
#
# 2) 直接部署 TDC 上训练的模型
# → 化学空间不匹配
#
# 3) 作为唯一的评测依据
# → 排行榜名次与实际价值的关系很弱
# 一个实用的做法:
# 用 TDC 做「健全性检查」——
# 你的流程在标准任务上应该达到接近 SOTA 的水平;
# 如果差很多,说明流程本身有问题(而非数据问题)
关键要点
- 按研发阶段而非 ML 任务类型组织,让基准贴近真实决策;
- 冷启动划分是 DTI 任务最重要的划分方式——随机划分下模型只是记住了药物的平均活性;
- Benchmark Group 强制多种子评测,这是正确的报告方式;
- 它适合做健全性检查与横向比较,不能替代自家数据的验证。
延伸资源
- MoleculeNet:132《MoleculeNet 论文精读》;实战:335《用 TDC Benchmark 评估模型》;
- Benchmark 陷阱:169《Benchmark 陷阱》;DTI 模型:157《AI DTI 预测模型》;模型外推性:167《模型外推性》。