Préparer les données : features, groupes, pièges
De la table au dataset
Le feedback vit en lignes « un candidat = une ligne ». L'entraînement LTR veut des groupes (les candidats d'une même requête ensemble) :
requête L1 : [candidat A (scores…, selected=1), candidat B (scores…, 0), candidat C (…, 0)]
requête L2 : [candidat D (…, 1), candidat E (…, 0)]
...
On regroupe par request_line_id, on trie, et on note la taille de chaque groupe (l'API LTR de la plupart des libs veut un tableau group = [3, 2, ...]). Les features par candidat : les cinq sous-scores + business_score + semantic_score. Le label : was_selected (après application de was_overridden_by_user — la correction humaine écrase le choix initial).
Les pièges qui coulent un reranker (tu les connais déjà)
Ce sont les fuites du cours ML classique, version ranking :
- la fuite du
final_score: l'inclure comme feature = tricher — c'est déjà la sortie du système actuel qu'on veut remplacer. On entraîne sur les sous-scores bruts, pas sur l'agrégat ; - la fuite du rang :
rankreflète l'ordre actuel — l'inclure apprend au modèle à copier le système existant. Feature interdite ; - le déséquilibre extrême : 1 positif pour N négatifs par groupe (normal en ranking) — les métriques d'accuracy mentent (cours ML éval !), on évalue en match@1/MRR ;
- le split par GROUPE, jamais par ligne : deux candidats de la même requête ne doivent PAS finir l'un en train, l'autre en test (le modèle « verrait » la requête). On split sur
request_line_id— le train/test sacré, appliqué au bon grain ; - le biais de sélection : on n'a du feedback que sur les lignes passées en deep match (les cas durs) — le reranker apprend sur une population biaisée. À garder en tête pour l'interprétation.
Le volume : combien faut-il ?
Question honnête à se poser AVANT d'entraîner : SELECT count(distinct request_line_id) FROM product_match_feedback WHERE was_selected. Sous quelques centaines de groupes, un modèle appris ne battra pas des poids bien réglés — le LTR a faim de données. La bonne démarche : commencer par mesurer le volume disponible, et si insuffisant, la conclusion utile est « continuer à collecter » (le feedback grossit à chaque correction) — un résultat négatif honnête vaut mieux qu'un modèle sur-ajusté sur 50 exemples.
Pourquoi exclure final_score des features du reranker ?