pytdc-therapeutics-data-commons について
PyTDCは、創薬研究向けのAI対応データセットとベンチマークを提供します。機械学習研究者向けに、標準化されたデータ分割や評価指標、分子生成タスク、分子スコアリング用オラクルを揃えています。
主な機能
- 01キュレーション済み治療データセット
- 02単一・複数エンティティの予測タスク
- 03分子生成データセット
- 04標準化された分割と評価指標
- 05複数シードのベンチマークグループ
- 06分子変換とスコアリングのユーティリティ
活用シーン
- 01ADMEや毒性データでモデルを学習
- 02コールド分割で薬物-標的モデルを評価
- 03複数シードでモデルをベンチマーク
- 04候補分子の生成とスコアリング
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ jaechang-hits/ sciagent-skills --skill pytdc-therapeutics-data-commonsインストール後、Claude Code で/pytdc-therapeutics-data-commonsを入力して読み込まれたか確認します。
同梱ファイルreferences/datasets_catalog.mdreferences/oracles_utilities.md
詳細
PyTDC(Therapeutics Data Commons)
概要
PyTDC は、創薬向けの AI 対応データセットとベンチマークを提供するオープンサイエンスプラットフォームです。治療薬データを、単一インスタンス予測(分子/タンパク質の特性)、複数インスタンス予測(薬物と標的の相互作用)、生成(分子設計、逆合成)の 3 つのカテゴリに分類します。すべてのデータセットには、標準化された分割、評価指標、分子オラクルが用意されています。
使用する場面
- ML モデルのトレーニング用に、キュレーション済みの ADME、毒性、生物活性データセットを読み込む場合
- 標準化された 5 シード評価プロトコルで創薬モデルをベンチマークする場合
- 適切なコールド分割評価を使用して、薬物と標的、または薬物同士の相互作用を予測する場合
- 新規分子を生成し、分子オラクル(QED、SA、DRD2、GSK3B)でスコアリングする場合
- 製薬 ML 向けに、骨格ベースまたは時間ベースのトレーニング/テスト分割を利用する場合
- 分子表現(SMILES から PyG グラフ、ECFP フィンガープリント、SELFIES)を変換する場合
- 化学データベースの検索(化合物検索、生物活性)には、代わりに
chembl-database-bioactivityを使用してください - フォーマット変換以外の分子特徴量化には、代わりに
molfeatを使用してください
前提条件
uv pip install PyTDC
# Core deps: numpy, pandas, scikit-learn, tqdm, fuzzywuzzy
# Optional: rdkit (scaffold splits), torch-geometric (PyG conversion)
API に関する注意:TDC は初回アクセス時にデータセットをダウンロードします(データセットあたり約 10~500 MB)。ダウンロード先を指定するには path='data/' を指定してください。API キーは不要です。
クイックスタート
from tdc.single_pred import ADME
from tdc import Evaluator
# Load dataset with scaffold split
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(f"Train: {len(train)}, Valid: {len(valid)}, Test: {len(test)}")
# Train: ~640, Valid: ~91, Test: ~182
# Evaluate predictions
evaluator = Evaluator(name='MAE')
# score = evaluator(test['Y'].values, predictions)
コア API
モジュール 1:単一インスタンス予測 — データセットへのアクセス
個々の分子またはタンパク質の特性を予測するためのデータセットを読み込みます。
from tdc.single_pred import ADME, Tox, HTS, QM
# ADME — pharmacokinetic properties
data = ADME(name='Caco2_Wang') # Intestinal permeability (regression)
data = ADME(name='BBB_Martins') # Blood-brain barrier (binary)
data = ADME(name='Lipophilicity_AstraZeneca') # LogD (regression)
data = ADME(name='Solubility_AqSolDB') # Aqueous solubility
# Toxicity — adverse effects
data = Tox(name='hERG') # Cardiotoxicity (binary)
data = Tox(name='AMES') # Mutagenicity (binary)
data = Tox(name='DILI') # Drug-induced liver injury
data = Tox(name='ClinTox') # Clinical trial toxicity
# Access data as DataFrame
df = data.get_data(format='df')
print(df.columns.tolist())
# ['Drug_ID', 'Drug', 'Y'] — Drug is SMILES, Y is target label
print(f"Dataset size: {len(df)}, Label range: [{df['Y'].min():.2f}, {df['Y'].max():.2f}]")
その他の単一予測タスク:HTS(スクリーニング)、QM(量子力学)、Yields、Epitope、Develop、CRISPROutcome。
モジュール 2:複数インスタンス予測 — 相互作用データセット
生物医学的エンティティのペア間の相互作用を予測するためのデータセットを読み込みます。
from tdc.multi_pred import DTI, DDI, PPI
# Drug-Target Interaction — binding affinity
data = DTI(name='BindingDB_Kd') # 52,284 pairs, Kd values
data = DTI(name='DAVIS') # 30,056 pairs, kinase binding
data = DTI(name='KIBA') # 118,254 pairs, kinase bioactivity
# Drug-Drug Interaction — interaction type prediction
data = DDI(name='DrugBank') # 191,808 pairs, 86 interaction types
# Protein-Protein Interaction
data = PPI(name='HuRI')
# Multi-instance data format
df = data.get_data(format='df')
print(df.columns.tolist())
# ['Drug_ID', 'Drug', 'Target_ID', 'Target', 'Y']
# Drug=SMILES, Target=protein sequence, Y=binding affinity or class
その他の複数インスタンスタスク:GDA、DrugRes、DrugSyn、PeptideMHC、AntibodyAff、MTI、Catalyst、TrialOutcome。
モジュール 3:生成タスク — 分子設計
分子生成と逆合成のためのトレーニングセットとオラクルを読み込みます。
from tdc.generation import MolGen, RetroSyn, PairMolGen
from tdc import Oracle
# Molecule generation — training data
data = MolGen(name='ChEMBL_V29') # 1.6M drug-like SMILES
split = data.get_split()
train_smiles = split['train']['Drug'].tolist()
# Oracle scoring — evaluate generated molecules
oracle = Oracle(name='GSK3B') # GSK3B inhibition predictor (0-1)
score = oracle('CC(C)Cc1ccc(cc1)C(C)C(O)=O')
print(f"GSK3B score: {score:.4f}")
# Batch evaluation
scores = oracle(['CCO', 'c1ccccc1', 'CC(=O)O'])
print(f"Batch scores: {scores}")
# Retrosynthesis — reaction prediction
data = RetroSyn(name='USPTO') # 1.9M reactions
split = data.get_split()
# Paired generation — prodrug design
data = PairMolGen(name='Prodrug')
モジュール 4:データ分割と評価
適切なデータ分割と標準化された評価指標を適用します。
from tdc.single_pred import ADME
from tdc.multi_pred import DTI
from tdc import Evaluator
# Scaffold split — ensures chemical diversity between sets
data = ADME(name='Caco2_Wang')
split = data.get_split(method='scaffold', seed=42, frac=[0.7, 0.1, 0.2])
# Cold splits — for DTI (unseen drugs/targets in test set)
data = DTI(name='BindingDB_Kd')
cold_drug = data.get_split(method='cold_drug', seed=1)
cold_target = data.get_split(method='cold_target', seed=1)
# Verify no overlap in cold split
train_drugs = set(cold_drug['train']['Drug_ID'])
test_drugs = set(cold_drug['test']['Drug_ID'])
print(f"Drug overlap: {len(train_drugs & test_drugs)}") # 0
# Evaluation metrics
eval_mae = Evaluator(name='MAE')
eval_auc = Evaluator(name='ROC-AUC')
eval_spearman = Evaluator(name='Spearman')
# score = eval_mae(y_true, y_pred)
利用可能な分割方法:random、scaffold(Bemis-Murcko)、cold_drug、cold_target、cold_drug_target、temporal。
利用可能な指標:分類 — ROC-AUC、PR-AUC、F1、Accuracy、Kappa。回帰 — RMSE、MAE、R2、MSE。ランキング — Spearman、Pearson。マルチラベル — Micro-F1、Macro-F1。
モジュール 5:ベンチマークグループ
モデル比較のために、標準化された複数シード評価プロトコルを実行します。
from tdc.benchmark_group import admet_group
# Load ADMET benchmark (22 datasets)
group = admet_group(path='data/')
# Standard 5-seed evaluation protocol
benchmark = group.get('Caco2_Wang')
predictions = {}
for seed in [1, 2, 3, 4, 5]:
train_df = benchmark['train']
valid_df = benchmark['valid']
test_df = benchmark['test']
# Train your model on train_df, tune on valid_df
# predictions[seed] = model.predict(test_df['Drug'])
predictions[seed] = test_df['Y'].values # placeholder
# Get benchmark results
results = group.evaluate(predictions)
print(f"Mean MAE: {results['Caco2_Wang'][0]:.4f} ± {results['Caco2_Wang'][1]:.4f}")
主な概念
データセットの構成
| カテゴリ | インポートパス | タスク例 | データ形式 |
|---|---|---|---|
| 単一インスタンス | tdc.single_pred | ADME、Tox、HTS、QM | Drug(SMILES)+ Y(ラベル) |
| 複数インスタンス | tdc.multi_pred | DTI、DDI、PPI、DrugSyn | Drug + Target + Y |
| 生成 | tdc.generation | MolGen、RetroSyn | SMILES コレクション |
| ベンチマーク | tdc.benchmark_group | admet_group | キュレーション済み分割 |
オラクルのカテゴリ
| カテゴリ | 例 | 速度 | 出力範囲 |
|---|---|---|---|
| 生化学的 | DRD2、GSK3B、JNK3、5HT2A | 中速(ML) | 確率 0~1 |
| 物理化学的 | QED、SA、LogP、MW | 高速(ルールベース) | 指標によって異なる |
| 複合 | Isomer_Meta、Median1/2、Rediscovery | 中速 | 0~1 の複合値 |
| 特化型 | ASKCOS、Docking、Vina | 低速(外部) | さまざま |
データ処理ユーティリティ
| ユーティリティ | 関数 | 例 |
|---|---|---|
| 形式変換 | MolConvert(src, dst) | SMILES → PyG、ECFP、SELFIES、DGL |
| 分子フィルター | MolFilter(filters) | PAINS、BMS、Glaxo、薬物らしさ |
| ラベルの二値化 | label_transform() | 連続値 → しきい値で二値化 |
| 単位変換 | label_transform(from_unit, to_unit) | nM → pIC50 |
| ID 解決 | cid2smiles()、uniprot2seq() | PubChem CID → SMILES |
| データセット一覧 | retrieve_dataset_names(task) | すべての ADME データセットを一覧表示 |
一般的なワークフロー
ワークフロー 1:複数シードによる ADME モデル評価
from tdc.single_pred import ADME
from tdc import Evaluator
import numpy as np
data = ADME(name='Caco2_Wang')
evaluator = Evaluator(name='MAE')
results = []
for seed in [1, 2, 3, 4, 5]:
split = data.get_split(method='scaffold', seed=seed)
train, valid, test = split['train'], split['valid'], split['test']
# model.fit(train['Drug'], train['Y'])
# preds = model.predict(test['Drug'])
preds = test['Y'].values + np.random.normal(0, 0.1, len(test)) # placeholder
score = evaluator(test['Y'].values, preds)
results.append(score)
print(f"Seed {seed}: MAE = {score:.4f}")
print(f"Mean MAE: {np.mean(results):.4f} ± {np.std(results):.4f}")
ワークフロー 2:多目的分子スコアリング
from tdc import Oracle
import numpy as np
# Define multi-objective scoring
oracles = {
'QED': (Oracle(name='QED'), 0.3), # drug-likeness
'SA': (Oracle(name='SA'), 0.3), # synthetic accessibility
'GSK3B': (Oracle(name='GSK3B'), 0.4), # target activity
}
test_smiles = ['CC(C)Cc1ccc(cc1)C(C)C(O)=O', 'c1ccc2c(c1)cc1ccc3cccc4ccc2c1c34']
for smi in test_smiles:
scores = {}
weighted_sum = 0
for name, (oracle, weight) in oracles.items():
score = oracle(smi)
scores[name] = score
weighted_sum += score * weight
print(f"SMILES: {smi[:30]}...")
print(f" Scores: {scores}")
print(f" Weighted: {weighted_sum:.4f}")
ワークフロー 3:Cold-Split による DTI 評価(テキストのみ)
- DTI データセットを読み込む —
DTI(name='BindingDB_Kd')(コア API モジュール 2) - cold_drug 分割を適用する —
data.get_split(method='cold_drug', seed=seed)(コア API モジュール 4) - 訓練セットとテストセットで薬剤の重複がないことを確認する(モジュール 4 の重複チェック)
- 訓練セットでモデルを学習し、テストセットで予測する
- スピアマン相関で評価する —
Evaluator(name='Spearman')(モジュール 4) - 5 つのシードで繰り返し、平均 ± 標準偏差を報告する(ワークフロー 1 と同じ方法)
主なパラメーター
| パラメーター | 関数/モジュール | デフォルト | 範囲/選択肢 | 効果 |
|---|---|---|---|---|
method | get_split() | 'scaffold' | random、scaffold、cold_drug、cold_target、temporal | 訓練/テストの分割方法 |
seed | get_split() | 42 | ベンチマークでは 1~5 | 再現性を確保します。ベンチマークには 5 つのシードを使用します |
frac | get_split() | [0.7, 0.1, 0.2] | 合計が 1.0 であること | 訓練/検証/テストの割合 |
name | Evaluator() | — | MAE、RMSE、ROC-AUC、Spearman など | 評価指標 |
name | Oracle() | — | QED、SA、GSK3B、DRD2 など | 分子のスコアリング関数 |
src/dst | MolConvert() | — | SMILES、SELFIES、PyG、DGL、ECFP4 | 分子表現の形式 |
path | admet_group() | 'data/' | 任意のディレクトリ | データセットのダウンロード/キャッシュ先 |
format | get_data() | 'df' | 'df'、'dict' | 出力データ形式 |
ベストプラクティス
- 分子特性予測には必ずスキャフォールド分割を使用してください — ランダム分割では構造情報が漏洩し、性能指標が過大評価されます
- 平均 ± 標準偏差とともに 5 シードでの評価結果を報告してください — 単一シードの結果では手法の比較に信頼性がありません
- 相互作用予測にはコールド分割を使用してください —
cold_drugは未知の薬剤への汎化を、cold_targetは未知の標的への汎化を検証します - 学習前に
MolFilter(PAINS、薬物らしさ)で分子を早期にフィルタリングし、問題のある化合物を除去してください - オラクルを適切に正規化してください — QED は 0~1、SA は 1~10(低いほど良い)を返し、結合スコアはさまざまです。組み合わせる前にオラクルのドキュメントを確認してください
- 永続的な
pathを指定してデータセットをキャッシュしてください — セッションごとに大きなデータセットを再ダウンロードせずに済みます
よく使うレシピ
レシピ 1:データセットの探索と統計
from tdc.single_pred import ADME
from tdc.utils import retrieve_dataset_names
# List all ADME datasets
datasets = retrieve_dataset_names('ADME')
print(f"Available ADME datasets: {datasets}")
# Load and inspect
data = ADME(name='Caco2_Wang')
df = data.get_data(format='df')
print(f"Size: {len(df)}")
print(f"Label stats: mean={df['Y'].mean():.2f}, std={df['Y'].std():.2f}")
print(f"SMILES example: {df['Drug'].iloc[0]}")
レシピ 2:分子形式の変換パイプライン
from tdc.chem_utils import MolConvert
# SMILES to multiple representations
smiles = 'CC(C)Cc1ccc(cc1)C(C)C(O)=O'
converter_ecfp = MolConvert(src='SMILES', dst='ECFP4')
converter_selfies = MolConvert(src='SMILES', dst='SELFIES')
ecfp = converter_ecfp(smiles)
selfies = converter_selfies(smiles)
print(f"ECFP4 shape: {ecfp.shape}") # (1024,) binary fingerprint
print(f"SELFIES: {selfies}")
レシピ 3:制約充足を伴うカスタムオラクル
from tdc import Oracle
# Define property constraints
constraints = {
'QED': (Oracle(name='QED'), 0.5, 1.0), # min, max
'SA': (Oracle(name='SA'), 1.0, 4.0),
'LogP': (Oracle(name='LogP'), -0.5, 5.0),
}
def check_constraints(smiles):
"""Check if molecule satisfies all property constraints."""
results = {}
all_pass = True
for name, (oracle, lo, hi) in constraints.items():
score = oracle(smiles)
passed = lo <= score <= hi
results[name] = {'score': score, 'passed': passed}
all_pass = all_pass and passed
return all_pass, results
passed, details = check_constraints('CC(C)Cc1ccc(cc1)C(C)C(O)=O')
for name, info in details.items():
status = "PASS" if info['passed'] else "FAIL"
print(f"{name}: {info['score']:.3f} [{status}]")
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
ModuleNotFoundError: tdc | パッケージがインストールされていません | uv pip install PyTDC |
| Scaffold split に失敗する | RDKit の依存関係が不足しています | Scaffold 分解には uv pip install rdkit を実行します |
| データセットのダウンロードがタイムアウトする | データセットが大きい、または接続が遅い | 永続キャッシュには path='data/' を設定し、再試行します |
データセット名で KeyError が発生する | 名前またはタスクカテゴリが誤っています | retrieve_dataset_names('ADME') を使って有効な名前を一覧表示します |
| Oracle が NaN を返す | 無効な SMILES、または RDKit の解析に失敗しています | まず RDKit の MolFromSmiles() で SMILES を検証します |
| Cold split のテストセットが空になる | 一意なエンティティが少なすぎます | より大きなデータセットで frac=[0.7, 0.1, 0.2] を使用します |
| ベンチマーク評価でエラーが発生する | 予測の形式が誤っています | シードをキーにした dict を渡します:{1: preds1, 2: preds2, ...} |
| 大規模データセットでメモリエラーが発生する | データセット全体がメモリに読み込まれています | チャンク単位で処理するか、より小さな分割比率を使用します |
| PyG への変換に失敗する | torch-geometric がインストールされていません | グラフ変換には uv pip install torch-geometric を実行します |
同梱リソース
references/datasets_catalog.md
内容:タスクカテゴリ(単一インスタンス、複数インスタンス、生成)別に整理した、TDC の全データセットの完全なカタログです。データセット名、サイズ、ラベルの種類、データソースを掲載しています。インラインから移動:上位の ADME/Tox/DTI データセットとコード例をまとめ、Core API Modules 1-2 に統合しました。省略:なし。すべてのデータセット項目をカタログ形式で保持しています。
references/oracles_utilities.md
内容:Oracle の詳細なドキュメント(17 種類以上の Oracle、パラメーター、速度の区分、出力範囲、カスタム Oracle のテンプレートを含む)と、データ処理ユーティリティ(形式変換の対象、分子フィルターの種類、ラベル変換、エンティティ解決)です。元の oracles.md と utilities.md を統合しました。インラインから移動:クイックスタートの Oracle 使用パターン、主要な評価指標、分割方法、MolConvert のパターンを Core API Modules 3-4 に移動しました。省略:分布学習の KS 検定の例(ニッチな統計的比較のため)、リーダーボードへの提出ガイド(プラットフォーム固有のため)。
スクリプトの配置
load_and_split_data.py(215 行):scaffold/cold split のパターン → Core API Module 4、カスタム分割比率 → 主要なパラメーター、評価の例 → Workflow 1。get_split()とEvaluator()を呼び出す薄いラッパーです。benchmark_evaluation.py(328 行):5 シードのプロトコル → Core API Module 5 と Workflow 1、複数データセットの評価 → Workflow 1 のパターン、リーダーボードのガイド → 省略(プラットフォーム固有のため)。molecular_generation.py(405 行):単一/バッチの Oracle 使用 → Core API Module 3、多目的スコアリング → Workflow 2、制約充足 → Recipe 3、分布学習 → 省略(ニッチなため)。
関連スキル
- chembl-database-bioactivity — ChEMBL の化合物/標的/活性データを直接クエリする場合に使用します
- molfeat — TDC に組み込まれた MolConvert の機能を超える、高度な分子特徴量化に使用します
- rdkit-cheminformatics — 分子の操作、部分構造検索、記述子の計算に使用します
参考資料
- TDC 公式ウェブサイト:https://tdcommons.ai
- TDC ドキュメント:https://tdc.readthedocs.io
- GitHub リポジトリ:https://github.com/mims-harvard/TDC
- Huang ら、「Therapeutics Data Commons」NeurIPS 2021 Datasets and Benchmarks