L'analyse des prédictions de structures protéiques générées par AlphaFold repose sur un système rigoureux d'évaluaiton de la confiance. Ce cadre multidimensionnel intègre le score pLDDT, la matrice d'erreur d'alignement prédite (PAE) et le score pTM. Ces métriques permettent de quantifier la fiabilité des coordonnées atomiques prédites, offrant ainsi aux chercheurs des critères objectifs pour interpréter les modèles tridimensionnels.
Le score pLDDT : Évaluation locale de la précision
Le predicted Local Distance Difference Test (pLDDT) est l'indicateur principal pour estimer la fiabilité résidu par résidu. Variant de 0 à 100, un score élevé indique une grande certitude sur la position locale des atomes. Ce mécanisme s'insipre du lDDT, qui évalue la préservation des distances interatomiques sans nécessiter de superposition rigide des structures.
Fondements mathématiques du lDDT
Le calcul du lDDT compare les matrices de distances des structures prédites et natives. Seules les paires d'atomes proches dans la structure réelle (généralement sous un seuil de 15 Å) sont prises en compte.
import numpy as np
def calculate_local_distance_diff(pred_coords, true_coords, valid_mask, dist_cutoff=15.0, per_residue=False):
# Calcul des matrices de distances euclidiennes
diff_true = true_coords[:, :, None, :] - true_coords[:, None, :, :]
dist_true = np.sqrt(np.sum(diff_true**2, axis=-1) + 1e-10)
diff_pred = pred_coords[:, :, None, :] - pred_coords[:, None, :, :]
dist_pred = np.sqrt(np.sum(diff_pred**2, axis=-1) + 1e-10)
# Masque des paires à évaluer (distance réelle < cutoff et non-diagonales)
pair_mask = (dist_true < dist_cutoff).astype(np.float32)
pair_mask *= valid_mask[:, :, None] * valid_mask[:, None, :]
np.fill_diagonal(pair_mask[0], 0) # Exclure les auto-interactions
# Différences absolues et binning
abs_diff = np.abs(dist_true - dist_pred)
local_score = 0.25 * (
(abs_diff < 0.5).astype(np.float32) +
(abs_diff < 1.0).astype(np.float32) +
(abs_diff < 2.0).astype(np.float32) +
(abs_diff < 4.0).astype(np.float32)
)
# Normalisation par le nombre de paires valides
axes = (-1,) if per_residue else (-2, -1)
valid_counts = np.sum(pair_mask, axis=axes) + 1e-10
final_score = np.sum(pair_mask * local_score, axis=axes) / valid_counts
return final_score
Architecture de prédiction et stratégie de binning
Dans AlphaFold, une tête de réseau spécifique transforme les représentations structurales en logits. Ces logits sont ensuite convertis en distribution de probabilité via une fonction softmax pour obtenir une valeur continue.
import scipy.special
def extract_plddt_from_logits(logits_tensor):
num_intervals = logits_tensor.shape[-1]
interval_width = 1.0 / num_intervals
interval_midpoints = np.arange(0.5 * interval_width, 1.0, interval_width)
probabilities = scipy.special.softmax(logits_tensor, axis=-1)
expected_lddt = np.sum(probabilities * interval_midpoints, axis=-1)
return expected_lddt * 100.0 # Conversion en pourcentage
Interprétation des niveaux de confiance
| Intervalle pLDDT | Niveau de confiance | Interprétation structurale |
|---|---|---|
| 90 - 100 | Très élevé | Coordonnées du squelette peptidique hautement fiables |
| 70 - 90 | Élevé | Prédiction globalement correcte |
| 50 - 70 | Faible | Régions à vérifier, potentielles erreurs locales |
| 0 - 50 | Très faible | Régions intrinsèquement désordonnées ou modèle incorrect |
Optimisation lors de l'entraînement
Le modèle est optimisé en minimisant l'entropie croisée entre la distribution prédite et les valeurs réelles de lDDT calculées sur les atomes Cα.
def compute_confidence_loss(model_outputs, data_batch, num_bins=50):
pred_atoms = model_outputs['final_atom_positions']
gt_atoms = data_batch['all_atom_positions']
atom_mask = data_batch['all_atom_mask']
ca_idx = 1 # Index de l'atome Cα
true_lddt = calculate_local_distance_diff(
pred_coords=pred_atoms[None, :, ca_idx, :],
true_coords=gt_atoms[None, :, ca_idx, :],
valid_mask=atom_mask[None, :, ca_idx:ca_idx+1].astype(np.float32),
dist_cutoff=15.0,
per_residue=True
)
# Discrétisation et encodage one-hot
bin_indices = np.floor(true_lddt * num_bins).astype(np.int32)
bin_indices = np.clip(bin_indices, 0, num_bins - 1)
one_hot_targets = np.eye(num_bins)[bin_indices]
# Calcul de la perte
pred_logits = model_outputs['predicted_lddt']['logits']
probs = scipy.special.softmax(pred_logits, axis=-1)
ce_loss = -np.sum(one_hot_targets * np.log(probs + 1e-8), axis=-1)
ca_mask = atom_mask[:, ca_idx].astype(np.float32)
return np.sum(ce_loss * ca_mask) / (np.sum(ca_mask) + 1e-8)
Analyse de la matrice PAE (Predicted Aligned Error)
La matrice PAE est un tableau symétrique de taille N×N (où N est le nombre de résidus). Chaque élément (i, j) estime l'erreur de distance attendue entre les résidus i et j lorsque la structure est alignée de manière optimale. Elle est cruciale pour comprendre l'organisation globale et les interfaces.
Calcul et propriétés de la PAE
La PAE est dérivée des représentations par paires du réseau de neurones. Les logits sont convertis en valeurs d'erreur attendues via une moyenne pondérée par les proabbilités.
def get_interval_centers(breakpoints):
step = breakpoints[1] - breakpoints[0]
centers = breakpoints + step / 2.0
return np.append(centers, centers[-1] + step)
def derive_pae_matrix(error_logits, breakpoints):
confidence_dist = scipy.special.softmax(error_logits, axis=-1)
interval_centers = get_interval_centers(breakpoints)
expected_error = np.sum(confidence_dist * interval_centers, axis=-1)
return expected_error
Les caractéristiques notables de cette matrice incluent sa symétrie (PAE[i,j] = PAE[j,i]), une diagonale nulle (erreur nulle d'un résidu avec lui-même), et des valeurs typiquement bornées entre 0 et 30 Å.
Extraction d'informations biologiques
L'analyse de la PAE permet d'identifier les domaines structuraux indépendants (blocs de faibles erreurs) et les régions charnières ou désordonnées (fortes erreurs). Dans le cas de complexes multiprotéiques, elle révèle la fiabilité des interfaces d'interaction.
def process_pae_data(pae_json_data, protein_sequence):
pae_mat = np.array(pae_json_data['predicted_aligned_error'])
# Masque des régions hautement fiables
reliable_mask = pae_mat < 8.0
# Détection des frontières de domaines
domain_limits = find_structural_domains(pae_mat, len(protein_sequence))
# Score de confiance global (moyenne de la matrice)
global_score = np.mean(pae_mat)
return {
'matrix': pae_mat,
'reliable_regions': reliable_mask,
'domain_boundaries': domain_limits,
'global_confidence': global_score
}
def find_structural_domains(pae_mat, seq_length):
limits = []
window = 15
for i in range(window, seq_length - window):
# Comparaison des erreurs intra-domaine et inter-domaine
intra_err = np.mean(pae_mat[i-window:i, i-window:i])
inter_err = np.mean(pae_mat[i-window:i, i:i+window])
if inter_err > 2.5 * intra_err:
limits.append(i)
return limits
Le score pTM et l'interface ipTM
Le predicted TM-score (pTM) évalue la similarité topologique globale de la structure prédite par rapport à une structure de référence théorique. Il est calculé à partir de la matrice PAE et intègre une normalisation dépendante de la longueur de la protéine.
Mécanisme de calcul du pTM
Le score TM original utilise un paramètre $d_0$ qui s'adapte à la taille de la protéine pour éviter les biais envers les grandes structures. AlphaFold adapte cette formule en calculant l'espérance mathématique basée sur les distributions de la PAE.
def estimate_predicted_tm(error_logits, breakpoints, res_weights=None, chain_ids=None, is_interface=False):
if res_weights is None:
res_weights = np.ones(error_logits.shape[0])
interval_centers = get_interval_centers(breakpoints)
num_res = int(np.sum(res_weights))
adjusted_res = max(num_res, 19)
# Paramètre de normalisation dépendant de la longueur
d0 = 1.24 * (adjusted_res - 15) ** (1.0 / 3.0) - 1.8
probs = scipy.special.softmax(error_logits, axis=-1)
# Contribution de chaque intervalle au score TM
tm_contributions = 1.0 / (1.0 + (interval_centers / d0) ** 2)
expected_tm_terms = np.sum(probs * tm_contributions, axis=-1)
# Gestion des masques (chaînes et interfaces)
pair_mask = np.ones((num_res, num_res), dtype=bool)
if is_interface and chain_ids is not None:
pair_mask = (chain_ids[:, None] != chain_ids[None, :])
expected_tm_terms *= pair_mask
# Pondération et normalisation finale
pair_weights = pair_mask * (res_weights[:, None] * res_weights[None, :])
norm_weights = pair_weights / (np.sum(pair_weights, axis=-1, keepdims=True) + 1e-8)
alignment_scores = np.sum(expected_tm_terms * norm_weights, axis=-1)
best_score = np.max(alignment_scores * res_weights)
return float(best_score)
Échelle d'interprétation du pTM
| Valeur pTM | Qualité topologique | Signification |
|---|---|---|
| > 0.8 | Excellent | Topologie globale très proche de l'état natif |
| 0.7 - 0.8 | Bon | Repliement global correct |
| 0.5 - 0.7 | Moyen | Architecture générale préservée, détails locaux incertains |
| < 0.5 | Faible | Repliement probablement incorrect |
Pour les complexes, le score ipTM (interface pTM) se concentre exclusivement sur les paires de résidus appartenant à des chaînes différentes, offrant une métrique dédiée à la qualité des interfaces d'assemblage.
Intégration des métriques et format de sortie
L'évaluation complète d'un modèle AlphaFold nécessite la corrélation de ces trois indicateurs. Le pLDDT informe sur la précision locale, la PAE sur l'organisation relative des domaines, et le pTM sur la justesse du repliement global.
Corrélation avec les données expérimentales
Les études de benchmarking ont démontré que ces scores prédictifs sont fortement corrélés avec les métriques expérimentales classiques comme le RMSD (Root Mean Square Deviation).
| pLDDT | RMSD moyen observé | Caractéristiques structurales |
|---|---|---|
| 90 - 100 | < 1.0 Å | Cœur hydrophobe, hélices alpha et feuillets bêta rigides |
| 70 - 90 | 1.0 - 2.0 Å | Boucles structurées, surfaces protéiques |
| 50 - 70 | 2.0 - 4.0 Å | Régions flexibles, extrémités N/C-terminales |
| 0 - 50 | > 4.0 Å | Désordre intrinsèque, absence de structure fixe |
Format de sortie standardisé
Pour faciliter l'intégration dans les pipelines bioinformatiques, AlphaFold génère des fichiers JSON récapitulant ces métriques, permettant un filtrage automatisé des modèles de haute qualité.
{
"global_metrics": {
"ptm_score": 0.89,
"iptm_score": 0.94,
"max_pae": 31.75
},
"residue_metrics": {
"plddt_scores": [92.4, 95.1, 88.3, 45.2, 76.8],
"confidence_labels": ["H", "H", "M", "D", "M"]
},
"pairwise_metrics": {
"pae_matrix": [[0.0, 1.5, 4.2], [1.5, 0.0, 3.1], [4.2, 3.1, 0.0]]
}
}
Ce format de sortie structuré permet l'automatisation du filtrage des modèles dans les pipelines de découverte de médicaments et d'ingénierie des protéines.