3. 数据获取:公开数据集介绍与下载
做 ADMET 肝毒性预测,第一步不是调参炼丹,而是搞定数据。
说白了,数据质量决定了模型的上限。我刚开始接触这个方向时,光整理数据就花了一周,几个数据集的 assay 命名、ID 格式、文件类型全都不一样,那叫一个头大。所以这一章,我带你把数据源理清楚。
3.1 主流公共数据集概览
目前学术界和工业界做肝毒性预测,最常用的公共数据集就是 Tox21、ToxCast 和 PubChem。各家的侧重点不同,数据格式也不一样。
核心思路: 统一数据格式,做好 ID 映射,这是后续建模的基础。千万别小看这一步,很多项目的结果复现不了,问题就出在数据源头和预处理上。
- Tox21:美国国立卫生研究院(NIH)牵头,目标是测试 10,000+ 化合物。数据以 CSV 和 SDF 格式发布,主要包含核受体和应激反应通路数据。
- ToxCast:美国环保署(EPA)的 Phases I/II 项目,覆盖 1,800+ 化合物。数据量比 Tox21 大,assay 类型也更丰富,但格式比较复杂,有 CSV 和 SQLite 数据库两种。
- PubChem:不仅是数据集,更是一个开放的化学数据库。它整合了 Tox21 和 ToxCast 的原始数据,并提供统一的 CID 标识符。我建议大家通过 PubChem 来交叉验证化合物结构。
3.2 数据集特点对比
我把这三个数据集的关键属性整理了一下,方便你快速对比。
| 特性 | Tox21 | ToxCast | PubChem |
|---|---|---|---|
| 发布机构 | NIH / EPA / FDA | EPA | NCBI |
| 化合物数量 | ~12,000 | ~1,800 | 1.1亿+ |
| 重点关注 | 核受体与应激反应 | 高内涵筛选、体外毒理 | 综合数据、生物活性 |
| 文件格式 | CSV + SDF | CSV + SQLite | FTP / API 下载 |
| 适用场景 | 分类模型训练 | 多任务学习 | 数据补充与验证 |
避坑指南
我曾经直接用 ToxCast 的原始 CSV 文件进行建模,结果发现里面的 Assay 名称和 Tox21 根本对不上。后来我统一用 PubChem CID 做中介,才把两个数据集打通。切记,ID 映射要慎之又慎。
3.3 数据下载实战
这里我演示一下怎么用 Python 下载 Tox21 的数据。不建议手动下载,因为文件会更新,自动化脚本更靠谱。
import requests
import zipfile
import os
# Tox21 数据下载地址(以官方公开地址为例)
url = "https://tripod.nih.gov/tox21/challenge/download"
local_zip = "tox21_data.zip"
# 流式下载,避免内存暴涨
response = requests.get(url, stream=True)
response.raise_for_status()
with open(local_zip, "wb") as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)
print("Tox21 数据下载完成")
# 解压
with zipfile.ZipFile(local_zip, 'r') as zip_ref:
zip_ref.extractall("./tox21_raw/")
print("解压完成,文件列表:")
print(os.listdir("./tox21_raw/"))
注意
我曾经直接复制了官网的 wget 链接,结果发现证书过期了,导致下载失败。建议设置超时参数和重试机制,不然半夜跑脚本断掉了都不知道。另外,下载前确认一下文件大小,避免下到空文件。
3.4 数据格式解析
下载下来的文件通常是 CSV 或者 SDF 格式。我个人习惯用 Pandas 处理 CSV,用 RDKit 处理 SDF。
解析 Tox21 CSV 文件:
import pandas as pd
# 读取 Tox21 的标签文件
labels_df = pd.read_csv(
"./tox21_raw/tox21_labels.csv",
index_col=0
)
print("数据维度:", labels_df.shape)
print("列名列表:", labels_df.columns.tolist())
# 查看前 5 行,确认数据完整性
labels_df.head()
解析 SDF 文件,提取分子结构:
from rdkit import Chem
from rdkit.Chem import PandasTools
# 读取 SDF 文件,转为 DataFrame
sdf_file = "./tox21_raw/tox21_structures.sdf"
molecule_df = PandasTools.LoadSDF(
sdf_file,
smilesName='SMILES',
molColName='Molecule',
includeFingerprints=False
)
print("分子数量:", len(molecule_df))
print(molecule_df[['PUBCHEM_CID', 'SMILES']].head())
3.5 数据整合与 ID 映射
不同数据集用的化合物 ID 不一样,Tox21 用的是内部 ID,PubChem 用的是 CID。你需要把它们统一映射成标准的 SMILES 或 InChIKey。
我个人喜欢用 SMILES 作为桥梁,因为它可以直接用来计算分子描述符。
# 假设我们已有一个 ID 映射表
mapping_df = pd.read_csv("./public/id_mapping.csv")
# 合并分子结构与标签数据
merged_df = molecule_df.merge(
labels_df,
left_on='PUBCHEM_CID',
right_index=True
)
print("整合后的数据集大小:", merged_df.shape)
# 检查是否有缺失值
print("SMILES 缺失数:", merged_df['SMILES'].isna().sum())
我自己惯用的数据范式: 先通过 PubChem API 矫正一遍 SMILES,然后用 RDKit 过滤掉无法规范化处理的分子。这样产出的数据,建模时心里有底。