QED(Quantitative Estimate of Drug-likeness,Bickerton et al. 2012)把多个理化性质综合成一个 0~1 的分数。它是分子生成中最常用的约束之一,但也是最容易被误用的指标。
QED 的构成
它把八个性质各自映射成「期望度函数」,再取加权几何平均:
| 性质 | 理想范围(大致) |
|---|---|
| 分子量 MW | 约 300 |
| 脂水分配系数 ALOGP | 约 2~3 |
| 氢键供体 HBD | 少 |
| 氢键受体 HBA | 适中 |
| 极性表面积 PSA | 适中 |
| 可旋转键 ROTB | 少 |
| 芳环数 AROM | 适中 |
| 结构警报 ALERTS | 无 |
各期望度函数是从已上市口服药物的性质分布拟合出来的。这就决定了它的适用边界:QED 衡量的是「像不像典型的口服小分子药」,而不是「是不是好药」。
计算
from rdkit import Chem
from rdkit.Chem import QED, Descriptors
for smi in [
"CC(=O)Oc1ccccc1C(=O)O", # 阿司匹林
"COc1cc2ncnc(Nc3ccc(F)c(Cl)c3)c2cc1OCCCN1CCOCC1", # 吉非替尼类
"CC(C)Cc1ccc(cc1)C(C)C(=O)O", # 布洛芬
]:
mol = Chem.MolFromSmiles(smi)
props = QED.properties(mol)
print(f"QED={QED.qed(mol):.3f} MW={props.MW:.0f} "
f"ALOGP={props.ALOGP:.2f} PSA={props.PSA:.0f} "
f"HBD={props.HBD} HBA={props.HBA} ROTB={props.ROTB}")
# 也可自定义权重
print(QED.qed(mol, w=QED.WEIGHT_MAX)) # 各性质权重不同的变体
print(QED.qed(mol, w=QED.WEIGHT_NONE)) # 等权重
在 REINVENT4 中配置
[[stage.scoring.component]]
[stage.scoring.component.QED]
[[stage.scoring.component.QED.endpoint]]
name = "QED"
weight = 0.6
# QED 本身已是 0~1,通常不需要 transform
# 若想强调高 QED,可加 sigmoid
# transform.type = "sigmoid"
# transform.low = 0.4
# transform.high = 0.8
# transform.k = 0.5
为什么不该过度依赖 QED
- 它是「典型性」而非「优质性」的度量。QED 高只说明这个分子的性质分布接近已上市口服药的中位数。很多成功药物的 QED 并不高——大环化合物、天然产物衍生物、肽类、共价抑制剂、PROTAC 都会得到低 QED,但它们是完全合法的药物模态。
- 会系统性压制创新:把 QED 权重设得很高,模型会收敛到「平庸的典型小分子」,恰恰排除了新模态的探索空间。
- 与活性无关:QED 完全不看分子能否结合靶点。一个 QED = 0.95 但毫无活性的分子没有任何价值。
- 不适用于非口服给药:静脉给药、吸入给药、局部给药的分子,性质要求与口服完全不同。
- 各性质的权重是经验的:QED 的权重来自对已有药物的拟合,不代表因果关系。
更合理的用法
# 用法一:作为软约束而非主目标
# 权重设低(0.3~0.6),主要目标应该是活性与选择性
# 用法二:只作为下界过滤,不追求最大化
[[stage.scoring.component.QED.endpoint]]
name = "QED_floor"
weight = 0.5
transform.type = "sigmoid"
transform.low = 0.3 # 低于 0.3 惩罚
transform.high = 0.5 # 超过 0.5 就够了,不再加分
transform.k = 1.0
# 这样模型只需保证「不太离谱」,不会为了刷 QED 牺牲其它目标
# 用法三:换成更贴合项目的自定义性质约束
# 与其用 QED 这个综合指标,不如直接约束项目关心的性质:
# - 中枢神经系统药物 → 用 CNS MPO 而非 QED
# - 需要口服暴露 → 单独约束 TPSA、HBD、MW
# - 抗菌药物 → 革兰阴性菌渗透规则与常规类药规则不同
项目特异的 MPO 更有价值
import numpy as np
def desirability(value, low, high, direction="range"):
"""把性质值映射到 0~1,用平滑函数"""
if direction == "range":
center, width = (low + high) / 2, max((high - low) / 2, 1e-9)
return float(np.exp(-((value - center) / width) ** 2))
if direction == "lower":
return float(1 / (1 + np.exp((value - high) / (0.1 * abs(high) + 1e-9))))
return float(1 / (1 + np.exp(-(value - low) / (0.1 * abs(low) + 1e-9))))
def custom_mpo(mol, criteria, weights):
"""按项目需求自定义的多参数评分"""
scores = []
for name, (fn, lo, hi, direc) in criteria.items():
d = desirability(fn(mol), lo, hi, direc)
scores.append(d ** weights[name])
return float(np.prod(scores) ** (1 / sum(weights.values())))
# 例:一个针对口服中枢神经系统药物的自定义 MPO
from rdkit.Chem import Descriptors, Crippen
criteria = {
"MW": (Descriptors.MolWt, 250, 400, "range"),
"cLogP": (Crippen.MolLogP, 1.0, 3.5, "range"),
"TPSA": (Descriptors.TPSA, 40, 90, "range"),
"HBD": (Descriptors.NumHDonors, 0, 2, "lower"),
}
weights = {"MW": 1.0, "cLogP": 1.5, "TPSA": 1.5, "HBD": 1.0}
print(custom_mpo(mol, criteria, weights))
这比 QED 更有价值:QED 是「通用的典型性」,而自定义 MPO 反映的是「你这个项目真正需要什么」。
常见坑与提示
- QED 衡量「像不像典型口服小分子」,不等于「是不是好药」;
- 权重设太高会压制创新,把模型逼向平庸的典型分子;
- 用作下界过滤(超过 0.5 不再加分)比追求最大化更合理;
- 项目特异的自定义 MPO 通常比通用 QED 更有指导价值。
延伸资源
- 生成平台:347《用 REINVENT4 生成新分子》、221《REINVENT4》;其它约束:348《在分子生成中加入 SA Score 约束》、350《在分子生成中加入 ADMET 约束》、351《在分子生成中加入 Docking Score 约束》;
- 类药性规则与 MPO 见「成药性」模块。