3. pLDDT 的定义:什么是局部距离差异测试(lDDT),pLDDT 的由来

很多人第一次看到 pLDDT,都会问同一个问题——这个分数到底在算什么?

嗯,要搞懂 pLDDT,得先聊它的前身:lDDT。这东西看着像个黑盒子,背后的逻辑其实很直观。

3.1 传统评估方法为什么不灵了

在 lDDT 出现之前,评估蛋白质模型好坏,最常用的指标是 RMSD(均方根偏差)。

做法很简单:把预测结构和真实结构叠在一起,算所有原子位置的偏差。

听起来挺合理吧?但实际上有个大问题。

RMSD 对整体偏移太敏感。

我记得刚开始做结构预测时,遇到过这么一个案例:一个蛋白的某个结构域整体平移了 2 Å,但域内构象一点没变。RMSD 直接飙到 2 Å,判定为"差模型"。可实际局部几何是完全正确的。

说白了,RMSD 惩罚的是"整体对齐偏差",不是"局部构象错误"。这就导致它没法区分两种截然不同的情况:

  • 整体好、局部差 —— RMSD 可能还行,但结构不能用
  • 整体偏、局部好 —— RMSD 很难看,但局部其实没问题

你想想看,做药物设计或者突变分析,我们关心的是局部侧链朝向、活性位点构象。全局叠得再好,局部错了也是白搭。

核心矛盾:RMSD 是一个"全局指标",而我们需要的是一把能衡量"局部结构质量"的尺子。

3.2 lDDT 的核心思想

lDDT 的全称是 Local Distance Difference Test。关键词就在"Local"上。

它的想法很简单:不去做全局叠加,而是直接比较模型和真实结构中,每个残基周围局部距离的保留情况。

具体来说:

  • 只考虑序列上相距较近的残基对(一般 |i−j| ≥ 6,且距离 < 15 Å)
  • 不看整体偏移,只看"这些残基之间的相对距离"是否跟真实结构一致

这样做的好处很明显:即使你模型的某个结构域整体平移了,只要域内构象正确,lDDT 依然会给高分。

我在项目中遇到过好几回,用 RMSD 筛掉的模型,用 lDDT 一测,局部构象其实非常好。后来就养成了习惯,两个指标一起看。

3.3 lDDT 的数学定义

lDDT 的计算分几步,我尽量说简单点:

  1. 选定一组局部残基对(序列间隔 ≥ 6,且真实距离 < 15 Å)
  2. 分别计算模型和真实结构中这些残基对的距离
  3. 用 4 个阈值(0.5 Å、1 Å、2 Å、4 Å)去判断每个距离对是否"保留"
  4. 取这 4 个阈值的平均保留比例,作为最终分数

用代码表示会更直观。这是一个简化的实现:

import numpy as np

def compute_lDDT(model_coords, ref_coords,
                 min_seq_sep=6, max_dist=15.0,
                 thresholds=[0.5, 1.0, 2.0, 4.0]):
    n = len(model_coords)
    # 计算所有 Cα 原子对的距离矩阵
    model_dists = np.linalg.norm(
        model_coords[:, None] - model_coords, axis=2)
    ref_dists = np.linalg.norm(
        ref_coords[:, None] - ref_coords, axis=2)

    # 选出局部残基对:序列间隔 >= min_seq_sep,且真实距离 < max_dist
    i, j = np.triu_indices(n, k=min_seq_sep)
    mask = ref_dists[i, j] < max_dist
    i, j = i[mask], j[mask]

    if len(i) == 0:
        return 1.0

    total = len(i)
    scores = []
    for t in thresholds:
        kept = np.sum(
            np.abs(model_dists[i, j] - ref_dists[i, j]) < t)
        scores.append(kept / total)

    return np.mean(scores)

你看,代码里没有做全局叠加。lDDT 只关心"局部距离对"的偏差,而不是整体位置的偏差。

经验之谈:在实际使用中,我建议把 lDDT 和 RMSD 组合起来看。RMSD 高但 lDDT 高 → 模型可能整体偏移但局部可用;两个都低 → 模型基本不能用。

3.4 从 lDDT 到 pLDDT

传统 lDDT 有一个硬伤:它需要真实结构作为参考。没有真实结构,就算不了。

那 AlphaFold 是怎么做的呢?

它在训练的时候,让模型自己做了一件事——预测 lDDT。

具体来说:AlphaFold 在输出结构的同时,额外加了一个"lDDT 预测头"。这个模块会为每个残基输出一个分数,代表模型自己对这个残基局部构象准确性的预估。

因为它是"预测出来的 lDDT",所以叫 pLDDT(predicted lDDT)。

训练时,AlphaFold 用真实结构算出的 lDDT 分数作为标签,让模型学习怎么从自己的特征表示中,估算每个位置的局部可靠性。

这就引出了一个有意思的结论:

pLDDT 的本质:它不是外部指标,而是模型对自身预测质量的自评估。

下面这张图总结了从 lDDT 到 pLDDT 的演进逻辑:

lDDT → pLDDT 演进逻辑 传统评估(RMSD) lDDT 核心思想(局部距离比较) lDDT 计算(多阈值 + 局部距离) AlphaFold 改造(预测 lDDT) pLDDT 输出(逐残基置信度) 关键概念 • lDDT:局部距离比较 • 不依赖全局叠加 • 多阈值(0.5 / 1 / 2 / 4 Å) • pLDDT = predicted lDDT • 每个残基一个独立分数 • 模型的自评估结果

3.5 pLDDT 的数值含义

AlphaFold 输出的 pLDDT 范围是 0~100。分数越高,代表模型对这个残基的局部构象越自信。

根据 DeepMind 的建议,一般这么解读:

pLDDT 分数 置信度 实际含义
> 90 非常高 模型非常可靠,适合做精细分析(如侧链取向、结合位点)
70 – 90 较高 模型整体可靠,但局部可能有轻微偏差,需谨慎
50 – 70 较低 模型不可靠,不适合做细节分析,只能看大致折叠
< 50 非常低 模型不可信,对应区域通常为无序 loop 或固有无序蛋白

我曾经踩过一个坑:拿到一个 pLDDT 在 60~70 的区域,硬想在上面做对接分析,结果完全对不上。后来才意识到,这个分数段本质上是在说"我猜了个大概,你别太当真"。

重要提醒:pLDDT 低于 50 的区域,不代表结构是"错的",而是模型没有足够信息判断它应该长什么样。这些区域通常是物理上就无序的,不要强行用预测结构去解释功能。

3.6 使用建议

在实际项目中,我一般这样用 pLDDT:

  • > 90:直接拿来用,做分子对接、突变分析都 OK
  • 70–90:参考使用,重点看整体折叠,局部细节要验证
  • 50–70:只看二级结构和拓扑关系,不做定量分析
  • < 50:直接标注为"不确定性区域",不参与任何下游计算

一个小技巧:pLDDT 对"域内精度"和"域间相对位置"的敏感性不同。有时你看到整体 pLDDT 很高,但域间排列可能是错的。这时候要结合 PAE(预测对齐误差)一起看,两个指标互补。

嗯,关于 lDDT 和 pLDDT 的定义,到这里就讲清楚了。核心就是一句话:pLDDT 是模型对自身局部结构质量的自评估,分数越高,局部构象越可信。