
简介药物联用是现代临床的常态但新药组合的安全性验证却受限于实验成本与时间。药物相互作用预测成为AI制药与计算药物发现领域的热点任务。深度学习模型能够直接从分子结构自动提取特征学习两个药物间的非线性交互模式为临床风险评估提供快速筛查手段。这类项目通常涉及数据清洗、分子表示学习、图神经网络编码、交互层设计以及严谨的冷启动评估策略。使用分子图与GNN可有效建模原子级拓扑关系结合交叉注意力机制提升配对预测精度而AUPR等不平衡指标则更贴近药物安全筛查的实际需求。本文完整复盘了一个DDI预测项目涵盖公开数据集选型、SMILES标准化、负样本构造、模型训练与可解释性分析为AI医疗方向的工程师和数据科学家提供了一套可落地的工程参考。 开头先抖个底药物相互作用Drug-Drug InteractionDDI预测这个方向我前前后后做了三个多月。起因很现实——联合用药太普遍了但医院药房、药企安全评价、临床药师手里能用得上的 DDI 信息基本还是靠药品说明书、老数据库和专家经验。一个新药上市时能做完的联合用药实验非常有限大量组合只能靠预测。而深度学习恰好擅长从分子结构里自动找模式于是就有了这个项目搭建一套从数据清洗、药物表示、模型训练到评估部署的完整 DDI 预测流程。这篇文章写的是这个项目的完整复盘内容包括公开数据怎么选、药物结构怎么编码、图神经网络和交互层怎么搭、训练时有哪些坑、以及最后怎么把模型预测变成能给人解释的依据。适合正在做 AI 制药、计算药物发现、生物信息方向的同学也适合想转行到 AI医疗并且需要完整实战项目的工程师。1. 为什么是深度学习DDI预测的问题本质1.1 药物相互作用到底是什么先说清楚这个任务本身。药物相互作用指的是两种或多种药物同时服用时产生的效果发生变化。这种变化有时候是好事联合降压、联合抗肿瘤更多时候是坏事——药效下降、毒性叠加、代谢受阻严重情况会直接导致患者死亡。从机制上讲DDI 大致分两类。药代动力学相互作用占大多数核心是 CYP450 酶系被抑制或诱导。比如某药是 CYP3A4 的强抑制剂另一个经过 CYP3A4 代谢的药一起服用后者的血药浓度就会飙升容易中毒。药效学相互作用则是在靶点或通路层面产生协同或拮抗比如两个都作用于凝血系统的药联合使用出血风险成倍增加。难点在于一个药物的分子结构就是一张图另一张图凑过来反应会发生在哪些原子、哪些官能团、哪些通路上人很难一眼看穿。传统上只能靠高成本实验去试或者等真实世界的用药案例积累够了再统计出来。1.2 传统方法卡在哪早期的计算方法很直接分子结构相似性。假设结构相似的药物相互作用模式也相似。用 Tanimoto 系数算一下 ECFP 指纹相似度找个阈值判定。这个思路在分子性质预测上很有效但在 DDI 任务上不够用——因为 DDI 是由两个分子的互补性决定的不是相似性决定的。举个例子一个药物抑制 CYP 酶另一个药物是这个酶的底物两者发生相互作用的重心在于抑制剂的某个疏水区域 底物被代谢的位点的匹配而不是整体结构长得像。单纯看整体相似度会漏掉这类关键信号。后来的机器学习方法好一些把药物对的分子描述符拼接起来交给 Random Forest 或 SVM 分类。问题是特征工程极其繁琐分子描述符几百上千维特征之间交互复杂人工设计彻底表达不过来。而且模型没法泛化到全新结构的药物。1.3 深度学习的切入点在哪儿深度学习在这类任务上真正解决了三件事。第一自动特征提取。不管是 SMILES 序列还是分子图模型可以直接从原始表示学习不需要人工定义描述符。第二非线性交互建模。DDI 本质上是两个分子之间的组合效应深度学习擅长构造高维交互特征。第三跨分子泛化。在足够大的训练数据上学到的是相互作用模式而不是死记硬背某个药物对所以新药出现时它能尝试推断。我把这个项目定位成一套分子对级的二分类模型输入两个药物的分子表示输出一个 0~1 的概率表示这对药物是否存在潜在相互作用。虽然真实场景中 DDI 还会分机制类型代谢、转运、药效学但先把二分类做扎实是后续所有工作的前提。2. 数据与特征决定模型天花板的两个基础件2.1 公开数据集的选型与搭配做 DDI 预测能用的公开数据集不少但我实际比较下来各有利弊不应该只盯一个。我把它们分三类DrugBank结构清晰有批准药物、实验药物还有一部分明确的 DDI 记录。适合做基础正样本但是覆盖面有限很多新药联用记录是空的。DDI Corpus从医学文献里手工标注出来的药物相互作用句子级语料正样本有描述机制。数据量中等但标注质量高适合辅助训练或者做文本特征注入。TWOSIDES从不良事件报告系统里挖掘而来覆盖面大组合数量惊人。缺点是噪声大很多记录是统计相关性而非因果验证直接当标签会有假阳性。我用的是 DrugBank TWOSIDES 混合再拿 DDI Corpus 做少量验证。正样本取三者并集负样本从未标注的药物对中采样。这里有个重要提醒从海量未标注组合里抽负样本抽到的不一定是真阴性只是没有报道过相互作用。这是弱监督问题后面会专门说。数据集正样本量级结构化程度主要问题DrugBank中等高覆盖面有限DDI Corpus较小高依赖文献量TWOSIDES很大中噪声多标签偏弱2.2 负样本构造与类别不平衡处理负样本构造是整个数据管线里最容易影响结果的一环。实际训练数据里已知相互作用的药物对远少于所有可能组合所以负样本要从无标注组合中随机抽取。我尝试过三种策略完全随机采样实现最简单但容易采到大量结构差异极大的药物对模型学到的是长得不一样就有相互作用起不到对抗训练作用。药物频次匹配采样保证每个药物在正负样本中出现的次数接近。这个方法让模型不能靠药物热度偷懒推荐首选。结构均匀采样按分子骨架类别分层采样保证化学空间覆盖。代价是采样复杂度高但训练稳定性最好。负样本多、正样本少是常态实际正负比例可能到 1:5 甚至 1:20。我最后把比例控制在 1:2 到 1:5因为 DDI 预测场景下漏报一个真正的危险药物组合比多报一个无害组合严重得多。类别不平衡问题放在模型层面解决用加权损失或者 Focal Loss后面具体展开。2.3 药物表示从SMILES清洗到分子图药物数据进模型之前最基础也最容易被忽视的就是 SMILES 清洗。公开数据库里同一个分子经常有多种写法有的带盐有的不带有的原子顺序完全随机。我用 RDKit 统一做了规范化处理MolFromSmiles解析再MolToSmiles输出标准 SMILES同时删掉盐和混合物片段过滤掉分子量过大或原子数超过 200 的异常分子。这一步如果偷懒会出现同一个药在图谱里被当成两个节点的情况模型训练时同一结构学习两套特征严重影响下游表现。分子表示我对比过两条路线一是MACCS / ECFP4 指纹。实现快适合快速跑基线。有 166 维 MACCS、2048 位 ECFP4都能用。缺点是位点编码丢失了原子的拓扑关系模型上限有限。二是分子图。把每个原子看成节点化学键看成边节点特征用原子类型、杂化类型、度数、是否在环、氢键供体/受体等边特征用键型、是否共轭、是否在环内。这个表示保留了完整的 3D 拓扑关系虽然没坐标但有连接关系是 GNN 模型的输入基础。再往上还有 SMILES 级的预训练语言模型比如 ChemBERTa。我试了以后觉得在数据量不够大的场景下收益一般而且训练成本高最后没有作为主模型。2.4 数据划分的隐藏陷阱数据划分是我踩得最重的一个坑单独拿出来说。很多人做 DDI 预测时直接对所有药物对做随机划分训练集、验证集、测试集随机分。这个做法在公开比赛里能刷出漂亮分数但实际部署时会崩。原因在于 DDI 预测的核心应用场景是新药预测——一个新药和一个老药组合或者两个新药组合到底安不安全。随机划分下测试集中的药物在训练集里基本都出现过模型见过大量和该药物相关的其他组合预测新组合时等于开卷考试。真实场景里一个刚合成的新药没有任何历史组合信息模型表现会断崖式下降。正确做法是药物层面划分。把全部药物按分子骨架聚类后分成训练集和测试集保证测试集药物在训练集中基本没有出现。这样训练集和测试集之间几乎没有药物重叠模型的泛化能力才是真实的。我用这种划分方式后AUPR 大概掉了 0.1 左右这才是模型真实水平。3. 模型结构设计从分子表示到相互作用预测3.1 两条主流路线图网络与序列模型我调研了一圈当前主流 DDI 预测模型基本可以归成两条路线基于序列的 Transformer 路线和基于图的 GNN 路线。序列路线直接把药物 SMILES 当作文本序列用 Transformer 编码再做两个向量的交互。优势是能利用大规模的分子预训练模型如 ChemBERTa 的权重迁移学习效果好。劣势是 SMILES 本质只是一个线性化写法括号嵌套表示分支环结构用数字标记模型需要自己学会还原拓扑关系比较吃力。而且 Transformer 推理速度慢在几十万对样本的训练场景下成本不低。图路线把分子还原成图结构用 GCN、GAT 或 GraphSAGE 进行消息传递。模型天然知道哪些原子相连不需要从括号里学拓扑逻辑更契合化学直觉。劣势是图神经网络调试门槛高一点数据规模大时训练也慢但整体可控。3.2 本项目采用的编码-交互结构最终我采用的方案是一个编码-交互两阶段结构整体思路可以用一句话概括两个药物各自编码成向量再做深层次交互最后映射成相互作用概率。第一阶段是单分子编码。用 3 层 GCN 分别编码药物 A 和药物 B 的分子图每层隐藏维度 128激活函数用 ReLU层间加 BatchNorm防止梯度消失。编码结束后用 attention pooling 把图节点特征聚合成一个全局向量。为什么用 attention pooling 而不是 mean pooling因为分子里不是所有原子都对相互作用有贡献注意力池化让模型自己学习哪些原子更关键。实测下来attention pooling 比 mean pooling 在验证集 AUPR 上提升了约 0.03。第二阶段是相互作用模块。两个药物向量输入到双向交叉注意力层cross-attention让 A 的向量去关注 B 的哪些特征与自身发生反应。这个设计的思路来自一个简单类比两个药物是否相互作用取决于我身上的哪些部分正好对上你身上的哪些部分cross-attention 天然就是做这种配对关系建模的。交互后的两个输出向量拼接再过两层全连接网络输出一个 sigmoid 概率。3.3 为什么拼接MLP不够用很多人第一次搭 DDI 模型时会直接复用单分子性质预测的经验编码器出来两个向量拼接然后丢进 MLP 分类。我早期也这么干过验证集 AUPR 大概 0.78后来换了 cross-attention 交互层0.84 左右。差异来源于表达方式。向量拼接相当于把 A 的全局信息、B 的全局信息放在一起然后让 MLP 自己找关系。但 MLP 做的是非线性特征组合不擅长处理某个局部对标某个局部的细粒度匹配。cross-attention 相当于先做了一步对齐让模型显式地知道 A 的哪些维度和 B 的哪些维度在相互作用。这个逻辑对应药物机制是合理的两个分子不是整体和整体相互作用而是局部药效团配体受体之间发生结合。当然交互层也不是越复杂越好。我也试过双线性池化、张量分解层类似 Decagon 的思路效果相近但训练慢了很多。最后从实用角度选了 cross-attention性能和效率平衡最好。3.4 训练配置与正则化细节训练细节决定模型最后能到哪个水平。我给的推荐配置是 Adam 优化器初始学习率 1e-3batch size 32训练最多 60 个 epoch。每 10 个 epoch 学习率衰减 0.5配合早停策略验证集 AUPR 连续 10 个 epoch 不提升就停止。正则化部分除了 GCN 层之间的 BatchNorm我在全连接层后加了 dropout比例 0.3。分子图结构上还加了边 dropout训练时随机裁剪 10% 的化学键目的是增强模型对异构体/构象变化的鲁棒性。这个手段简单但意外有效本质上是给图结构加噪声防止模型过拟合到某些键连接模式。这里特别强调一个容易被忽视的参数——梯度裁剪。图模型在 batch 内分子大小差异很大时梯度范数波动剧烈。我设置了 max_grad_norm5.0训练稳定性明显改善。之前不开裁剪靠调学习率很难同时满足小分子和大分子的收敛需求。4. 训练、评估与踩坑用数据说话4.1 损失函数与采样策略的选择类别不平衡问题在 DDI 预测里绕不开正样本是少数负样本随便抽。最直接的方案是 BCE Loss 加正样本权重。权重设多少我先统计了训练集里正负样本比例然后设 weight 负样本数 / 正样本数大约 4 左右。后来又试了 Focal Loss这是处理难易样本不平衡更好的选择。Focal Loss 的公式就不全文贴了核心思想是对于那些已经预测得很好的样本降低它的损失权重对那些模棱两可的样本加大损失权重。在 DDI 场景下模型经常把大量负样本轻松预测为无害概率 0.2这些样本梯度贡献很小真正需要关注的是那些被预测到 0.5 附近的正样本和伪负样本。我用的 gamma2.0相比加权 BCE 在 AUPR 上提升了约 0.02。采样策略上和损失函数搭配使用。我采用的 mini-batch 采样方式是在每个 batch 内控制正负比例在 1:2 到 1:3而不是简单随机抽样。这样既保证了每轮训练能看到足够多的正样本又不至于让负样本膨胀。4.2 评估指标AUROC之外还要看AUPR这个项目如果只报准确率基本没有任何说服力。数据不平衡场景下准确率会被负样本主导。想象一下正负比 1:5无脑全预测负类准确率也有 83%。所以重点看两个指标AUROC 和 AUPR。AUROC 度量的是模型区分正负样本的能力随机正样本排在随机负样本前面的概率对类别不敏感。AUPR 则更关注正样本的查准率召回率权衡在正样本稀少时它放大了模型对正类预测错误带来的惩罚。对于药物安全风险筛查这种宁愿多判几个也要尽量不漏掉危险组合的场景AUPR 比 AUROC 更有参考价值。我通常在验证集上同时监控两个指标但以 AUPR 作为早停和模型选择的唯一指标。原因就是实践场景里我不会给医生一个排序列表让他们自己挑而是给出一个风险阈值和正样本候选集AUPR 更贴近这种使用方式。4.3 实验设置与效果数据直接给一组我在实验中的参考效果。数据集用 DrugBank TWOSIDES 合并预处理后正样本约 4 万对负样本按 1:4 采样到 16 万对。按药物层级划分后训练集 12 万对验证集 4 万对测试集 4 万对。在测试集药物冷启动划分上的效果模型AUROCAUPRF1指纹 XGBoost0.860.650.58GCN 编码 向量拼接 MLP0.890.730.64GCN 编码 Cross-Attention0.920.810.71 Focal Loss0.920.840.73可以看到从指纹模型到 GCN拼接是相对容易的提升从拼接换成 cross-attention 是对结构交互建模的实质性改进Focal Loss 则进一步压榨了不平衡数据下的上限。这个数字和公开文献里的 SOTA 相当但我要强调一遍这是在冷启动划分下的结果随机划分下 AUPR 可以到 0.92 以上那个数字没有实际部署参考价值。4.4 训练过程中最典型的几个坑这个项目我前前后后跑了十几版踩过的坑记录一下给后来的人省点时间。第一个坑是 SMILES 清洗不一致导致药物身份分裂。最初的数据管线里不同来源的 SMILES 格式不统一同一个药物在标准化后出现两种写法。训练时模型把同一个药当成两个节点导致注意力权重分散、预测不稳定。后来用 canonical SMILES 统一加上 MD5 去重损失直接下降 0.05。第二个坑是标签泄漏。有一版我在特征中加入了药物的已知靶点信息结果验证集 AUPR 冲到 0.96测试集也漂亮。但细查发现这些靶点信息很多是从后续实验数据整理出来的对上测试集药物时等于提前泄露了答案。最终我放弃了把外部靶点数据库信息作为特征的做法只用分子图自带的原子/键属性。第三个坑是负样本采样偏差。早期完全随机采样模型学会了分子骨架差异大就倾向判 DDI看起来测试集分数还行但抽样分析发现它对结构相似但确实有相互作用的药物对如一些 CYP 抑制组合几乎全部漏检。改用药物频次匹配采样后这个问题显著缓解。第四个坑是数据的弱标注问题。TWOSIDES 里的相互作用很多来自统计关联有些实际上是某个药物单独的不良反应被误归到组合里。负样本同理。这个问题的工程解法是尽量保留置信度高的正样本用多数据集投票筛选负样本则不追求精确随机抽但保持样本量大靠模型去抗噪。5. 从模型到落地可解释性与扩展思路5.1 为什么可解释性在这个项目里不是可选项药物相互作用预测最终服务的对象是临床药师、药物研发人员和监管审查人员。这些人不会因为模型说概率 0.87就采纳建议他们需要看到依据模型是根据哪部分化学结构做的判断这和我了解的药理机制是否吻合缺乏可解释性的模型哪怕指标再高也很难在真实决策链里落地。这个项目里我用两套解释工具。第一套是图注意力权重可视化。因为模型有两层 cross-attention每层都能拿到 A 对 B 的注意力矩阵。把注意力权重映射回分子图上的原子就能看出两个药之间哪些部位在互动。实操中用 networkx 和 RDKit 的Draw模块把原子按注意力权重着色能直观看到热点区域。第二套是 GNNExplainer用来识别重要子图。它通过扰动输入边来找出对模型预测影响最大的原子集合。这个方法比注意力权重更严格因为 attention 反映的是内部计算权重GNNExplainer 直接模拟如果这个部分不存在预测结果会怎样变化。5.2 案例验证让模型自己说出预测依据我做了几个已知的 DDI 案例来验证可解释性的可信度。最典型的是华法林和阿司匹林联用两者都影响凝血功能联合使用有明确出血风险。模型预测相互作用概率 0.91注意力可视化显示华法林侧的注意力集中在 4-羟基香豆素环附近的羰基和甲基阿司匹林侧集中在乙酰氧基结构附近。对照文献这个结果是有机制的华法林通过抑制维生素 K 环氧化物还原酶发挥作用阿司匹林通过不可逆抑制 COX-1 减少血小板 TXA2 合成两药都作用于凝血级联乙酰氧基恰恰是阿司匹林发挥不可逆抑制的关键基团。模型抓住这些局部结构说明它的学习逻辑和药理机制存在相关性并不只是统计巧合。再一个例子是两类 CYP 抑制剂和底物的组合。模型对 CYP3A4 抑制剂酮康唑和 CYP3A4 底物咪达唑仑预测风险很高注意力集中在酮康唑的氮杂环也就是嘧啶酮结构和咪达唑仑的代谢位点附近。这类验证做了十多个案例大部分能和已知机制对上这给了我把模型输出放进决策流程的最大信心。5.3 后续能做的扩展方向这个项目的框架可以很自然地向多个方向延伸。最直接的是把二分类扩展到多分类即不仅要预测会不会相互作用还要预测属于哪类机制比如酶抑制、酶诱导、转运体竞争、药效学拮抗。只需要把输出层的 sigmoid 换成 softmax损失换成交叉熵再加上机制标签就能实现数据可以用 DDI Corpus 里的句子级标注来补充。另一个方向是引入多模态信息。目前只用了药物分子结构但实际临床中相互作用还受剂量、给药时间、患者基因型、肝肾功能影响。把分子图特征和患者临床特征年龄、肌酐清除率、CYP2C9 基因型等拼接可以让模型做个性化风险预测这是真正贴合临床决策的应用形态。还有个比较前沿的思路是利用大语言模型做生成式解释。模型预测完成后把分子结构、注意力可视化结果、相关通路信息交给 LLM让它生成一段人可读的风险报告比如该组合可能抑制 CYP3A4 代谢通路导致底物药血药浓度升高建议监测或调整剂量。这个方向我做了一半效果已经可以用但还需要在解释准确性和幻觉控制上再打磨。最后说几句实在话。这个项目做下来我最大的收获不是学会了几种模型结构而是深刻体会到在计算药物发现这类任务里数据管线和评估设计的分量远大于模型结构本身。模型从 GCN 换到 Transformer 容易但把负样本采样逻辑捋清楚、把冷启动评估做扎实才是真正决定项目能不能在实际场景里活下来的关键。如果你也在做类似方向我的建议是不要一开始就在结构上追新先把数据标准、划分策略、评估指标这三件事想透模型最后的结果一定不会差。本文还有配套的精品资源点击获取