第3章:ADMET预测简介——属性、方法与评估指标

3.1 ADMET属性:药物成败的生命线

说到ADMET,我早期做计算化学那会儿,常常把它当成一个「选做题」。总觉得只要药效好,其它的都好说。后来吃过亏,才知道这想法有多天真。

它到底指什么?

说白了,ADMET是个缩略语,每个字母都代表一个关键环节:

  • A (吸收) — 药物能不能顺利进入人体循环系统?
  • D (分布) — 药物到了血液里,能不能去到该去的地方?
  • M (代谢) — 药物会不会被肝脏「代谢掉」,导致还没干活就失效了?
  • E (排泄) — 药物最后怎么离开人体?会不会在体内积聚?
  • T (毒性) — 药物有没有副作用?会不会致癌或者伤肝?

我在项目中遇到过很多化合物,体外活性好得不得了,结果一测Ames(一种致癌性测试),阳性。直接团灭。所以,ADMET不是锦上添花,是生死攸关。

关键提醒: 药效和安全性同样重要。一个「高效但有毒」的分子,几乎不可能成药。
属性 典型实验指标 机器学习预测目标
吸收 Caco-2 渗透性、人肠道吸收 (HIA) 分类(高/低渗透性)或回归(渗透率值)
分布 血浆蛋白结合率 (PPB)、表观分布容积 (Vd) 回归(PPB%)
代谢 CYP450酶抑制、半衰期 (T½) 分类(是否抑制剂)或回归(T½)
排泄 肾清除率、胆汁排泄率 回归(清除率)
毒性 hERG 抑制、Ames 试验、肝毒性 分类(有毒/无毒)

你想想看,这些属性不是孤立的。比如,如果化合物血浆蛋白结合率特别高,那它的自由药物浓度就低,药效就会打折扣。所以,我们做预测时,要尽可能多地考虑这些属性。

3.2 机器学习预测常用方法

好了,属性我们认识了。那怎么用机器学习的办法去预测它们呢?

我个人习惯把方法分成三路:

  1. 经典机器学习模型:随机森林(RF)、支持向量机(SVM)、XGBoost。
  2. 深度学习方法:图神经网络(GNN)、卷积神经网络(CNN)处理分子图像。
  3. 基于物理的方法:分子动力学模拟、自由能微扰。但计算量大,不适合高通量筛选。

这里,我重点讲一下经典机器学习模型。为什么?因为它们在很多ADMET预测任务上,表现甚至比深度学习还好,而且解释性强。

注意: 不要盲目追求复杂模型。对一个只有几千个样本的数据集,一个调好参的随机森林可能比GNN更实用。

拿一个预测水溶性的例子来说,我们通常需要将分子结构转化为数值特征,即「分子描述符」。常用的描述符有:

  • 分子量 (MW)
  • 脂水分配系数 (logP)
  • 氢键供体/受体计数
  • 拓扑极性表面积 (TPSA)

然后把这些特征喂给模型。我早期用RDKit算描述符,再用Scikit-learn的随机森林去做回归预测。效果不错。

一个简单的流程示例:

# 假设你已经有一个分子列表 molecules
from rdkit import Chem
from rdkit.Chem import Descriptors
import numpy as np

def compute_descriptors(mols):
    descs = []
    for mol in mols:
        # 计算几个基础描述符
        mw = Descriptors.MolWt(mol)
        logp = Descriptors.MolLogP(mol)
        tpsa = Descriptors.TPSA(mol)
        hbd = Descriptors.NumHDonors(mol)
        hba = Descriptors.NumHAcceptors(mol)
        descs.append([mw, logp, tpsa, hbd, hba])
    return np.array(descs)

# 然后喂给随机森林模型
# X = compute_descriptors(molecules)
# y = solubility_values
# from sklearn.ensemble import RandomForestRegressor
# model = RandomForestRegressor()
# model.fit(X, y)

这其实只是最基础的用法。真正的挑战在于,如何挑选出最有预测能力的描述符?如何避免过拟合?我在项目中踩过很多坑。

经验之谈: 我曾经用了一个包含200多个描述符的集合去训练模型,结果在测试集上表现极差。后来通过特征重要性分析,发现只有10个描述符真正有用。所以,特征选择是重中之重。

3.3 评估指标:怎么判断模型好坏?

模型训练完了,怎么判断它行不行?不能光看训练集上的性能。我们必须有一套客观的评估指标。

对于ADMET预测,我一般分成两类任务来看:

3.3.1 分类任务(比如预测是否致癌)

常用的指标有:

  • 准确率:预测正确的比例。但类别不平衡时失效。
  • 精确率:预测为阳性的样本中,真实阳性的比例。
  • 召回率:真实阳性的样本中,被正确预测的比例。
  • F1分数:精确率和召回率的调和平均。
  • AUC-ROC:曲线下面积,衡量模型排序能力。

举个例子,在预测hERG(心脏毒性)时,我们更关注「召回率」。宁可错判十个无毒的药,也不能漏掉一个有毒的。因为漏掉一个有毒的,可能就导致临床试验出人命。

指标 含义 适用场景
准确率 整体预测正确的比例 类别大致平衡时
精确率 预测为阳性的有多少是真的 对假阳性容忍度低(比如资源有限)
召回率 真实阳性有多少被找出来了 对假阴性容忍度低(比如安全筛选)
F1分数 精确率和召回率的平衡 需要两者兼顾时
AUC-ROC 模型对不同类别区分能力的总体度量 通用、不受阈值影响

3.3.2 回归任务(比如预测logD)

回归指标相对简单:

  • 均方根误差 (RMSE):预测值与真实值误差的平方根。值越小越好。
  • 平均绝对误差 (MAE):预测值与真实值误差的绝对值平均。更直观。
  • 决定系数 (R²):模型解释了总方差的比例。越接近1越好。

我自己做回归项目时,喜欢同时看RMSE和R²。RMSE告诉你误差有多大,R²告诉你模型对数据的解释力强不强。举个例子,如果R²只有0.3,说明你的模型几乎白做了,还不如直接用平均值代替。

# 回归指标计算示例
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
import numpy as np

y_true = [0.5, 1.2, 2.8, 3.1]
y_pred = [0.4, 1.1, 2.9, 3.2]

rmse = np.sqrt(mean_squared_error(y_true, y_pred))
mae = mean_absolute_error(y_true, y_pred)
r2 = r2_score(y_true, y_pred)

print(f"RMSE: {rmse}")
print(f"MAE: {mae}")  
print(f"R²: {r2}")
避坑指南: 千万不要在训练集上评估模型性能。一定要留出独立的测试集,或者使用交叉验证。我见过太多人对着训练集上的高R²兴奋,结果测试集上一塌糊涂。

评估模型,不是只看一个指标。我通常在分类任务上看AUC和F1,在回归任务上看RMSE和R²。然后结合领域知识,判定模型是否可用。

ADMET预测工作流 分子输入 SMILES / SDF / 分子图 特征工程 描述符(分子量/logP) 指纹 / 图特征 模型构建 RF / XGB / GNN 训练集/验证集划分 预测输出 吸收/分布/代谢/排泄/毒性 评估指标 分类:AUC / F1 / 召回率 回归:RMSE / MAE / R² 外部测试集 / 交叉验证 领域专家审核 SHAP可解释性分析 全局特征重要性 单分子预测解释 迭代优化 根据SHAP结果筛选分子 反馈至特征工程

这张图概括了ADMET预测的完整工作流,从分子输入到最终评估与优化。其中SHAP可解释性分析是后面章节的重点,这里先埋个伏笔。

好,关于ADMET预测的基础知识,我们就讲到这儿。记住,模型只是工具,领域知识才是灵魂。不要迷信指标,要多想想背后的化学和生物学意义。这是我在多年项目中最大的感悟。