第4章 数据准备:分子描述符计算、标准化、数据集划分
好了,前面我们聊了SHAP和ADMET的基本概念,现在要动真格的了。数据准备——这步你做不好,后面模型再花哨也是白搭。我见过太多项目,数据处理的坑比算法本身的坑多得多。
4.1 分子描述符计算:把分子结构变成数字
分子结构是抽象的,但模型只认数字。所以第一步,把分子结构转化为数值特征——分子描述符。说白了,就是把每个分子的形状、极性、电荷分布等等信息,用一组数字表达出来。
举个最简单的例子,用 RDKit 计算分子的摩根指纹(Morgan Fingerprints):
from rdkit import Chem
from rdkit.Chem import AllChem
smiles = "CCO" # 乙醇
mol = Chem.MolFromSmiles(smiles)
fp = AllChem.GetMorganFingerprintAsBitVect(mol, radius=2, nBits=2048)
print(fp.ToList()[:20]) # 输出前20位
常用的描述符种类很多,我整理了一张速查表:
| 描述符类别 | 举例 | 维度 | 说明 |
|---|---|---|---|
| 2D 描述符 | 分子量、LogP、TPSA、HBD、HBA、RotBonds | ~200 种 | 直接计算,速度快 |
| 3D 描述符 | 分子体积、溶剂可及表面积、偶极矩 | ~50 种 | 需要构象优化,计算慢但更准确 |
| 指纹(Fingerprint) | 摩根指纹、MACCS 指纹、拓扑指纹 | 2048 / 166 / 1024 | 稀疏高维,适合树模型和神经网络 |
| 物理化学性质 | pKa、溶解度、logD | ~20 种 | 通常用经验公式或第三方工具估算 |
4.2 标准化:消除量纲差异
描述符的量纲差异很大。比如分子量动辄几百,而 LogP 一般只有个位数。如果不做标准化,模型中权重大的特征会严重偏向大数值的描述符。你想想看,模型会以为分子量是决定 ADMET 性质的关键——其实很可能只是因为它数值大。
常用的标准化方法有两种:
- Z-score 标准化: 减去均值,除以标准差。适合数据近似正态分布的情况。
- Min-Max 缩放: 缩放到 [0,1] 区间。适合有边界的描述符(如指纹位点 0/1)。
我用 scikit-learn 实现标准化:
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 假设 X 是 n_samples x n_features 的矩阵
scaler = StandardScaler() # 或者 MinMaxScaler()
X_scaled = scaler.fit_transform(X)
我踩过这个坑。有一次我偷懒,直接对整个数据集做了标准化再划分——结果训练集和测试集的数据“混在一起”了,模型在测试集上的 AUC 高达 0.98,但上线后只有 0.65。嗯,从那以后,我每次都会把标准化器先 fit 训练集,再 transform 验证和测试集。
4.3 数据集划分:训练集、验证集、测试集
数据准备好了,接下来要分成三份:
- 训练集(Train): 模型从这里学习模式,占比通常 60%–80%。
- 验证集(Validation): 用于调参、选择模型,不参与最终评估。占比 10%–20%。
- 测试集(Test): 模型做完所有调整后,最后一次评估。占比 10%–20%。
注意:验证集和测试集的作用完全不同。验证集是在模型开发过程中帮你选超参数、选特征的;测试集则是模拟真实场景,用于评估最终模型的泛化能力。千万不要用测试集来调参,否则你得到的性能就是“作弊”的。
划分方法我一般用分层随机抽样,尤其是 ADMET 数据经常有类别不平衡问题。举个例子,如果只有 5% 的分子是有毒的,那划分时保持每份中毒性分子的比例都接近 5%。
from sklearn.model_selection import train_test_split
X_train, X_temp, y_train, y_temp = train_test_split(
X_scaled, y, test_size=0.3, random_state=42, stratify=y)
X_val, X_test, y_val, y_test = train_test_split(
X_temp, y_temp, test_size=0.5, random_state=42, stratify=y_temp)
这里的 stratify=y 保证了分层。验证集和测试集各占原始数据的 15%(因为 temp 是 30%,再 split 一半正好 15%)。
4.4 数据准备流程图
整个流程我用一张图串起来,大家看完应该心里有数了。
- 描述符计算:优先选择与任务相关的 50-100 个 2D 描述符 + 指纹。
- 标准化:fit 训练集,transform 验证/测试集——这个顺序绝对不能错。
- 划分:分层抽样,验证集用于调参,测试集只评估一次。
数据准备阶段就这些内容。别看步骤简单,每一步都有讲究。我当年刚开始做 ADMET 预测时,数据准备花了整整两周时间,但后来模型上线后的稳定性比团队里其他人高出一截。说白了,后面那些花哨的 SHAP 分析、模型调优,都建立在干净的数据之上。数据不干净,一切免谈。