2. 分子描述符基础:从结构到数字
大家好,欢迎来到第2章。这一章我们聊聊分子描述符,说白了,就是把化学结构变成计算机能理解的数字。这是我做ADMET预测的第一步,也是最关键的一步。模型的精度,很多时候就取决于你选的描述符对不对。
核心观点:分子描述符是化学结构的数学映射。 没有这一步,机器学习无从谈起。
我曾经在项目里被电子表格坑过——100多个分子,手动算描述符,结果漏了几列数据,模型直接崩了。后来我才明白,理解描述符的本质比动手敲代码更重要。
2.1 什么是分子描述符
分子描述符,你可以把它想象成一个分子的「身份证号码」。但它不是一串无意义的数字,而是有物理或化学含义的数值。比如分子量、辛醇-水分配系数(logP)、极性表面积……每个数字都对应着分子在某方面的特征。
举个例子,假设你有个分子C₆H₁₂O₆(葡萄糖)。它的分子量大约是180.16 g/mol。这串数就告诉模型:这个分子不轻,可能在肠道吸收上有点费劲。
我习惯把描述符分为三个层次:
- 零维(0D):原子数、分子式、分子量。最粗暴,但也最常用。
- 一维(1D):结构片段,比如官能团计数、键的类型。
- 二维(2D):拓扑特征,比如路径长度、分支度。这类最常见。
- 三维(3D):几何特征,比如表面积、体积、手性。计算量大,但有时效果更好。
- 四维(4D):构象集合的特征。我很少用,因为太吃计算资源。
| 维度 | 例子 | 计算难度 | 信息量 |
|---|---|---|---|
| 0D | 分子量、原子数 | 极低 | 少 |
| 1D | 官能团计数 | 低 | 中 |
| 2D | 拓扑极性表面积(TPSA) | 中等 | 高 |
| 3D | 分子体积、溶剂可及表面积 | 高 | 非常高 |
| 4D | 构象系综平均性质 | 极高 | 最丰富 |
我的建议: 刚开始做ADMET预测,先用2D描述符。它们计算快,效果已经够用。等模型调优到瓶颈了,再考虑加3D特征。
2.2 分类:拓扑、几何、电性及其他
描述符按物理意义分,主要有以下几类。我个人习惯按计算代价排序:
- 组成描述符(Constitutional):原子个数、键数、环数、分子量。计算几乎不花时间。
- 拓扑描述符(Topological):基于图论。比如分子连接性指数(Chi指数)、基尔霍夫指数。这类描述符能捕捉分子的分支、环化程度。
- 几何描述符(Geometric):基于3D结构。比如分子体积、投影面积、回转半径。
- 电性描述符(Electronic):电荷分布、偶极矩、HOMO/LUMO能级。反映分子与靶点的相互作用潜力。
- 量子化学描述符(Quantum Chemical):用DFT或半经验方法算。计算量巨大,但物理意义清晰。
为什么分类这么重要?因为不同ADMET性质需要不同的描述符。比如预测水溶性,几何和电性描述符很关键;预测血脑屏障穿透,拓扑和极性描述符更管用。
避坑指南: 我曾经一股脑儿把几百个描述符全扔进模型,结果过拟合到怀疑人生。后来学乖了——先按物化直觉筛选,再用量化方法(比如相关系数、互信息)砍到50个以内。记住,描述符不是越多越好。
2.3 常见描述符类型介绍
接下来是我最常用的几种描述符,每个我都踩过坑。你想想看,不懂这些就直接跑模型,基本等于闭眼开车。
2.3.1 分子量(MW)
最基础、也最容易被忽略。我第一个ADMET项目就吃了它的亏——忘了对分子量做标准化,导致logP预测全偏。记住,分子量超过500的分子,口服吸收概率断崖式下降(所谓的“利平斯基五规则”第一条)。
2.3.2 辛醇-水分配系数(logP)
衡量分子亲脂性的金标准。logP高,分子容易穿透细胞膜,但水溶性差。我习惯用实验测的logP做基准,算出来的作为补充特征。为什么?因为不同计算方法结果差0.5个单位很正常。
2.3.3 氢键供体/受体计数(HBD/HBA)
利平斯基规则里要求HBD≤5且HBA≤10。我遇到过一个候选分子,HBA=11,结果体外实验吸收率不到5%。后来改结构砍掉一个氢键受体,吸收率提升到30%。有时候一个数就能决定生死。
2.3.4 可旋转键数(RotB)
反映分子的柔性。RotB越多,分子骨架越灵活,但肠道渗透性通常越差。我记得有个项目,RoTB从8降到4,小鼠口服生物利用度直接翻倍。
2.3.5 拓扑极性表面积(TPSA)
这是我最喜欢的2D描述符之一。它估算分子中极性原子暴露在表面的面积,单位是Ų。TPSA<140通常意味着口服吸收可行;<60穿透血脑屏障没问题。
一个实用的经验公式: TPSA ≈ (HBD×35) + (HBA×25) + 电荷项。我自己在代码里用过这个近似,效果出奇好。
2.3.6 分子连接性指数(Chi指数)
这类拓扑描述符抽象但强大。Chi指数能捕捉分子的分支程度和环结构。我曾在预测血浆蛋白结合率时,发现Chi指数比分子量相关性高出30%。但初学者容易忽略它——因为它不够直观。
2.3.7 电荷衍生描述符
比如部分电荷(Qtot)、最大正电荷(Qpos)、最小负电荷(Qneg)。这些我用在预测毒性时特别多。毒性机制往往与电荷分布异常有关。
| 描述符 | 含义 | 常用界限 | 最适用ADMET |
|---|---|---|---|
| MW | 分子量 | <500 | 吸收 |
| logP | 脂溶性 | 1-3(最佳) | 吸收、代谢 |
| HBD | 氢键供体 | ≤5 | 吸收、血脑屏障 |
| HBA | 氢键受体 | ≤10 | 吸收、血脑屏障 |
| RotB | 可旋转键 | ≤10 | 吸收、生物利用度 |
| TPSA | 拓扑极性表面积 | <140 (口服),<60 (CNS) | 吸收、血脑屏障 |
| Chi | 分子连接性 | 视体系而定 | 代谢、毒性 |
一个小技巧: 用Python RDKit计算这些描述符时,我发现部分库版本会返回不同单位。比如logP有时默认是mlogP,有时是AlogP。请始终在代码里显式指定计算方法。
2.4 动手算一算:用代码确认理解
光说不练假把式。我们来跑一个简单的Python片段,用RDKit算上面提到的几个描述符。这是我每个新项目的开工仪式。
from rdkit import Chem
from rdkit.Chem import Descriptors
smiles = "CC(=O)OC1=CC=CC=C1C(=O)O" # 阿司匹林
mol = Chem.MolFromSmiles(smiles)
mw = Descriptors.MolWt(mol)
logp = Descriptors.MolLogP(mol)
hbd = Descriptors.NumHDonors(mol)
hba = Descriptors.NumHAcceptors(mol)
rotb = Descriptors.NumRotatableBonds(mol)
tpsa = Descriptors.TPSA(mol)
print(f"MW: {mw:.2f}")
print(f"logP: {logp:.2f}")
print(f"HBD: {hbd}")
print(f"HBA: {hba}")
print(f"RotB: {rotb}")
print(f"TPSA: {tpsa:.2f}")
跑完这段代码,你应该能看到阿司匹林的这些数字。嗯,很标准——MW=180.16, logP≈1.19, HBD=1, HBA=3, RotB=3, TPSA≈63.6。这些数字告诉我:这分子口服没问题,但不能穿透血脑屏障(TPSA>60)。
警告: 别直接用SMILES字符串的长度或字符数当描述符。我曾经见过有人把"CC(=O)O"当特征扔进网络,结果模型学到的是字符串长度和毒性负相关——完全不科学。
2.5 选择描述符的三大原则
最后,我分享三条我踩了无数坑之后总结的原则:
- 可解释性优先:能用logP、TPSA这样的物化描述符,就别用纯统计描述符。模型出问题了你才知道怎么修。
- 计算成本敏感:1000个分子用3D描述符没问题,但100万个分子千万别加3D。我吃过计算一个周末结果崩掉的亏。
- 量纲统一:分子量、logP、TPSA的单位和数值范围差异巨大。做模型前一定要做标准化或归一化。否则神经网络第一层就把数值大的特征放大了。