405

Lead Optimization:先导优化阶段如何平衡多参数

先导优化要在多个冲突目标间取得平衡。这篇讲清参数间的相互制约、优化顺序与常用的权衡手段。

先导优化(Lead Optimization, LO)是新药发现中耗时最长、投入最大的阶段。它的困难不在于「提高某个指标」,而在于这些指标彼此冲突——改善一个往往损害另一个

参数间的典型冲突

改动 改善 损害
增加疏水基团 活性、通透性 溶解度、代谢稳定性、hERG
增加极性基团 溶解度、降 hERG 通透性、可能损失活性
增加分子量 活性、选择性 通透性、溶解度、口服吸收
引入碱性中心 溶解度 hERG 风险、组织蓄积
阻断代谢位点 代谢稳定性 可能损失活性、转移代谢到别处
刚性化 活性(减少熵损失)、选择性 溶解度(常降低)
提高活性 剂量降低 可能牺牲选择性或性质

「增加脂溶性提高活性」是最常见的陷阱:它几乎总是有效(疏水结合几乎不需要精确匹配),但同时推高 hERG 风险、降低溶解度、加快代谢。这就是为什么要看 LLE 而非只看活性。

优化的一般顺序

# 经验性的优先级(因项目而异)
#
# 1) 先解决「致命缺陷」
#    有没有哪一项差到无法接受?
#    (如溶解度 < 1 μM、代谢半衰期 < 5 min、hERG < 1 μM)
#    → 这类问题不解决,其它优化都是白费
#
# 2) 建立足够的活性与选择性
#    达到目标水平即可,不必追求极致
#
# 3) 优化 ADMET 到可接受范围
#
# 4) 精细平衡,选出最佳候选
#
# 关键原则:
#   「足够好」优于「最好」
#   活性做到 1 nM 而性质很差,不如活性 20 nM 但性质均衡
#   除非该靶点确实需要极高活性

常用的权衡手段

  • 生物电子等排替换(见 281《Cresset Spark》):在保持活性的前提下改善性质。羧酸→四氮唑改善通透性;苯环→吡啶降 logP。
  • 调整 pKa:碱性太强导致 hERG 与蓄积,可通过邻近吸电子基团降低 pKa。
  • 代谢阻断:在代谢软点引入氟、甲基或改变电子密度。注意可能把代谢转移到其它位点。
  • 降低分子平面性:引入 sp³ 中心(Fsp³ 提高)通常改善溶解度并可能降低脱靶。
  • 控制分子量增长:每加一个基团都要问「它带来的活性提升值得这些重量吗」。
  • 利用构象限制:环化或引入位阻锁定活性构象,可在不增重的情况下提高活性。

多参数优化的实现

import numpy as np
from rdkit import Chem
from rdkit.Chem import Descriptors, Crippen

def desirability(v, low, high, direction="higher"):
    """把指标映射到 0~1 的期望度,用平滑函数避免阈值悬崖"""
    if v is None or (isinstance(v, float) and np.isnan(v)):
        return 0.5                     # 缺失值给中性分
    if direction == "higher":
        return float(1 / (1 + np.exp(-(v - (low + high) / 2) /
                                     max((high - low) / 6, 1e-9))))
    if direction == "lower":
        return float(1 / (1 + np.exp((v - (low + high) / 2) /
                                     max((high - low) / 6, 1e-9))))
    center, width = (low + high) / 2, max((high - low) / 2, 1e-9)
    return float(np.exp(-((v - center) / width) ** 2))

CRITERIA = {
    "pIC50":       {"low": 7.0, "high": 9.0,  "dir": "higher", "w": 2.0},
    "selectivity": {"low": 1.0, "high": 2.0,  "dir": "higher", "w": 1.5},
    "logD":        {"low": 1.0, "high": 3.5,  "dir": "range",  "w": 1.0},
    "solubility":  {"low": 10,  "high": 100,  "dir": "higher", "w": 1.5},
    "HLM_CLint":   {"low": 10,  "high": 50,   "dir": "lower",  "w": 1.5},
    "hERG_pIC50":  {"low": 4.5, "high": 5.5,  "dir": "lower",  "w": 1.5},
    "Papp":        {"low": 2,   "high": 10,   "dir": "higher", "w": 1.0},
}

def mpo_score(compound_data, criteria=CRITERIA):
    """几何加权平均:任一项极差则整体差"""
    scores, weights = [], []
    for name, cfg in criteria.items():
        d = desirability(compound_data.get(name), cfg["low"],
                         cfg["high"], cfg["dir"])
        scores.append(max(d, 1e-6) ** cfg["w"])
        weights.append(cfg["w"])
    return float(np.prod(scores) ** (1 / sum(weights)))

# 为什么用几何平均而非算术平均:
#   算术平均下,一个 0 分项可以被其它高分项掩盖
#   几何平均下,任一项接近 0 则整体接近 0
#   → 这更符合「必须每项都过关」的实际要求

不确定性感知的决策

# 预测值都有误差,决策时应考虑这一点

def mpo_with_uncertainty(predictions, uncertainties, criteria, n_sim=2000):
    """蒙特卡洛传播不确定性,得到 MPO 分数的分布"""
    scores = []
    for _ in range(n_sim):
        sampled = {k: np.random.normal(predictions[k], uncertainties.get(k, 0))
                   for k in predictions}
        scores.append(mpo_score(sampled, criteria))
    return {
        "mean": float(np.mean(scores)),
        "ci_90": [float(np.percentile(scores, 5)),
                  float(np.percentile(scores, 95))],
    }

# 关键用法:
#   如果两个化合物的 90% 置信区间高度重叠,
#   就不该仅凭 MPO 分数选一个弃一个 ——
#   此时应引入其它因素(合成难度、新颖性、专利空间)

什么时候停止优化

  • 达到目标产品特征(TPP)的要求(见 414《目标产品特征 TPP》)——这是最明确的停止信号;
  • 改善出现平台期:连续几轮 SAR 无实质进展,说明该系列可能已接近上限;
  • 参数间陷入循环:改善 A 就损害 B,改善 B 就损害 A,反复无法突破——这通常提示需要骨架跃迁而非继续微调(见 352《Scaffold Hopping 实战》);
  • 「足够好」原则过度优化是常见的资源浪费。如果当前分子已满足 TPP,继续追求更好的数字通常不划算——把资源投到推进临床前研究上更有价值。

数据管理的重要性

LO 阶段会产生几百到上千个化合物、几十个测定终点的数据。如果数据管理混乱,SAR 分析将无从做起

  • 统一的化合物注册与唯一标识;
  • 测定条件、批次、日期的完整元数据;
  • 预测值与实测值严格区分
  • 失败与阴性数据同样记录;
  • 可程序化取数用于建模(见 300《CDD Vault》225《AI 制药工具工程化》)。

关键要点

  • LO 的困难在于参数间相互冲突,改善一个常损害另一个;
  • 先解决致命缺陷,再做精细平衡;「足够好」优于「最好」
  • MPO 用几何平均而非算术平均,并考虑预测不确定性;
  • 陷入「改 A 损 B」的循环时,应考虑骨架跃迁而非继续微调

延伸资源