005

Therapeutics Data Commons 教程:AI 药物发现数据集怎么系统学习

TDC 是系统学习 AI 药物发现数据集的最佳起点。这篇给出按研发阶段的学习路径与关键的划分方式实践。

Therapeutics Data Commons(TDC)把 AI 药物发现的任务按研发阶段组织,而非按机器学习任务类型。这个组织方式让它不只是数据集集合,更是一张「AI 能在药物研发中做什么」的地图。

用 TDC 系统学习的路径

pip install PyTDC

# 【第 1 步】:先看有哪些任务
from tdc.utils import retrieve_benchmark_names, retrieve_dataset_names

print("ADME 数据集:", retrieve_dataset_names("ADME"))
print("Tox 数据集:", retrieve_dataset_names("Tox"))
print("DTI 数据集:", retrieve_dataset_names("DTI"))

# 【浏览这个列表本身就很有价值】:
#   它告诉你「AI 药物发现有哪些具体任务」
#   比读综述更直观

# 【第 2 步】:按研发阶段逐个理解
#
#   靶点发现相关:
#     - 基因-疾病关联
#   苗头发现相关:
#     - HTS 数据、DTI
#   先导优化相关:
#     - 【ADMET 各终点】← 数据最丰富
#     - 活性预测
#   临床前相关:
#     - 毒性(hERG、DILI、Ames)
#   临床相关:
#     - 试验结果预测
#
# 【第 3 步】:每个任务问三个问题
#   □ 这个数据是怎么测的?(实验方法)
#   □ 数据量多少?标签怎么定义?
#   □ 【预测准了能改变什么决策?】

核心实践:划分方式

# 【TDC 最有教学价值的部分】

from tdc.single_pred import ADME

data = ADME(name="Caco2_Wang")

# 三种划分对比
for method in ["random", "scaffold"]:
    split = data.get_split(method=method, seed=42, frac=[0.7, 0.1, 0.2])
    train, test = split["train"], split["test"]
    print(f"{method}: 训练 {len(train)}, 测试 {len(test)}")
    # 训练模型并评测,比较两种划分下的性能差距

# ---- 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_drug = data.get_split(method="cold_split", column_name="Drug")
split_prot = data.get_split(method="cold_split", column_name="Target")
split_both = data.get_split(method="cold_split",
                            column_name=["Drug", "Target"])

# 【练习】:在这三种划分下各训练一个模型,比较性能
#   典型结果:
#     random        Pearson 0.85
#     cold drug     Pearson 0.60
#     cold protein  Pearson 0.35
#     cold both     Pearson 0.25
#   → 【这个梯度告诉你模型真实的泛化能力】
#   → 而论文中常常只报告第一个数字(见 169)

# ---- 时间划分 ----
# 部分数据集支持
split = data.get_split(method="time", ...)
# 【最接近真实部署场景】

Benchmark Group:规范的评测方式

# TDC 提供的 Benchmark Group 强制了正确的评测规范

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 = benchmark["train_val"]
        test = benchmark["test"]
        train, valid = group.get_train_valid_split(
            benchmark=name, split_type="default", seed=seed)

        # 训练你的模型
        model = train_model(train, valid)
        predictions[name] = model.predict(test["Drug"])
    predictions_list.append(predictions)

results = group.evaluate_many(predictions_list)
# 返回 {任务名: [均值, 标准差]}
for task, (mean, std) in results.items():
    print(f"{task:30s} {mean:.4f} ± {std:.4f}")

# 【为什么强制多种子重要】:
#   很多任务只有几百到一两千个样本
#   → 单次运行的结果不可靠
#   → 【标准差常常大于方法间的差异】
#
# 【学习价值】:
#   跑一遍就能亲眼看到方差有多大
#   → 以后读论文时会自动怀疑没有标准差的数字

值得重点学习的任务

任务 为什么值得学
Caco2_Wang(通透性) 数据小,能感受小数据建模的困难
hERG(心脏毒性) 实际项目中必看的安全性终点
Solubility_AqSolDB 数据较多,适合比较方法
CYP 系列 多个相关任务,适合练多任务学习
BindingDB / DAVIS(DTI) 练冷启动划分的最佳场景
HIA、Bioavailability 体会「整合性终点」的建模困难
MolGen(生成) 入门分子生成

TDC 的局限(学习时要意识到)

  • 数据质量取决于原始来源:TDC 做了整理,但无法修复不同实验室、不同测定方法之间的系统差异(见 156《AI ADMET 预测模型》);
  • 部分数据集仍然很小:几百个样本的任务不少,统计功效有限;
  • 排行榜的局限刷榜的动机会导致过拟合排行榜——名次靠前不代表在你的数据上好用;
  • 与实际决策的距离:即使某个 ADMET 任务的 RMSE 降低了,也要问「这对项目决策意味着什么」;
  • 不能替代自家数据的验证:这是最重要的一条。

把 TDC 用作「健全性检查」

# 【一个实用的用法】
#
# 当你在自家数据上做出一个模型时:
#   把同样的流程跑在 TDC 的对应任务上
#   → 与公开的最好成绩比较
#
# 判读:
#   接近 SOTA → 你的流程本身没问题
#              自家数据上的表现差是数据问题
#   明显落后 → 【你的流程有问题】
#             先修流程再谈数据
#
# 【反向的用法】:
#   如果你在自家数据上的指标
#   【远好于】TDC 上同类任务的最好成绩,
#   那么几乎可以肯定:
#     - 数据划分有泄漏
#     - 或评测方式有问题
#   → 【这是一个很有用的自检】
#
# 例:
#   TDC 上 hERG 分类最好的 AUC 约 0.85
#   如果你在自家数据上做到 0.97,
#   先检查:是不是同一个化合物出现在训练与测试集?

关键要点

  • 按研发阶段组织的任务列表本身就是一张能力地图,比读综述直观;
  • DTI 的冷启动划分是最有教学价值的实践——亲眼看到性能梯度;
  • Benchmark Group 强制多种子,跑一遍就能看到方差常大于方法间差异
  • 用它做健全性检查:自家指标远好于 TDC 最好成绩,几乎肯定有泄漏。

延伸资源