420

可信 AI Trustworthy AI:可解释、可重复、可审计

可信 AI 要求可解释、可重复、可审计。这篇讲清三个维度的具体含义与在药物研发中的落地做法。

可信 AI(Trustworthy AI)不是一个抽象的口号,它可以拆解成几个可操作的技术与流程要求。在药物研发这种高风险、长周期、强监管的领域,这些要求尤其实际。

三个核心维度

维度 核心问题 落地手段
可解释 模型为什么给出这个预测? 特征重要性、局部解释、可解释模型
可重复 同样输入能否给出同样输出? 版本锁定、种子固定、环境容器化
可审计 能否追溯某个决策的完整依据? 完整记录、数据溯源、变更管理

可解释性:在药物研发中的具体价值

# 可解释性不只是为了合规,它有直接的科学价值

# 1) 特征重要性 —— 全局解释
import shap

explainer = shap.TreeExplainer(model)
shap_values = explainer.shap_values(X)
shap.summary_plot(shap_values, X, feature_names=feature_names)

# 2) 单分子解释 —— 局部解释
#    对某个具体化合物,哪些结构特征驱动了预测?
shap.force_plot(explainer.expected_value, shap_values[i], X[i])

# 3) 映射回分子结构 —— 最有用的形式
from rdkit import Chem
from rdkit.Chem import Draw, rdFingerprintGenerator

def explain_on_molecule(smiles, model, explainer):
    """把重要特征映射回分子的具体原子"""
    mol = Chem.MolFromSmiles(smiles)
    gen = rdFingerprintGenerator.GetMorganGenerator(radius=2, fpSize=2048)
    ao = rdFingerprintGenerator.AdditionalOutput()
    ao.AllocateBitInfoMap()
    fp = gen.GetFingerprint(mol, additionalOutput=ao)
    bit_info = ao.GetBitInfoMap()

    # 取重要的位,找到对应的原子环境
    # → 可视化「哪个子结构导致了高 hERG 预测」
    #
    # 这对药化的价值远大于一个数字:
    #   知道是哪个基团有问题,就知道该改哪里
    return bit_info

# 4) 反事实解释
#    「如果把这个基团换掉,预测会怎么变?」
#    → 直接给出改造建议

可解释性最大的实际价值是「把预测变成可操作的设计建议」:告诉药化「这个分子 hERG 风险高」不如告诉他「这个碱性氮 + 疏水尾巴的组合是主要贡献」——后者直接指向改造方案。

可解释性的边界

  • 解释不等于因果:SHAP 值反映的是「模型如何使用特征」,不是「这个特征真的导致了该性质」。模型可能学到了数据中的虚假关联;
  • 解释本身可能不稳定:不同的解释方法可能给出不同结果;同一方法在相似样本上的解释也可能差别很大;
  • 可解释模型的代价:线性模型、决策树可解释性好,但表达能力有限。不必为了可解释性牺牲性能——用复杂模型 + 事后解释通常是更好的权衡
  • 解释要与领域知识对照:如果模型的解释与化学常识矛盾,可能是模型学到了伪相关,值得深究。

可重复性的技术栈

# 三个层次的固化

# 层次 1:代码版本
git rev-parse HEAD          # 记录提交哈希

# 层次 2:环境
# 用容器 + 锁文件
pip freeze > requirements.lock
# 或 conda-lock / pixi

# 层次 3:数据版本
# DVC 或内容哈希
import hashlib
def data_fingerprint(df):
    return hashlib.sha256(
        df.to_csv(index=False).encode()).hexdigest()

# 层次 4:随机性
import random, numpy as np, torch
def set_all_seeds(seed=42):
    random.seed(seed)
    np.random.seed(seed)
    torch.manual_seed(seed)
    torch.cuda.manual_seed_all(seed)
    torch.backends.cudnn.deterministic = True
    torch.backends.cudnn.benchmark = False

# 注意:完全的位级可重复在 GPU 上有时难以保证,
#      此时应记录并接受一定的数值容差

可审计性:记录什么

# 每次预测都应生成完整的审计记录

AUDIT_RECORD = {
    # 谁、何时
    "timestamp": "2026-01-15T10:30:00Z",
    "requested_by": "user_id",

    # 用了什么
    "model_name": "herg_classifier",
    "model_version": "v2.3.1",
    "model_hash": "sha256:abc...",
    "code_commit": "git:def456",
    "environment": "container:ghcr.io/org/img@sha256:...",

    # 输入输出
    "input": {"smiles": "...", "hash": "..."},
    "output": {"prediction": 5.2, "uncertainty": 0.4},

    # 可信度信息
    "applicability_domain": {"status": "in_domain", "score": 0.62},

    # 人的介入
    "human_review": {
        "reviewed": True,
        "reviewer": "...",
        "decision": "accepted",
        "rationale": "与已知 SAR 一致",
    },

    # 下游使用
    "used_in_decision": "compound_prioritization_round_5",
}

# 关键原则:
#   这些记录必须在预测时自动生成,
#   而不是事后补录 —— 事后无法保证准确性

人的监督:怎么设计

  • 明确触发条件:什么情况必须人工复核?(超出适用域、不确定性高、与既有认知冲突、涉及关键决策);
  • 复核者要有能力推翻如果流程上人只能「确认」不能「否决」,这个监督就是形式化的
  • 记录推翻的理由:这些记录是改进模型的宝贵输入——人推翻模型的地方,往往是模型的系统性缺陷所在;
  • 避免自动化偏差:人容易过度信任自动化系统的输出。呈现预测时一并给出不确定性与适用域,能减少这种偏差
  • 定期校准:回顾人与模型意见不一致的案例,看谁对得多。

公平性与偏倚

  • 在药物研发中的表现形式:训练数据的化学空间偏倚(导致对某类化学型系统性预测不准)、人群代表性偏倚(临床数据集中于某些族裔)、研究热度偏倚(热门靶点数据多);
  • 后果:模型对代表性不足的类别系统性表现更差,可能导致这些方向被系统性地低估;
  • 缓解:分层评估性能(按化学类别、按人群亚组),而非只看整体指标;主动补充代表性不足的数据。

关键要点

  • 可解释性最大的实际价值是把预测变成可操作的设计建议
  • 解释不等于因果,解释本身也可能不稳定,需与领域知识对照;
  • 审计记录必须在预测时自动生成,事后无法补齐;
  • 人的监督要能真正推翻模型,否则只是形式化;推翻的理由是改进模型的宝贵输入。

延伸资源