219

Molfeat:分子特征工程工具箱

Molfeat 统一了指纹、描述符、预训练表征等多种分子特征化方法,让特征工程一站式完成。这篇给出统一 API 用法与特征选型建议。

Molfeat 是 Valence Labs 开发的分子特征化工具箱。它解决的问题是:分子特征方法有几十种——指纹、描述符、图表示、预训练模型嵌入——每种的调用方式都不一样,做特征对比实验时要写一堆适配代码。Molfeat 把它们统一到同一个接口下。

安装

pip install molfeat
# 预训练模型需额外依赖
pip install molfeat[transformer]     # 语言模型类
pip install molfeat[dgl]             # 图预训练模型

统一 API

from molfeat.trans import MoleculeTransformer
from molfeat.trans.pretrained import PretrainedDGLTransformer

smiles = ["CC(=O)Oc1ccccc1C(=O)O", "CN1C=NC2=C1C(=O)N(C)C(=O)N2C"]

# 指纹
fp = MoleculeTransformer(featurizer="ecfp", dtype=float)
X1 = fp(smiles)                    # (2, 2048)

# 物理化学描述符
desc = MoleculeTransformer(featurizer="desc2D")
X2 = desc(smiles)

# 预训练模型嵌入 —— 换一行就换一种表示
gin = PretrainedDGLTransformer(kind="gin_supervised_contextpred", dtype=float)
X3 = gin(smiles)

print(X1.shape, X2.shape, X3.shape)

关键在于切换特征只需改一个字符串。做「哪种表示对我的任务最好」这类实验时,代码量从几百行降到几行。

可用的特征类型

类别 代表 特点
子结构指纹 ecfp、fcfp、maccs、atompair、topological 快、可解释、小数据友好
物化描述符 desc2D、desc3D、mordred 可解释性最好,维度低
药效团 pharm2D、pharm3D 关注相互作用特征
形状 / 3D usrcat、electroshape 构象敏感任务
预训练图模型 gin_supervised_*、pcqm4mv2_graphormer 大数据下更强
语言模型 ChemBERTa、ChemGPT、MolT5 SMILES 序列表示
from molfeat.store.modelstore import ModelStore
store = ModelStore()
for m in store.available_models[:20]:
    print(m.name, "|", m.group)      # 浏览全部可用特征器

接进 scikit-learn 管线

from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestRegressor
from sklearn.model_selection import cross_val_score

for feat in ["ecfp", "fcfp", "maccs", "desc2D"]:
    pipe = Pipeline([
        ("feat", MoleculeTransformer(featurizer=feat, dtype=float, n_jobs=-1)),
        ("model", RandomForestRegressor(n_estimators=300, random_state=0)),
    ])
    s = cross_val_score(pipe, smiles_all, y, cv=5, scoring="neg_root_mean_squared_error")
    print(f"{feat:10s} RMSE = {-s.mean():.3f} ± {s.std():.3f}")

它实现了 sklearn 的 transformer 接口,可以直接放进 Pipeline,用交叉验证公平比较不同特征——这正是它设计的目标场景。

缓存:处理大库时的关键

from molfeat.utils.cache import FileCache

cache = FileCache(cache_file="feats.parquet", name="ecfp")
fp = MoleculeTransformer(featurizer="ecfp", dtype=float)
fp.set_cache(cache)
X = fp(smiles_all)        # 第二次调用直接命中缓存

预训练模型特征化很慢,缓存能省下大量重复计算,尤其是在反复调参的实验中。

特征选型的实际建议

  • 先跑 ECFP4 基线:几百到几千个分子的任务上,ECFP + 随机森林/梯度提升常常打平甚至打败复杂表示,而且快得多、可解释。
  • 数据量决定上限:预训练嵌入的优势通常要在数据量较大或任务与预训练分布接近时才显现。小数据上盲目用大模型嵌入,往往还不如指纹。
  • 拼接常常有效:指纹 + 物化描述符拼起来,比单用任一种更稳,成本也低。
  • 可解释性别忘了:要向药化同事解释「为什么模型这么预测」时,描述符和子结构指纹远比嵌入向量有用。
  • 公平比较的前提:所有特征都要在同一套骨架划分和同样的多种子设置下比,否则结论不可信。

上手提示

  • 换一个字符串就换一种分子表示,是做特征对比实验的最佳工具;
  • 实现了 sklearn transformer 接口,可直接进 Pipeline 做交叉验证;
  • 预训练特征务必开缓存,否则反复实验时间全耗在特征化上;
  • 先跑 ECFP4 基线,小数据上它常常不输给大模型嵌入。

延伸资源