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())
数据获取与整合流程 Tox21 (CSV/SDF) ToxCast (CSV/SQLite) PubChem (FTP/API) 格式解析与标准化 统一 SMILES / InChIKey ID映射与去重 保留原始 ID 溯源 最终输出:高质量、格式统一的肝毒性特征数据集

我自己惯用的数据范式: 先通过 PubChem API 矫正一遍 SMILES,然后用 RDKit 过滤掉无法规范化处理的分子。这样产出的数据,建模时心里有底。