3. 分子描述符基础概念归纳总结
做 ADMET 预测这些年,我最大的体会是:描述符选不对,后面全白费。你想想看,模型再漂亮,喂进去的特征本身就有问题,那预测结果能靠谱吗?这一章我们就来系统梳理一下分子描述符的核心概念,把基础打扎实。
3.1 什么是分子描述符
说白了,分子描述符就是把化学结构翻译成计算机能理解的数字。我习惯这么定义它:描述符是分子在某个维度上的数学指纹。它可以是单个数值(比如分子量),也可以是一组向量(比如指纹位点)。
为什么需要这层翻译?因为 ADMET 性质本质上是由分子的微观特征决定的。脂溶性看 LogP,透膜性看 TPSA,代谢稳定性看可旋转键数……没有描述符,你就没法构建结构与性质之间的定量关系。
3.2 描述符的分类体系
描述符的分类方式很多,我个人最常用的是按维度和按类型两种切法。下面这张图是我自己整理的知识框架,涵盖了 ADMET 建模中最核心的描述符类别。
3.3 四大描述符类别深度拆解
3.3.1 2D 描述符——最稳定的「基本功」
2D 描述符只依赖分子拓扑结构,不涉及三维构象。这意味着它计算快、可重复性极高。我在项目中遇到过好几次,同样是计算 LogP,不同工具给出的结果能差 0.5 以上。但 2D 描述符的算法一旦固定,结果就是确定的。
ADMET 建模中最常用的 2D 描述符包括:
| 描述符 | 缩写 | ADMET 关联性 | 典型阈值(类药) |
|---|---|---|---|
| 分子量 | MW | 透膜性、溶解度 | < 500 Da |
| 脂水分配系数 | LogP | 吸收、代谢、毒性 | 0 ~ 3 |
| 氢键供体/受体 | HBD / HBA | 透膜性、外排 | HBD ≤ 5, HBA ≤ 10 |
| 拓扑极性表面积 | TPSA | 肠道吸收、血脑屏障 | < 140 Ų |
| 可旋转键数 | RotB | 口服生物利用度 | ≤ 10 |
3.3.2 3D 描述符——构象依赖的「双刃剑」
3D 描述符能捕捉分子在真实空间中的立体特征。举个例子,分子体积和分子表面积对预测组织分布非常有帮助。但问题在于——构象是柔性的。同一个分子,用不同的力场优化,或者用不同的最低能量构象,算出来的 3D 描述符可能差很多。
我个人的建议是:除非你的模型明确需要立体信息(比如 CYP450 对接打分),否则优先用 2D 描述符做基线模型。3D 描述符留到模型调优阶段再引入。
3.3.3 理化性质——直接对应实验值的「硬指标」
这部分描述符本身就是 ADMET 性质的一部分。LogS(水溶性)、pKa、熔沸点,这些参数可以直接通过实验测定,也可以预测。在校验场景下,我习惯拿实测值与计算值做对比,如果偏差超过 0.3 log 单位,我会优先检查输入结构而非模型本身。
3.3.4 指纹描述符——高维空间的「特征引擎」
指纹描述符把分子变成固定长度的二进制或计数向量。MACCS 166 位、Morgan 指纹(ECFP)是最常用的两种。它们的优势是编码了局部子结构信息,适合做多样性筛选和相似性搜索。
但要注意:指纹位点的含义是不直观的。你不能像解释 LogP 那样说「这个位点代表什么」。所以在我自己的项目中,指纹通常作为辅助特征,不会单独用它做关键决策。
3.4 计算工具与一致性校验
市面上主流的描述符计算工具有不少:
- RDKit:开源、社区活跃、覆盖最全,我 90% 的项目都用它
- OpenBabel:格式转换强,描述符计算相对基础
- Mordred:基于 RDKit 的扩展库,能算 1800+ 描述符
- PaDEL-Descriptor:Java 实现,支持 1800+ 描述符
- 商业软件(MOE、Discovery Studio):精度高,但成本也高
我用 RDKit 举个例子,计算一组核心描述符的代码非常简洁:
from rdkit import Chem
from rdkit.Chem import Descriptors, Lipinski
mol = Chem.MolFromSmiles('CC(=O)OC1=CC=CC=C1C(=O)O')
mw = Descriptors.ExactMolWt(mol)
logp = Descriptors.MolLogP(mol)
hbd = Lipinski.NumHDonors(mol)
hba = Lipinski.NumHAcceptors(mol)
tpsa = Descriptors.TPSA(mol)
rotb = Lipinski.NumRotatableBonds(mol)
print(f'MW: {mw:.2f}')
print(f'LogP: {logp:.2f}')
print(f'HBD: {hbd}, HBA: {hba}')
print(f'TPSA: {tpsa:.2f} Ų')
print(f'RotB: {rotb}')
输出结果:
MW: 180.16
LogP: 1.31
HBD: 1, HBA: 3
TPSA: 63.60 Ų
RotB: 3
3.5 一致性校验的「三道关」
在实际项目中,我总结了三道必须过的校验关卡:
- 工具内一致性:同一版本的工具,对同一个分子计算 3 次,结果是否完全一致?RDKit 是确定的,但有些工具会引入随机种子。
- 跨工具一致性:RDKit 算的 LogP 和 PaDEL 算的 LogP,偏差在可接受范围内吗?我通常设容忍阈值为 0.2 log 单位。
- 版本间一致性:从 RDKit 2020.03 升级到 2023.09,描述符数值有没有漂移?尤其是 TPSA 和指纹位点定义。
3.6 选描述符的「最少够用原则」
说了这么多,你可能想问:那我到底该用哪些描述符?
我个人的实践是:从 2D 核心集出发,按需扩展。具体来说:
- 第一层(必选):MW、LogP、HBD、HBA、TPSA、RotB —— 覆盖 Lipinski 五规则,也是大多数 ADMET 模型的基础特征
- 第二层(按任务选):LogS(溶解度任务必加)、pKa(离子化相关任务)、芳香环数(平面性相关)
- 第三层(模型调优用):3D 描述符、指纹描述符、Mordred 扩展描述符
为什么要这样分层?我见过太多新手一股脑算出 1000 多个描述符,然后扔进模型做特征选择。最后模型精度没提高多少,可解释性却一塌糊涂。少即是多,在描述符选择上尤其成立。