DeepChem Sweetlead 示例全解析:基于 Tox21 与 SIDER 模型的药物安全性交叉预测
【免费下载链接】deepchemDemocratizing Deep-Learning for Drug Discovery, Quantum Chemistry, Materials Science and Biology项目地址: https://gitcode.com/GitHub_Trending/de/deepchem
导读
SWEETLEAD 是计算机辅助药物发现领域一个著名的"先导化合物"数据库,收录已批准药物、传统草药中的化学分离物以及受管制化学品。本文以 DeepChem 仓库中的 examples/sweetlead/README.md 为核心,结合配套脚本 sweet.py 与 MoleculeNet 数据加载源码,完整讲解如何利用 DeepChem 将 Tox21(毒性)与 SIDER(副作用)上训练好的单任务模型集成起来,对 Sweetlead 化合物库进行跨数据集预测,并输出一张 Tox21×SIDER 的混淆矩阵(协变矩阵),用于分析不同毒性机制与副作用类别之间的关联。读完本文,你将掌握dc.molnet数据加载器、SingletaskToMultitask模型包装器以及多任务预测结果交叉分析的完整实战套路。
Sweetlead 数据集:是什么,为何重要
根据 examples/sweetlead/README.md 的描述,Sweetlead 是一个化学结构数据库,包含三类来源的化合物:
- 已批准药物(approved drugs)
- 传统草药中的化学分离物(chemical isolates from traditional medicinal herbs)
- 受管制化学品(regulated chemicals)
数据在入库前经过了严格的后处理流水线:
- 过滤:只保留活性药物成分(active pharmaceutical ingredient, API),剔除辅料、盐型等无关结构;
- 标准化:对分子结构进行统一标准化处理,保证同一结构在不同来源中表示一致;
- 合并:同一药物的不同制剂/配方在最终数据库中合并为一条记录。
该数据集引用自 Novick 等人的论文:"SWEETLEAD: an in silico database of approved drugs, regulated chemicals, and herbal isolates for computer-aided drug discovery."PLoS One8.11 (2013)。由于其同时覆盖"已上市药物 + 天然产物 + 管制化学品"三种语义完全不同的化学空间,它常被用于在已有模型上进行外部验证——即检验模型在未见过的、贴近真实药物研发场景的数据上的泛化表现。
三行代码载入 Sweetlead:dc.molnet.load_sweet
DeepChem 已把 Sweetlead 接入 MoleculeNet 数据集体系,只需一行调用即可完成下载、特征化、切分与变换。其实现位于 deepchem/molnet/load_function/sweetlead_datasets.py,并通过 deepchem/molnet/init.py 导出:
sweet_tasks, (sweet_dataset, _, _), sweet_transformers = dc.molnet.load_sweet()load_sweet完整签名与参数
从源码(sweetlead_datasets.py)可以看到,其签名与 Tox21、SIDER 等其他 MoleculeNet 加载器完全一致:
def load_sweet( featurizer: Union[dc.feat.Featurizer, str] = 'ECFP', splitter: Union[dc.splits.Splitter, str, None] = 'scaffold', transformers: List[Union[TransformerGenerator, str]] = ['balancing'], reload: bool = True, data_dir: Optional[str] = None, save_dir: Optional[str] = None, **kwargs )各参数说明如下(可与 molnet_loader.py 中_MolnetLoader的构造逻辑对照):
| 参数 | 默认值 | 说明 |
|---|---|---|
featurizer | 'ECFP' | 分子特征化器,可传实例或字符串快捷名。源码注册表支持ecfp(1024 位圆指纹)、graphconv(ConvMolFeaturizer)、raw、onehot、smiles2img、weave等 |
splitter | 'scaffold' | 数据切分器,支持index、random、scaffold、butina、fingerprint、task、stratified;传None则全部数据放进单个数据集,不切分 |
transformers | ['balancing'] | 数据变换器列表,字符串快捷名包括balancing(类别平衡)、normalization、minmax、clipping、log;也可以直接传TransformerGenerator对象 |
reload | True | 是否启用磁盘缓存:首次调用会按"数据集-特征化器-切分器-变换器"路径缓存到本地,后续调用直接加载 |
data_dir | None | 原始数据保存目录,缺省使用dc.utils.data_utils.get_data_dir() |
save_dir | None | 特征化后数据集保存目录,同样缺省指向全局数据目录 |
底层加载流程:_SweetLoader与_MolnetLoader
load_sweet内部实例化_SweetLoader,其核心是create_dataset方法(sweetlead_datasets.py):
def create_dataset(self) -> Dataset: dataset_file = os.path.join(self.data_dir, "sweet.csv.gz") if not os.path.exists(dataset_file): dc.utils.data_utils.download_url(url=SWEETLEAD_URL, dest_dir=self.data_dir) loader = dc.data.CSVLoader(tasks=self.tasks, feature_field="smiles", featurizer=self.featurizer) return loader.create_dataset(dataset_file, shard_size=8192)可见:原始数据以sweet.csv.gz的形式从远程 URL 下载;SWEETLEAD_TASKS = ["task"]定义了唯一任务列;SMILES 作为特征输入字段,配合指定特征化器生成特征,并以 8192 的 shard 大小分片构建DiskDataset。
后续的切分与变换由基类_MolnetLoader.load_dataset统一完成(molnet_loader.py):
- 若
splitter非空,先执行train_valid_test_split,得到 train / valid / test 三份数据; - 每个
Transformer仅在训练集上拟合并分别变换三份数据(防止数据泄露); - 若
reload=True且数据为DiskDataset,则将结果(含变换器)落盘缓存,下次直接读取。
理解这条链路对后续预测非常关键:Sweetlead 在示例中扮演的是"外部预测对象"角色,不需要训练/测试切分,只需将全部数据作为单一数据集传给已训练好的模型。
从单任务到多任务:SingletaskToMultitask包装器
示例脚本的核心技巧在于:Tox21 有 12 个毒性任务、SIDER 有 27 个副作用任务(任务清单见 tox21_datasets.py 与 sider_datasets.py),而 scikit-learn 的RandomForestClassifier本质是单任务模型。为此 DeepChem 提供了SingletaskToMultitask包装器,实现位置在 deepchem/models/multitask.py。
tox_tasks, (tox_train, tox_valid, tox_test), tox_transformers = dc.molnet.load_tox21() def model_builder(model_dir): sklearn_model = RandomForestClassifier( class_weight="balanced", n_estimators=500, n_jobs=-1) return dc.models.SklearnModel(sklearn_model, model_dir) tox_model = SingletaskToMultitask(tox_tasks, model_builder) tox_model.fit(tox_train)其工作机制(依据 multitask.py 源码):
- 构造:为每个任务在
model_dir下创建独立子目录(task_model_dirs[task]); fit:通过_to_singletask将多任务DiskDataset按任务列拆分成单任务数据集——对于每个样本,仅保留该任务权重w != 0的行(即该样本在该任务上有标注才参与训练),再对每个任务各自调用model_builder构造并训练一个独立的随机森林;predict:逐个任务reload已保存的模型并预测,最后用np.stack把各任务输出按列拼接成(样本数, 任务数)的概率矩阵。
因此tox_model.predict(sweet_dataset, sweet_transformers)会返回形状为(sweet 分子数, 12)的矩阵,sider_model则返回(sweet 分子数, 27)的矩阵。
完整实战:跨数据集预测与混淆矩阵生成
下面逐段解析 examples/sweetlead/sweet.py 的完整流水线,它同时是本文最可直接复用的代码模板。
第一步:训练 Tox21 与 SIDER 模型
tox_tasks, (tox_train, tox_valid, tox_test), tox_transformers = dc.molnet.load_tox21() classification_metric = Metric( metrics.roc_auc_score, np.mean, mode="classification") def model_builder(model_dir): sklearn_model = RandomForestClassifier( class_weight="balanced", n_estimators=500, n_jobs=-1) return dc.models.SklearnModel(sklearn_model, model_dir) print(tox_train.get_task_names()) print(tox_tasks) tox_model = SingletaskToMultitask(tox_tasks, model_builder) tox_model.fit(tox_train)要点:
- 随机森林采用
class_weight="balanced"应对毒性/副作用数据普遍存在的类别不平衡; n_estimators=500、n_jobs=-1(使用全部 CPU 核)兼顾精度与训练速度;- 每个任务独立训练一棵 500 棵树的森林,共 12(Tox21)+ 27(SIDER)个模型;
dc.molnet.load_tox21()/load_sider(split="random")返回(tasks, (train, valid, test), transformers)三元组。
第二步:加载 Sweetlead 并预测
sweet_tasks, (sweet_dataset, _, _), sweet_transformers = dc.molnet.load_sweet() sider_predictions = sider_model.predict(sweet_dataset, sweet_transformers) tox_predictions = tox_model.predict(sweet_dataset, sweet_transformers)注意这里把sweet_transformers传入predict——训练时所用的变换器(默认balancing)会在预测阶段被undo_transforms逻辑还原,确保输出的是与训练数据同一语义空间的预测值。load_sweet()默认splitter='scaffold',因此返回值中的后两个数据集(valid/test)被_丢弃,预测只针对完整数据集进行。
第三步:构建 Tox21×SIDER 混淆矩阵
sider_dimensions = sider_predictions.shape[1] # 27 tox_dimensions = tox_predictions.shape[1] # 12 confusion_matrix = np.zeros(shape=(tox_dimensions, sider_dimensions)) for i in range(tox_predictions.shape[0]): nonzero_tox = np.nonzero(tox_predictions[i, :]) nonzero_sider = np.nonzero(sider_predictions[i, :]) for j in nonzero_tox[0]: for k in nonzero_sider[0]: confusion_matrix[j, k] += 1 df = pd.DataFrame(confusion_matrix) df.to_csv("./tox_sider_matrix.csv")这段代码的核心思想:对 Sweetlead 中的每个分子,分别统计其被 Tox21 哪些任务"命中"(预测概率非零)以及被 SIDER 哪些任务"命中",然后在 12×27 的矩阵对应位置累加。最终tox_sider_matrix.csv的单元格(j, k)表示"同时被 Tox21 第 j 个任务和 SIDER 第 k 个任务预测为阳性的 Sweetlead 化合物数量",可用于观察:
- 特定毒性机制(如核受体通路
NR-*、应激反应通路SR-*)与特定副作用系统(如心脏、肝胆、神经系统)之间的共现关系; - 已上市药物/草药分离物中哪些结构同时带有高风险信号,辅助后续的脱靶效应排查。
运行方式
# 在仓库根目录执行 python examples/sweetlead/sweet.py运行前提:已安装 DeepChem 及其 scikit-learn 依赖(环境配置可参考 requirements/env_common.yml 等环境文件);首次运行会自动下载 tox21、sider、sweet 三个数据集(原始 gz 文件与特征化缓存统一存放在get_data_dir()指定目录),耗时取决于网络与 CPU 核数。
参数定制与扩展思路
更换特征化器
load_sweet与load_tox21、load_sider都接受字符串快捷名,可一键切换表征方式:
# 图卷积特征:适合后续接 GNN 模型 dc.molnet.load_sweet(featurizer='graphconv') # 分子图 Weave 特征 dc.molnet.load_sweet(featurizer='weave')注意:特征化器必须与训练模型一致——用ECFP(默认)训练的随机森林无法直接预测graphconv特征化的数据。
模型可替换性
model_builder是SingletaskToMultitask的唯一模型入口,可平滑替换为其他SklearnModel兼容的分类器(如ExtraTreesClassifier、GradientBoostingClassifier或SVC),结构无需改动;但需注意该包装器当前实现仅面向 sklearn 模型(见 multitask.py 的 Note 说明)。
更严格的切分控制
若希望 Sweetlead 预测完全独立于训练集,可显式传入splitter=None与训练时相同的data_dir,并利用reload缓存避免重复特征化:
sweet_tasks, (sweet_dataset,), sweet_transformers = dc.molnet.load_sweet( splitter=None, data_dir="./data", reload=True)总结:该示例的工程价值
从仓库证据看,这个示例演示了一条可复用的"跨数据集药物安全性筛查"流水线:
- 用 MoleculeNet 标准加载器(load_tox21、load_sider、load_sweet)统一管理数据获取与特征化;
- 用
SingletaskToMultitask让 500 棵树的随机森林逐个任务训练,实现单任务模型的多任务化; - 对 Sweetlead 全库预测并输出 Tox21×SIDER 共现矩阵,把"模型置信度"转化为可读的机制关联分析表。
其设计思路与 MoleculeNet 的统一加载抽象(_MolnetLoader基类)一脉相承:数据集是插拔的、模型是插拔的,唯有预测-交叉分析的主干逻辑保持稳定,这正是它适合作为药物化学、计算毒理学研究起点的原因。
【免费下载链接】deepchemDemocratizing Deep-Learning for Drug Discovery, Quantum Chemistry, Materials Science and Biology项目地址: https://gitcode.com/GitHub_Trending/de/deepchem
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考