045

QSPR 入门:从分子结构预测理化性质

QSPR 从结构预测理化性质,与 QSAR 有重要差异。这篇讲清这些差异与各性质的建模要点。

QSPR(定量构性关系)预测的是理化性质(溶解度、logP、熔点、渗透性),而非生物活性。它与 QSAR 的技术流程相似,但有几个关键差异,影响建模策略。

QSPR 与 QSAR 的关键差异

QSPR(理化性质) QSAR(生物活性)
物理基础 有明确的物理原理 依赖具体的靶点结合
数据量 通常更多,跨化学空间 受限于某个靶点的数据
泛化能力 更好——物理规律普适 差——换靶点就失效
实验一致性 较好(标准方法) 较差(体系差异大)
活性悬崖 ——性质变化连续 常见
描述符的作用 很大——直接相关 较小
可用的通用模型 (如 logP 的计算方法)

最重要的差异:QSPR 有明确的物理基础。logP 主要由分子的极性表面积与疏水表面积决定;溶解度与晶格能和溶剂化能相关——这让物化描述符成为极其有效的特征,也让模型的泛化能力更好。

主要性质与建模要点

# ---- logP / logD ----
#   【已有成熟的计算方法】:
#     Crippen(RDKit 内置)、XLogP、ALogP
#   → 【建模前先用现成方法作为基线】
#   → 机器学习的增量常常有限
#
#   【注意 logP vs logD】:
#     logP: 中性形式的分配系数
#     logD: 【特定 pH 下】的表观分配系数(考虑电离)
#     → 【生理相关的是 logD7.4】
#     → 对可电离化合物,两者可能相差几个数量级
#
# ---- 溶解度 ----
#   【区分两种】:
#     动力学溶解度:从 DMSO 储液稀释 → 常用于筛选
#     热力学溶解度:固体与溶液平衡 → 更相关但更慢
#     → 【两者可能相差几十倍,不能混用】(见 156)
#
#   【影响因素】:
#     - 亲脂性(logP 越高越难溶)
#     - 【晶格能】(熔点高的难溶)
#     - 分子的极性与氢键能力
#     → 【经典的 GSE 方程】:
#       logS = 0.5 - 0.01(MP - 25) - logP
#       → 需要熔点,而熔点本身很难预测
#
# ---- 熔点 ----
#   【非常难预测】
#   原因:取决于晶体堆积,而这是三维的、
#         对分子的细微差异极其敏感
#   → 【模型精度普遍不高,不要期望太多】
#
# ---- pKa ----
#   【对成药性影响很大】:
#     决定电离状态 → 影响溶解度、通透性、结合
#   【建模思路】:
#     按可电离基团的类型分别建模
#     (羧酸、脂肪胺、芳香胺、酚...)
#   → 【专门的工具通常好于通用模型】
#
# ---- 通透性(Caco-2、PAMPA)----
#   【实验体系差异大】(见 086)
#   → 混合不同来源的数据要谨慎
#
# ---- 血浆蛋白结合 ----
#   【高结合率区间难以精确】
#     99% vs 99.9% 的差异对游离药物浓度影响 10 倍
#     但模型很难分辨
#   → 【建议建模 log(游离分数) 而非结合率百分比】

建模的实用做法

import numpy as np
import lightgbm as lgb
from rdkit import Chem
from rdkit.Chem import Descriptors, rdFingerprintGenerator

# ---- 特征:【描述符权重更高】----
# QSPR 中,物化描述符比指纹更重要
# 【与 QSAR 相反】

DESC_QSPR = [
    "MolWt", "MolLogP", "MolMR", "TPSA",
    "NumHDonors", "NumHAcceptors", "NumRotatableBonds",
    "NumAromaticRings", "NumAliphaticRings", "RingCount",
    "FractionCSP3", "HeavyAtomCount", "NHOHCount", "NOCount",
    "LabuteASA", "BalabanJ", "BertzCT",
    "HallKierAlpha", "Kappa1", "Kappa2", "Kappa3",
    "Chi0v", "Chi1v", "Chi2v", "Chi3v", "Chi4v",
    "MaxPartialCharge", "MinPartialCharge",
    "NumSaturatedRings", "NumHeteroatoms",
]

gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=1024)

def featurize_qspr(smiles_list, use_fp=True):
    X = []
    for s in smiles_list:
        m = Chem.MolFromSmiles(s)
        if m is None:
            X.append(np.zeros(len(DESC_QSPR) + (1024 if use_fp else 0)))
            continue
        d = []
        for name in DESC_QSPR:
            try:
                d.append(getattr(Descriptors, name)(m))
            except Exception:
                d.append(0.0)
        d = np.nan_to_num(np.array(d), nan=0.0, posinf=0.0, neginf=0.0)
        if use_fp:
            fp = np.array(gen.GetCountFingerprint(m).ToList())
            X.append(np.concatenate([d, fp]))
        else:
            X.append(d)
    return np.array(X)

# 【对比实验:描述符 vs 指纹 vs 两者】
# 【QSPR 中,常常「只用描述符」就已经很好】
# → 而 QSAR 中通常需要指纹

# ---- 用现成方法作为基线 ----
def crippen_baseline(smiles_list):
    """logP 的计算基线"""
    from rdkit.Chem import Crippen
    return np.array([Crippen.MolLogP(Chem.MolFromSmiles(s))
                     if Chem.MolFromSmiles(s) else np.nan
                     for s in smiles_list])

# 【重要】:
#   在做 logP 的 ML 模型前,
#   先看 Crippen 计算值与实验值的相关性
#   → 如果已经很好,ML 的增量可能不值得

QSPR 特有的注意事项

  • 数据的实验条件必须一致:温度、pH、缓冲液——混合不同条件的数据是常见错误
  • 用对数尺度:溶解度用 logS、通透性用 log Papp——这些量跨越数量级;
  • 注意可电离化合物:中性与电离形式的性质差异巨大,数据的 pH 条件必须记录
  • 优先用描述符:QSPR 中描述符的作用比 QSAR 大得多;
  • 与物理模型比较:logP 有 Crippen,溶解度有 GSE——ML 必须超过这些基线才有价值
  • 跨化学空间的泛化更好:因为物理规律普适——这意味着可以用更多样的训练数据

QSPR 结果在项目中的用法

# 【QSPR 的主要价值:早期排除】
#
# 在合成之前,用预测值筛掉明显有问题的分子:
#   logS < -6      → 溶解度可能有问题
#   logD7.4 > 4    → 亲脂性过高,可能有代谢与毒性风险
#   TPSA > 140     → 口服吸收可能差(见 060)
#
# 【不要期望精确预测】:
#   预测 logS = -4.2 而实测 -4.8
#   → 【这个精度对「排除明显不行的分子」已经够用】
#   → 但不足以支撑「这个比那个溶解度好」的细致判断
#
# 【多参数视角】(见 405):
#   实际优化是多目标的:
#     活性 ↑ + logD ↓ + 溶解度 ↑ + 通透性 ↑
#   → 这些性质之间常常冲突
#     (提高亲脂性通常提升活性与通透性,但损害溶解度)
#   → 【QSPR 模型的价值在于快速看到这个权衡】

def multiparameter_profile(smiles, models):
    """给出一个分子的多维性质画像"""
    from rdkit import Chem
    from rdkit.Chem import Descriptors, Crippen
    m = Chem.MolFromSmiles(smiles)
    if m is None:
        return None
    return {
        "MW": round(Descriptors.MolWt(m), 1),
        "cLogP": round(Crippen.MolLogP(m), 2),
        "TPSA": round(Descriptors.TPSA(m), 1),
        "HBD": Descriptors.NumHDonors(m),
        "RotB": Descriptors.NumRotatableBonds(m),
        "pred_logS": float(models["logS"].predict([featurize_qspr([smiles])[0]])[0]),
        "pred_perm": float(models["perm"].predict([featurize_qspr([smiles])[0]])[0]),
    }
# 【把这个画像与目标产品概况对比,就是早期决策的依据】

关键要点

  • QSPR 有明确的物理基础,因此描述符作用大、泛化能力好于 QSAR;
  • logP 有 Crippen、溶解度有 GSE——ML 必须超过这些物理基线才有价值;
  • 动力学与热力学溶解度可能相差几十倍,不能混用;
  • 价值在早期排除快速看到多参数权衡,而非精确预测。

延伸资源