LangueFR
Français
English
Retour au sommaire du cours

Recherche, ranking et recommandation

Trouver un document, ordonner des résultats, suggérer un article : ces trois problèmes partagent la même architecture — réduire des millions de candidats à quelques dizaines, puis les ordonner finement. C'est l'un des domaines applicatifs les plus répandus de la data science, et celui où l'écart entre l'évaluation hors ligne et la réalité est le plus grand.

1. L'architecture commune

le pipeline en trois étages
1. RÉCUPÉRATION (retrieval)      millions → quelques centaines de candidats
   contrainte : quelques millisecondes → modèles simples et INDEXABLES
   moyens : BM25, index vectoriel ANN (module 22), filtres métier, règles

2. CLASSEMENT (ranking)          centaines → dizaines, ordonnées finement
   contrainte : dizaines de millisecondes → modèle riche autorisé
   moyens : gradient boosting de ranking, cross-encoder, réseau profond

3. RE-CLASSEMENT MÉTIER          ce qui est réellement affiché
   diversité, fraîcheur, stocks, marges, équité entre fournisseurs,
   exclusions réglementaires, dé-duplication

Cette séparation est imposée par la latence : on ne peut pas évaluer un modèle coûteux sur un million d'items en 50 ms. Elle a une conséquence souvent négligée : la qualité du système est plafonnée par l'étage de récupération. Un excellent modèle de classement ne peut pas remonter un item que la récupération n'a pas proposé. Quand un système déçoit, c'est donc le rappel de l'étage 1 qu'il faut mesurer en premier — et c'est une mesure simple : sur un jeu de questions annotées, quelle proportion des bons items figure dans les 200 candidats ?

2. Recherche : lexical, sémantique, hybride

Le module 22 présente la recherche dans le cadre du RAG ; les mêmes briques valent pour une recherche destinée à des humains. BM25 (module 18) reste une référence redoutable : il trouve immédiatement les références exactes, les codes produit et les termes rares. La recherche vectorielle gère les reformulations et les synonymes mais échoue sur ces mêmes termes rares, qu'elle n'a souvent jamais vus à l'entraînement.

La combinaison par fusion de rangs réciproques est robuste et sans paramètre à régler :

\[ \text{RRF}(d) = \sum_{s \in \text{systèmes}} \frac{1}{k + \text{rang}_s(d)}, \qquad k \approx 60 \]
pourquoi fusionner les RANGS plutôt que les scores
BM25 renvoie des scores de 0 à 30, le cosinus de -1 à 1 : les additionner
n'a aucun sens, et les normaliser suppose de connaître leurs distributions.
Les RANGS, eux, sont directement comparables.

document A : rang 1 en BM25, rang 8 en vectoriel → 1/61 + 1/68 = 0,0311
document B : rang 3 en BM25, rang 2 en vectoriel → 1/63 + 1/62 = 0,0320  ← devant
Un document bien classé par LES DEUX systèmes remonte, même sans être premier.

Le reste du travail se joue sur la requête et les métadonnées : analyse de la requête (correction orthographique, expansion par synonymes, détection d'intention), filtres (catégorie, date, disponibilité) et gestion des requêtes sans résultat, qui sont le principal motif d'abandon. Sur un corpus technique, un simple dictionnaire de synonymes métier rapporte souvent plus qu'un changement de modèle d'embedding.

3. Learning to rank

Classer n'est pas prédire une valeur : seul l'ordre compte, et les premières positions comptent bien plus que les suivantes — personne ne consulte la page 3. Trois formulations :

  • Pointwise — prédire un score de pertinence par item, indépendamment des autres. Simple, mais optimise la mauvaise chose : une erreur en position 1 et une erreur en position 50 pèsent pareil.
  • Pairwise — apprendre, pour chaque paire, lequel doit passer devant (RankNet, LambdaRank). Beaucoup plus proche de l'objectif réel.
  • Listwise — optimiser directement une métrique de liste comme le NDCG. LambdaMART — gradient boosting (module 14) dont les gradients sont pondérés par le gain de NDCG qu'apporterait l'échange de deux documents — reste l'état de l'art pratique, et est disponible directement dans LightGBM et XGBoost (objective="lambdarank").

La métrique de référence est le NDCG, qui pondère la pertinence par une remise logarithmique sur le rang :

\[ \text{DCG}@k = \sum_{i=1}^{k}\frac{2^{\text{rel}_i}-1}{\log_2(i+1)}, \qquad \text{NDCG}@k = \frac{\text{DCG}@k}{\text{IDCG}@k} \]
NDCG, calculé à la main
pertinences réelles des 5 résultats affichés : [3, 0, 2, 3, 1]   (0 = inutile, 3 = parfait)

DCG = (2³-1)/log₂(2) + (2⁰-1)/log₂(3) + (2²-1)/log₂(4) + (2³-1)/log₂(5) + (2¹-1)/log₂(6)
    =    7/1,00     +      0/1,58     +     3/2,00     +     7/2,32     +     1/2,58
    = 7 + 0 + 1,5 + 3,02 + 0,39 = 11,91

classement IDÉAL : [3, 3, 2, 1, 0] → IDCG = 7 + 4,42 + 1,5 + 0,43 + 0 = 13,35
NDCG = 11,91 / 13,35 = 0,89

La normalisation par le classement idéal rend les requêtes COMPARABLES entre elles,
ce que ne permettent ni la précision@k ni le MRR.

Les variables d'un modèle de ranking se rangent en trois familles : caractéristiques de la requête (longueur, intention, langue), de l'item (popularité, fraîcheur, qualité, prix) et surtout de l'appariement requête-item (scores BM25 par champ, similarité d'embedding, correspondances exactes, historique de clics sur cette paire). Ce sont ces dernières qui portent l'essentiel du signal.

4. Données de clics et biais de position

Les clics sont la source d'étiquettes la plus abondante — et la plus traîtresse. Un item est cliqué parce qu'il est pertinent, mais surtout parce qu'il était affiché en première position. Les études d'oculométrie montrent un taux de clic en première position cinq à dix fois supérieur à celui de la cinquième, à pertinence égale.

les biais des journaux de clics
Biais de position    les premiers résultats sont bien plus cliqués, à pertinence égale
Biais de sélection   on n'observe QUE ce qui a été affiché par la politique en place :
                     les bons items jamais montrés restent invisibles pour toujours
Biais de confiance   les utilisateurs font confiance au système et cliquent "par défaut"
Absence de négatif   un non-clic ne signifie pas "non pertinent" : peut-être non VU
                     (d'où l'importance de journaliser ce qui a été réellement affiché)

Entraîner naïvement sur les clics revient donc à apprendre le classement actuel et à le figer : le système se confirme lui-même indéfiniment. Les remèdes : la pondération inverse de propension — chaque clic est pondéré par l'inverse de la probabilité d'examen à cette position, ce qui rend son poids comparable quelle que soit la place occupée —, l'estimation de cette courbe de propension par permutations aléatoires contrôlées sur une petite fraction du trafic, et l'utilisation de signaux moins biaisés que le clic brut : temps de lecture, achat, ou retour en arrière rapide, qui est un signal négatif fort.

5. Filtrage collaboratif et factorisation

L'intuition fondatrice : des utilisateurs qui ont aimé les mêmes choses aimeront les mêmes choses ensuite. Aucune connaissance du contenu n'est nécessaire — seule la matrice d'interactions compte, ce qui est à la fois la force (ça marche sur n'importe quel catalogue) et la faiblesse (ça ne marche pas sur un item neuf).

La factorisation matricielle approche cette matrice très creuse \(R\) par un produit de faible rang \(R \approx P Q^\top\), où chaque utilisateur et chaque item sont représentés par un vecteur latent de dimension \(k\) (typiquement 32 à 256) :

\[ \hat r_{ui} = \mu + b_u + b_i + p_u^\top q_i, \qquad \min \sum_{(u,i)\in\mathcal{K}} \big(r_{ui}-\hat r_{ui}\big)^2 + \lambda\big(\|p_u\|^2+\|q_i\|^2\big) \]
ce que chaque terme capture
μ        la moyenne globale                    (tout le monde note autour de 3,5)
b_u      le biais UTILISATEUR                  (cet utilisateur note systématiquement bas)
b_i      le biais ITEM                          (ce film plaît à tout le monde)
p_uᵀq_i  l'affinité SPÉCIFIQUE                 (cet utilisateur aime CE genre)

Les seuls biais expliquent souvent la moitié du signal : les inclure avant toute
sophistication est le meilleur premier pas.

C'est l'idée d'approximation de rang faible du module 8, adaptée au cas où la plupart des entrées sont manquantes : on n'ajuste que sur les interactions observées, d'où l'usage de la descente de gradient stochastique ou des moindres carrés alternés (ALS) plutôt que d'une SVD classique, qui exigerait une matrice complète.

6. Retour implicite

L'absence n'est pas un rejet. Dans la plupart des systèmes réels, on n'a pas de notes mais des vues, clics et achats — uniquement des signaux positifs. Traiter tout le reste comme des zéros est faux : l'utilisateur n'a probablement jamais vu l'item. Sur un catalogue d'un million de références, un utilisateur en a vu quelques centaines ; les 999 000 autres ne sont pas des rejets.

Deux réponses. Les méthodes à confiance pondérée (ALS implicite) traitent les non-interactions comme des négatifs de faible poids, et les interactions répétées comme des positifs de poids croissant. Ou bien l'on change d'objectif : BPR (Bayesian Personalised Ranking) n'apprend pas une valeur mais un ordre — il maximise la probabilité qu'un item vu passe devant un item tiré au hasard. L'échantillonnage de ces négatifs est le détail d'implémentation qui décide de la qualité du résultat : tirer uniformément donne des négatifs trop faciles (l'item tiré est évidemment sans intérêt), tirer parmi les items populaires donne des négatifs informatifs.

7. Two-tower et recommandation séquentielle

L'architecture à deux tours est devenue le standard industriel de l'étage de récupération : un réseau encode l'utilisateur et son contexte, un autre encode l'item, et la pertinence est le produit scalaire des deux vecteurs.

pourquoi cette architecture précisément
   utilisateur + contexte              item + métadonnées
         │                                    │
    [ tour user ]                        [ tour item ]
         │                                    │
      vecteur u  ─────── produit ────────  vecteur i
                        scalaire

  L'astuce : les vecteurs d'items se calculent HORS LIGNE et s'indexent dans une
  base vectorielle (module 22). Une requête en ligne ne demande qu'un encodage
  utilisateur + une recherche ANN. On obtient la souplesse d'un réseau avec la
  latence d'un index — impossible avec un modèle qui croiserait user et item
  dès la première couche.

La recommandation séquentielle (GRU4Rec, SASRec, BERT4Rec) modélise l'historique comme une séquence et prédit l'action suivante — c'est un transformer appliqué à des identifiants d'items (module 16). Elle capture l'intention du moment, ce que la factorisation matricielle, purement statique, ignore complètement : quelqu'un qui vient de consulter trois perceuses n'est pas dans le même état que sa moyenne historique.

Un point à connaître : au-delà du prototype, les gains viennent moins de l'architecture que des variables et de la fraîcheur des données. Un modèle simple réentraîné toutes les heures bat souvent un modèle sophistiqué réentraîné chaque semaine.

8. Évaluer : hors ligne et en ligne

métriques hors ligne
Précision@k / Rappel@k   les basiques, faciles à interpréter
MAP, MRR                 position du premier élément pertinent
NDCG@k                   pertinence graduée avec remise logarithmique : la référence
Couverture (catalogue)   quelle part du catalogue est réellement recommandée ?
Diversité intra-liste    les k items proposés se ressemblent-ils trop ?
Nouveauté / sérendipité  recommande-t-on autre chose que les best-sellers ?
Équité                   entre fournisseurs, auteurs, catégories (module 27)

Le découpage des données mérite une attention particulière : un découpage aléatoire est une fuite (module 12), puisqu'il permet d'entraîner sur le futur d'un utilisateur pour prédire son passé. Il faut découper par date et évaluer sur la période suivante — ou, à défaut, exclure les dernières interactions de chaque utilisateur (leave-last-out).

Le décalage hors ligne / en ligne

C'est la caractéristique la plus déroutante du domaine : les gains mesurés hors ligne se traduisent mal en gains réels. Trois raisons. Les données historiques ont été produites par l'ancien système, donc un nouveau modèle qui propose des items jamais affichés est évalué comme s'il se trompait — alors qu'on ne sait tout simplement pas. Les métriques hors ligne mesurent la reproduction du passé, pas la satisfaction. Et l'effet d'un changement met parfois des semaines à se manifester (fidélité, lassitude), bien au-delà de la durée d'un test. La conclusion pratique : l'évaluation hors ligne sert à filtrer les candidats et à éviter les régressions, mais seule une expérience en ligne (module 9) tranche — avec des métriques de garde-fou pour détecter les effets pervers.

9. Démarrage à froid, popularité, boucles

  • Démarrage à froid — un nouvel utilisateur ou un nouvel item n'a pas d'historique, donc pas de vecteur latent. Solutions : s'appuyer sur le contenu (attributs, embedding du texte ou de l'image, module 18), recommander par popularité contextualisée, poser deux ou trois questions d'amorçage, ou exploiter un bandit pour explorer rapidement (module 24).
  • Biais de popularité — les modèles entraînés sur des interactions amplifient les items déjà populaires, ce qui pénalise la longue traîne et appauvrit le catalogue utile. Correctifs : échantillonnage négatif pondéré par la popularité, pénalisation explicite dans la fonction de perte, ou contrainte de couverture au re-classement.
  • Boucle de rétroaction — le système ne voit que les conséquences de ses propres recommandations, ce qui rétrécit progressivement l'exposition (modules 24 et 26). Les parades : conserver une part d'exploration aléatoire, maintenir un groupe témoin permanent, et surveiller la diversité dans le temps comme métrique de santé.
  • Contraintes système — latence, coût d'indexation, fraîcheur des embeddings, cohérence entre les variables d'entraînement et celles servies en ligne (module 26). C'est là, plus que dans le modèle, que se situent les vraies difficultés d'ingénierie.

Ce qu'il faut retenir du module

  • Architecture en trois étages ; la qualité est plafonnée par le rappel de la récupération.
  • Hybride lexical + vectoriel par fusion de rangs : robuste et sans réglage.
  • LambdaMART reste l'état de l'art pratique du ranking ; le NDCG est la métrique de référence, et sa normalisation rend les requêtes comparables.
  • Les clics sont biaisés par la position : corriger par propension, sinon le système fige son propre classement.
  • La factorisation matricielle est une approximation de rang faible sur données manquantes ; les termes de biais portent la moitié du signal.
  • En retour implicite, apprendre un ordre (BPR) plutôt qu'une valeur, et soigner l'échantillonnage des négatifs.
  • Two-tower pour la récupération, transformer séquentiel pour l'intention du moment.
  • Découper par date, et ne conclure qu'en ligne : le décalage hors ligne/en ligne est structurel.

BM25NDCGLambdaMARTFactorisationTwo-towerCold start