399

反应数据库:USPTO、Reaxys 与 Pistachio 怎么用

反应数据库是合成 AI 的数据基础。这篇对比 USPTO、Reaxys 与 Pistachio 的特点、许可与数据质量问题。

所有合成 AI 模型都建立在反应数据之上。数据的覆盖面与质量直接决定模型能力的上限,而各个数据源的特点差别很大。

三个主要数据源

USPTO Reaxys Pistachio
来源 美国专利文本挖掘 期刊 + 专利,人工审编 专利文本挖掘(商业)
规模 约 100~180 万条 数千万条 数百万条
许可 公开免费 商业订阅(昂贵) 商业许可
数据质量 中等(自动抽取) 高(人工审编) 中高
条件信息 部分 详细 较详细
产率 部分有 较全 部分
原子映射 需自行处理 提供 提供
用途 学术研究、开源模型 工业检索与建模 工业建模

USPTO 是几乎所有开源合成 AI 工具的训练数据(AiZynthFinder、ASKCOS 等)。理解它的局限,就理解了这些工具的局限。

USPTO 数据集的版本

# 常见的几个版本(都源自 Lowe 的文本挖掘工作)
#
# USPTO-full        约 180 万条,未去重
# USPTO-MIT         约 48 万条,清洗后,常用于反应预测
# USPTO-50K         5 万条,按反应类型分类,常用于逆合成基准
# USPTO-STEREO      保留立体化学信息
#
# 获取:
#   https://figshare.com (搜索 USPTO reactions)
#   或通过 rxn-dataset 等工具包

# 数据格式(反应 SMILES):
#   反应物>试剂>产物
#   CC(=O)O.OCC>[H+]>CCOC(C)=O

数据质量问题:必须知道

  • 只有成功的反应这是最根本的局限。专利与文献不报告失败的实验,所以模型学不到「什么条件行不通」。这解释了为什么合成 AI 会自信地给出不可行的建议。
  • 文本抽取错误:从专利文本自动抽取时会出错——反应物与试剂混淆、化学计量错误、产物识别错误。
  • 条件信息不完整:专利常写「在适当溶剂中,适当温度下」,具体条件缺失。
  • 原子映射质量:反应物到产物的原子对应关系是模板提取的基础,自动映射(如 RXNMapper)有错误率。
  • 产率不可靠:专利中的产率可能是最优值或估计值。
  • 反应类型分布极不均衡酰胺偶联、Suzuki 偶联、Boc 脱保护等占了很大比例,罕见反应样本极少。这导致模型对常见反应表现好,对罕见反应几乎无能为力。
  • 专利偏倚:反映的是工业界的合成偏好,某些学术上重要的反应代表性不足。

数据处理流程

from rdkit import Chem
from rdkit.Chem import AllChem
import re

def clean_reaction_smiles(rxn_smiles):
    """清洗反应 SMILES"""
    try:
        parts = rxn_smiles.split(">")
        if len(parts) != 3:
            return None, "bad_format"
        reactants, reagents, products = parts

        # 1) 解析检查
        r_mols = [Chem.MolFromSmiles(s) for s in reactants.split(".") if s]
        p_mols = [Chem.MolFromSmiles(s) for s in products.split(".") if s]
        if any(m is None for m in r_mols + p_mols):
            return None, "parse_failed"
        if not p_mols:
            return None, "no_product"

        # 2) 只保留主产物(最大的)
        main_product = max(p_mols, key=lambda m: m.GetNumHeavyAtoms())

        # 3) 原子守恒粗检(产物原子应来自反应物)
        from collections import Counter
        def counts(mols):
            c = Counter()
            for m in mols:
                for a in m.GetAtoms():
                    if a.GetSymbol() != "H":
                        c[a.GetSymbol()] += 1
            return c
        rc, pc = counts(r_mols), counts([main_product])
        if any(pc[el] > rc.get(el, 0) for el in pc):
            return None, "atom_imbalance"

        # 4) 排除平凡反应(产物 = 某个反应物)
        p_canon = Chem.MolToSmiles(main_product)
        if p_canon in [Chem.MolToSmiles(m) for m in r_mols]:
            return None, "trivial"

        # 5) 排除过小或过大的反应
        if main_product.GetNumHeavyAtoms() < 5:
            return None, "too_small"

        return {
            "reactants": ".".join(Chem.MolToSmiles(m) for m in r_mols),
            "reagents": reagents,
            "product": p_canon,
        }, None
    except Exception as e:
        return None, f"error:{type(e).__name__}"

# 典型清洗后保留率:50%~70%
# 一定要统计各类失败原因,这能暴露数据源的系统性问题

原子映射

# 原子映射是模板提取的前提:需要知道产物中每个原子来自哪个反应物原子

pip install rxnmapper

from rxnmapper import RXNMapper

rxn_mapper = RXNMapper()
results = rxn_mapper.get_attention_guided_atom_maps([
    "CC(=O)O.OCC>>CCOC(C)=O"
])
print(results[0]["mapped_rxn"])
print(f"置信度: {results[0]['confidence']:.3f}")

# 输出形如:
#   [CH3:1][C:2](=[O:3])[OH:4].[OH:5][CH2:6][CH3:7]>>
#   [CH3:1][C:2](=[O:3])[O:5][CH2:6][CH3:7]

# 置信度低的映射应剔除 —— 错误的映射会产生错误的模板

模板提取

# 从映射好的反应中提取反应模板(反应规则)
# 常用工具:rdchiral(处理立体化学的模板提取与应用)

pip install rdchiral

from rdchiral.template_extractor import extract_from_reaction

reaction = {
    "_id": 0,
    "reactants": "[CH3:1][C:2](=[O:3])[OH:4].[OH:5][CH2:6][CH3:7]",
    "products": "[CH3:1][C:2](=[O:3])[O:5][CH2:6][CH3:7]",
}
template = extract_from_reaction(reaction)
print(template["reaction_smarts"])

# 模板的「半径」影响泛化能力:
#   半径小(只含反应中心)→ 泛化好但可能应用到不合适的底物
#   半径大(含更多环境)  → 特异性好但泛化差
#
# 实践中常提取多个半径的模板,或用统计频率筛选

开放数据的新进展

  • ORD(Open Reaction Database):结构化的开放反应数据库,格式规范(含完整条件、产率、分析数据),并鼓励提交阴性结果——这正是现有数据源最缺的;
  • 高通量实验数据集:某些公开的 HTE 数据集包含系统变化的条件与完整的产率(含低产率),质量远高于文献挖掘数据;
  • 电子实验记录本数据:企业内部数据质量最高但不公开——这是自建团队的潜在优势

关键要点

  • USPTO 免费但质量中等,是所有开源合成 AI 工具的训练基础;
  • 「只有成功反应」是最根本的局限,解释了合成 AI 为何会给出不可行建议;
  • 反应类型分布极不均衡,常见反应表现好、罕见反应几乎无能为力;
  • 自建团队的优势在于内部数据包含失败案例,这是公开数据没有的。

延伸资源