135

GuacaMol 论文精读:分子生成评测为什么容易被刷分

GuacaMol 定义了分子生成的标准评测,也暴露了这类评测容易被刷分的本质。这篇讲清它的任务设计与失效方式。

GuacaMol(Brown 等,JCIM 2019)是分子生成模型的标准评测框架。它的设计相当用心,但也清楚地展示了一个根本问题:只要目标函数是可计算的,模型就能找到「满足目标但化学上荒谬」的分子

两类任务

类别 问题 指标
分布学习 能否生成与训练集相似的分子 有效性、唯一性、新颖性、KL 散度、FCD
目标导向 能否优化指定的目标函数 20 个基准目标的得分

分布学习的指标

# Validity(有效性)
#   生成的 SMILES 中能被 RDKit 解析的比例
#   → 现在的模型普遍 > 95%,【区分度已经很低】
#
# Uniqueness(唯一性)
#   生成的分子中不重复的比例
#
# Novelty(新颖性)
#   不在训练集中的比例
#
# KL divergence(KL 散度)
#   生成分子与训练集在各种描述符分布上的差异
#   (分子量、logP、TPSA、环数、...)
#   → 分数越接近 1 越好
#
# FCD(Fréchet ChemNet Distance)
#   用一个预训练的神经网络提取分子表示,
#   比较生成集与参考集的分布距离
#   → 类比图像生成中的 FID
#
# 【这些指标的共同问题】:
#   它们衡量「像不像训练数据」,
#   而药物发现需要的是「好且新」
#
#   一个完美复制训练集分布的模型,
#   在所有分布指标上都完美 ——
#   但它没有任何发现价值
#
# → 分布学习指标应作为【健全性检查】,
#   而非模型优劣的判据

目标导向任务与刷分问题

# 20 个目标任务包括:
#   - 重新发现(rediscovery):生成指定的已知药物
#   - 相似性:生成与某分子相似的分子
#   - 中位分子:同时与两个分子相似
#   - 性质匹配:达到指定的 logP、TPSA 等
#   - 多目标:同时满足多个约束
#   - 骨架跃迁:保持药效团但换骨架
#
# 【核心问题】:
#   这些目标函数都是【可计算且可微/可搜索】的
#   → 优化算法必然找到「钻空子」的解
#
# 典型的钻空子方式:
#
# 1) 生成极端分子
#    要求高 logP → 生成一条长烷基链
#    分数完美,但化学上毫无意义
#
# 2) 利用相似性指标的盲区
#    ECFP 相似性高,但三维形状完全不同
#
# 3) 生成不稳定/不可合成的结构
#    目标函数不检查这些
#
# 4) 生成描述符「刚好」满足但结构荒谬的分子
#
# 【论文本身也承认这一点】:
#   高分不等于有用的分子
#
# → 因此 GuacaMol 分数【不应作为方法优劣的唯一依据】

使用

pip install guacamol

# 分布学习评测
from guacamol.assess_distribution_learning import assess_distribution_learning
from guacamol.distribution_matching_generator import DistributionMatchingGenerator

class MyGenerator(DistributionMatchingGenerator):
    def generate(self, number_samples: int):
        # 返回 SMILES 列表
        return my_model.sample(number_samples)

assess_distribution_learning(
    MyGenerator(),
    chembl_training_file="guacamol_v1_train.smiles",
    json_output_file="distribution_results.json",
)

# 目标导向评测
from guacamol.assess_goal_directed_generation import assess_goal_directed_generation
from guacamol.goal_directed_generator import GoalDirectedGenerator

class MyOptimizer(GoalDirectedGenerator):
    def generate_optimized_molecules(self, scoring_function,
                                     number_molecules, starting_population=None):
        # scoring_function.score(smiles) 返回 0~1 的分数
        return my_optimizer.run(scoring_function, number_molecules)

assess_goal_directed_generation(
    MyOptimizer(),
    json_output_file="goal_directed_results.json",
    benchmark_version="v2",
)

更有意义的评测维度

维度 为什么重要
可合成性 不能合成的分子没有价值——用 SA score、RAscore 或逆合成规划检验
结构警示 PAINS、Brenk 等过滤(见 069《Brenk Alert》
化学多样性 生成的是一批近似物还是真正多样的分子
骨架新颖性 是否产生了训练集中没有的骨架
药化专家评分 最有说服力但最贵——让化学家盲评
多参数同时满足 真实项目从来不是单目标
实验验证 唯一的最终判据

评价生成模型的务实做法

# 一个更接近实际的评测流程:
#
# 1) 用 GuacaMol/MOSES 做健全性检查
#    有效性 > 95%,唯一性高,无明显异常
#    → 通不过说明模型有基本问题
#
# 2) 【生成一批分子,做完整的过滤流程】
#    去重 → 结构警示过滤 → 性质范围过滤
#    → 可合成性评分 → 相似性去冗余
#    统计:1000 个生成分子中,多少个通过?
#    → 【这个「通过率」比 GuacaMol 分数有意义得多】
#
# 3) 检查骨架分布
#    生成的分子分成多少个不同骨架?
#    有多少骨架是训练集里没有的?
#
# 4) 【盲评】
#    把生成分子与真实的项目分子混在一起,
#    让药化专家判断哪些「看起来像真的」
#    → 这个测试很残酷但很有信息量
#
# 5) 小规模实验验证
#    合成 5~10 个,测活性
#    → 唯一能真正回答「有没有用」的方式
#
# 现实提醒:
#   目前公开发表的生成模型中,
#   有实验验证记录的仍然是少数
#   → 阅读论文时应特别关注这一点(见 170)

关键要点

  • 分布学习指标衡量「像不像训练数据」——完美复制训练集分布的模型毫无发现价值;
  • 目标函数可计算就必然能被钻空子——高分分子常常化学上荒谬;
  • 有效性指标现在普遍 > 95%,区分度已经很低
  • 更有意义的评测是完整过滤流程的通过率加药化专家盲评。

延伸资源