Étendre la question avant le retrieval pour mieux identifier les termes à rechercher.
Introduction
La phase de retrieval (recherche de documents qui offrent le contexte pertinent pour une requête) est au cœur de l’architecture RAG (Retrieval-Augmented Generation). Si cette étape n’extrait pas le contexte pertinent, le modèle de langage en aval risque de générer une réponse incomplète ou une hallucination. La robustesse globale du système dépend donc en grande partie de la précision de cette première brique.
Pourtant, faire du retrieval ne date pas de l’avènement des grands modèles de langage. Il s’agit du cœur historique de la recherche d’information dans les moteurs de recherche, un domaine déjà éprouvé depuis des décennies par les ingénieurs.
Plutôt que de réinventer la roue, la conception de systèmes RAG gagne à capitaliser sur cet héritage. Cet article explore dans quelle mesure une expansion de requête contrôlée par un thésaurus SKOS améliore la récupération et le classement des documents pertinents par BM25, comparativement à une requête non enrichie.
Comment estimer la pertinence d’un document pour une requête ?
Similarité
Afin de sélectionner des documents qui contiennent le bon contexte, le système doit estimer dans quelle mesure chacun répond à l’intention exprimée dans la requête de l’utilisateur. Cette intention ne peut pas être observée directement. La recherche d’information l’approche donc à partir de scores de similarité entre la requête et les documents.
Le concept de similarité dans la recherche d’informations peut être divisé en deux catégories :
Similarité lexicale : Elle mesure la similarité entre la requête et un document à partir des mots-clés ou expressions identiques qu’ils partagent.
Similarité sémantique : Elle mesure la similarité entre la requête et un document à partir du sens qu’ils partagent, même lorsque les mots ou expressions employés sont différents. Elle est notamment mise en œuvre par la recherche vectorielle, très couramment utilisée dans les systèmes RAG modernes.
On pourrait alors être tenté de considérer que la recherche vectorielle suffit à elle seule. Mais ce n’est pourtant pas toujours le cas. La recherche lexicale reste particulièrement efficace lorsque l’on doit retrouver précisément le nom d’une personne, une référence de contrat, un numéro de document, un code d’erreur, un identifiant technique, un vocabulaire métier très spécifique, un nom de produit, un acronyme ou tout autre terme qui ne doit pas être manqué. Certains termes ont donc une forte valeur discriminante et nécessitent une recherche lexicale.
Décalage lexical
Cependant, la similarité lexicale souffre du décalage lexical. Il survient lorsque le vocabulaire utilisé dans la requête de l’utilisateur diffère de celui employé dans les documents pertinents, alors qu’ils font référence au même concept. Ce décalage lexical peut engendrer un biais dans le calcul de la similarité entre la requête de l’utilisateur et le document.
query ="Comment indemniser un assuré après un accident de voiture ?"
Considérons maintenant un premier document pertinent pour cette requête :
Document_A =""" En cas de sinistre automobile responsable, l’assureur procède au règlement des dommages subis par l’assuré conformément aux garanties prévues au contrat. Le montant de la prestation versée dépend notamment de l’évaluation du préjudice et des conditions d’indemnisation applicables. """
Ici, la requête et le document sont sémantiquement liés, mais syntaxiquement différents. La requête ne contient pas les termes exacts du document, à l’exception du terme l’assuré. Il s’agit d’un exemple classique de problème de décalage lexical.
Considérons maintenant un second document, lexicalement proche de la requête mais non pertinent :
Document_B =""" L’assuré doit déclarer son accident de voiture dans les meilleurs délais. L’accident peut être déclaré depuis l’espace personnel de l’assuré ou auprès de son agence d’assurance. Une confirmation de la déclaration est ensuite adressée à l’assuré. """
Document B contient les termes de la requête, mais il ne répond pas à l’intention de l’utilisateur, qui cherche à être indemnisé. Un algorithme de recherche lexicale est susceptible de mieux classer Document B que Document A en raison de sa plus forte correspondance lexicale avec la requête.
Introduction à l’algorithme de BM25
Parmi les algorithmes de recherche lexicale, BM25 est l’un des plus utilisés. Il attribue un score de pertinence à chaque document en fonction des termes de la requête qu’il contient.
Avant d’effectuer une recherche, on commence par extraire le texte des documents et le découper en tokens, puis par construire un index inversé. Cette structure associe chaque terme aux documents qui le contiennent. Elle conserve aussi le nombre d’apparitions de chaque terme dans un document, le nombre de documents qui contiennent ce terme, le nombre total de documents, la longueur de chaque document et la longueur moyenne des documents du corpus.
Lorsqu’une question arrive, elle est elle aussi découpée en tokens. Chaque token est ensuite utilisé pour interroger l’index et retrouver directement les documents qui le contiennent.
Pour chaque token de la requête, BM25 calcule un score à partir des statistiques de l’index. Le score BM25 final d’un document correspond à la somme des scores obtenus pour les différents tokens de la requête.
Les documents sont ensuite classés selon leur score BM25.
Figure 1: Étapes de la recherche lexicale avec BM25.
\(n(t)\) : le nombre de documents contenant le terme \(t\) ;
\(\operatorname{IDF}(t)\) : le poids associé à la rareté du terme \(t\) dans le corpus.
Plus \(n(t)\) est faible, plus le terme est rare et plus son poids est élevé.
Dans le code qui suit, BM25S utilise ses valeurs par défaut \(k_1 = 1.5\) et \(b = 0.75\).
Comment BM25 corrige-t-il les biais de la recherche lexicale ?
Le score BM25 repose principalement sur trois éléments : la fréquence du terme dans le document, sa rareté dans le corpus et la longueur du document. Chacun apporte un signal de pertinence tout en corrigeant un biais possible.
La fréquence du terme \(f(t,D)\) indique combien de fois le terme \(t\) apparaît dans le document \(D\). C’est un indice de pertinence, mais répéter cent fois le même mot ne doit pas donner un avantage cent fois plus grand. Le paramètre \(k_1\) permet donc de saturer progressivement le gain apporté par les répétitions successives.
La rareté du terme \(\operatorname{IDF}(t)\) augmente le poids des termes présents dans peu de documents du corpus. Un code d’erreur ou un acronyme rare distingue davantage un résultat qu’un mot présent dans presque tous les documents.
La longueur du document \(\frac{|D|}{\operatorname{avgdl}}\) compare la longueur du document à la longueur moyenne des documents du corpus. Sans cette correction, un document très long aurait davantage de chances de contenir les mots recherchés et pourrait être artificiellement favorisé. Le paramètre \(b\) contrôle l’importance de cette normalisation.
Retrieval lexical avec BM25S
documents = {"Document A": Document_A,"Document B": Document_B,}df = pd.DataFrame( documents.items(), columns=["document", "text"])# Le corpus est transformé une seule fois, avant les recherches utilisateur.corpus_tokens = bm25s.tokenize( df["text"].tolist(), stopwords="fr", show_progress=False,)corpus = df.to_dict(orient="records")retriever = bm25s.BM25(corpus=corpus)retriever.index(corpus_tokens, show_progress=False)# BM25S cherche dans tout l'index, puis retourne seulement les top_k meilleurs documents.def bm25_retrieval(query, retriever, top_k=2): query_tokens = bm25s.tokenize( query, stopwords="fr", show_progress=False, ) results = retriever.retrieve( query_tokens, k=top_k, show_progress=False, ) retrieval_results = pd.DataFrame(results.documents[0].tolist()) retrieval_results["bm25_score"] = results.scores[0] retrieval_results["bm25_rank"] =range(1, len(retrieval_results) +1 )return retrieval_resultsretrieval_results = bm25_retrieval(query, retriever, top_k=2)
Table 1: Résultats de la recherche lexicale avec BM25
Document
Contenu
Score BM25
Rang
Document B
L’assuré doit déclarer son accident de voiture dans les meilleurs délais. L’accident peut être déclaré depuis l’espace personnel de l’assuré ou auprès de son agence d’assurance. Une confirmation de la déclaration est ensuite adressée à l’assuré.
0.801
1
Document A
En cas de sinistre automobile responsable, l’assureur procède au règlement des dommages subis par l’assuré conformément aux garanties prévues au contrat. Le montant de la prestation versée dépend notamment de l’évaluation du préjudice et des conditions d’indemnisation applicables.
0.072
2
Conséquences du décalage lexical dans un système RAG
Ce résultat met en évidence une limite inhérente à la recherche lexicale; le score ne peut exploiter que les termes présents dans la requête et dans les documents.
Ce décalage lexical affecte deux propriétés essentielles du retrieval :
Le rappel (recall) diminue lorsque des documents pertinents ne contiennent pas les termes employés dans la requête et ne sont donc pas récupérés parmi les premiers résultats.
La précision (precision) diminue lorsque des documents qui partagent les mots de la requête sont classés haut sans répondre réellement au besoin de l’utilisateur.
Pour palier ce problème, nous allons donc faire recour à une solution bien connue: l’expansion de requête.
L’expansion de requête.
C’est quoi un Thésaurus ?
L’expansion de requête consiste à enrichir la formulation de l’utilisateur avec des termes susceptibles d’apparaître dans les documents pertinents.
Thésaurus
Un thésaurus organise les concepts d’un domaine et les termes qui les désignent. Il sert à normaliser le vocabulaire, relier différentes formulations d’une même notion et améliorer la recherche d’information.
Concept
Un concept est une idée ou une notion que l’on cherche à représenter. Ce n’est pas un mot. Les mots et les expressions sont les termes employés pour nommer cette notion dans une langue ou un contexte donné.
Dans un thésaurus, un terme préféré est le terme retenu pour désigner un concept. Les autres formulations peuvent être utilisées comme termes alternatifs pour accéder à ce même concept.
Par exemple, indemnisation, indemniser et règlement des dommages sont des formulations différentes qui peuvent, dans un thésaurus métier donné, être rattachées au même concept d’indemnisation. Ici, indemnisation peut être retenu comme terme préféré, tandis que les autres formulations deviennent des termes alternatifs. Le concept reste le même, même lorsque les mots utilisés pour l’exprimer changent.
Comment RDF et SKOS représentent-ils un thésaurus ?
RDF
RDF (Resource Description Framework) représente les informations sous la forme de triplets composés d’un sujet, d’un prédicat et d’un objet. Chaque triplet exprime une relation.
Les triplets RDF permettent de définir explicitement la relation entre un sujet et un objet. Si le sujet est un concept, l’objet peut être un terme qui le désigne : le prédicat précise alors s’il s’agit de son terme préféré ou d’un terme alternatif.
L’objet peut également être un autre concept. Le prédicat permet alors d’indiquer qu’un concept est plus général qu’un autre, plus spécifique ou simplement associé.
Les triplets forment ainsi un graphe dans lequel un même concept peut être relié à plusieurs termes, notes et autres concepts. RDF permet donc de représenter explicitement et de manière flexible les différentes relations qui structurent un thésaurus.
SKOS
SKOS (Simple Knowledge Organization System) est un vocabulaire RDF standardisé par le W3C pour représenter des systèmes d’organisation des connaissances comme les thésaurus. Il fournit un ensemble commun de classes et de propriétés permettant de représenter les concepts, leurs libellés et les relations qui les relient.
RDF fournit la structure en triplets, tandis que SKOS fournit un vocabulaire standardisé pour représenter les concepts d’un thésaurus, leurs différentes formulations et les relations qui les unissent.
SKOS permet également de décrire plus précisément chaque concept :
skos:prefLabel désigne le terme préféré dans une langue donnée ;
skos:altLabel contient les synonymes, variantes ou abréviations acceptées ;
skos:hiddenLabel contient des formes utiles à la reconnaissance, comme une faute fréquente ou un terme obsolète ;
skos:definition précise le sens du concept ;
skos:scopeNote précise son contexte ou ses limites d’utilisation.
Enfin, SKOS permet de représenter les relations entre concepts :
skos:broader relie un concept à un concept plus général ;
skos:narrower le relie à un concept plus spécifique ;
skos:related indique une association entre deux concepts sans affirmer qu’ils sont équivalents.
Cette structure rend le thésaurus bien plus riche qu’une simple liste de synonymes et permet de l’échanger, de l’interpréter et de le réutiliser dans différents systèmes.
Comment construire notre thésaurus d’assurance ?
Pour un prototype Python, nous pouvons représenter le thésaurus dans une structure JSON lisible. Chaque concept possède un identifiant stable. Les relations pointent vers les identifiants d’autres concepts et non vers leurs libellés, ce qui évite toute ambiguïté lorsque les termes changent ou existent dans plusieurs langues.
Pour exploiter ces principes dans notre prototype, nous allons d’abord utiliser une représentation JSON inspirée de cette structure SKOS.
Cette structure JSON reprend les principaux éléments de SKOS sans être encore une représentation RDF/SKOS. La bibliothèque Python RDFLib permettra ensuite de la convertir en graphe RDF conforme au modèle SKOS.
Comment enrichir et pondérer la requête à partir du graphe SKOS ?
Nous construisons d’abord un index de libellés SKOS qui associe les formulations de la requête aux concepts du thésaurus afin de pouvoir ensuite les enrichir.
Pour chaque terme ou expression de la requête, nous cherchons s’il correspond au prefLabel, à un altLabel ou à un hiddenLabel d’un concept du thésaurus. Lorsqu’un concept est reconnu, la requête peut être enrichie avec :
son prefLabel ;
ses altLabel ;
les libellés des concepts narrower ;
les libellés des concepts broader ;
les libellés des concepts related.
Tous ces termes ne sont cependant pas considérés comme également importants. Lors du calcul du score, un poids différent leur est attribué selon leur proximité avec le concept reconnu. Par exemple, un prefLabel peut recevoir un poids plus élevé qu’un terme provenant d’une relation related.
Les hiddenLabel servent uniquement à reconnaître un concept et ne sont pas réinjectés dans la requête.
La provenance explique pourquoi le terme a été ajouté. Le poids exprime la confiance accordée à cette source.
Comment les poids interviennent-ils dans le score BM25 ?
La politique SKOS indique seulement quels termes sont ajoutés et le poids qui leur est attribué selon leur source.
on a vu plus haut que pour chaque document, BM25 calcule une contribution lexicale pour chaque token de la requête. Notre politique multiplie cette contribution par le poids du token avant de les additionner :
Ici, \(q^\star\) contient les tokens originaux et ceux issus de l’expansion. \(w_t\) vaut 1.00 pour un token de la requête utilisateur, puis dépend de sa source pour les tokens ajoutés. Les tokens de la requête originale sont conservés tels quels, y compris lorsqu’ils sont répétés par l’utilisateur. En revanche, lorsqu’un même token est produit plusieurs fois par l’expansion SKOS, une seule occurrence est conservée avec le poids le plus élevé. Cela évite que l’expansion amplifie artificiellement un même signal lexical.
Table 3: Résultats de la recherche lexicale avec BM25
Document
Contenu
Score BM25
Rang
Document A
En cas de sinistre automobile responsable, l’assureur procède au règlement des dommages subis par l’assuré conformément aux garanties prévues au contrat. Le montant de la prestation versée dépend notamment de l’évaluation du préjudice et des conditions d’indemnisation applicables.
1.322
1
Document B
L’assuré doit déclarer son accident de voiture dans les meilleurs délais. L’accident peut être déclaré depuis l’espace personnel de l’assuré ou auprès de son agence d’assurance. Une confirmation de la déclaration est ensuite adressée à l’assuré.
0.801
2
Document A passe devant Document B parce que les termes indemnisation, règlement des dommages et sinistre automobile apportent un signal lexical qui n’était pas présent dans la requête initiale. BM25 ne déduit toujours pas le sens de ces expressions. Le graphe SKOS a rendu explicite le pont lexical dont il avait besoin et la politique a limité la confiance accordée aux concepts plus éloignés.
Chaque terme affiché dans la table conserve sa source et son poids. Cette provenance permet d’expliquer un classement, de désactiver une relation trop large ou de modifier sa pondération sans changer le thésaurus métier.
Comment limiter le risque de dérive de la requête ?
Une expansion trop large peut provoquer une dérive de requête (query drift). La requête s’éloigne alors de l’intention originale à mesure que des concepts voisins sont ajoutés.
Quelques règles permettent de contenir ce risque.
Toujours conserver les termes originaux avec le poids 1.00.
Attribuer un poids élevé aux prefLabel et altLabel, qui restent proches du concept reconnu.
Utiliser hiddenLabel pour reconnaître une entrée, sans réinjecter les fautes ou les formes obsolètes.
Diminuer le poids de narrower, broader et related, car ces relations ne sont pas des synonymes.
Ne pas parcourir récursivement la hiérarchie ni les relations skos:related sans une règle métier et une évaluation.
Plafonner le nombre de termes ajoutés et conserver leur source ainsi que leur poids.
Comparer les politiques d’expansion sur un jeu de requêtes annotées.
Comment évaluer réellement cette méthode ?
L’exemple précédent montre que l’implémentation produit le comportement attendu sur ce cas pédagogique. L’expansion contrôlée modifie ici le classement BM25 dans le sens attendu. Document A remonte parce que le thésaurus a fourni des formulations absentes de la requête initiale.
Deux documents et une requête ne permettent absolument pas de conclure que la méthode améliore systématiquement le retrieval.
Il faut donc distinguer clairement preuve du mécanisme et validation empirique de la méthode. La première vérifie que le code fait ce qu’on lui a demandé. La seconde dirait que, sur un corpus réel et des questions représentatives du futur usage, l’expansion aide plus souvent qu’elle ne dégrade le classement. Ce second niveau n’est pas encore atteint.
Un protocole sur des données réelles
Pour tester réellement cette approche, il faudrait disposer de données construites indépendamment du système évalué, puis comparer deux retrievers dans exactement les mêmes conditions.
1. Un corpus documentaire réel
Les passages indexés doivent être ceux que le futur RAG interrogera. Selon le projet, cela peut être de la documentation d’assurance, des conditions générales, des procédures de gestion, de la documentation contractuelle ou une base documentaire interne. Le critère n’est pas le volume. C’est la fidélité au fonds réellement interrogé.
2. Un ensemble de requêtes réalistes
Idéalement, ces questions sont celles que posent déjà les utilisateurs, ou des formulations préparées avec des experts métier. Certaines doivent employer un vocabulaire différent de celui des documents. Les acronymes, synonymes et formulations métier alternatives sont particulièrement utiles. Ce sont précisément les cas de décalage lexical que l’expansion vise à traiter.
3. Des jugements de pertinence (qrels)
Qrels
Les query relevance judgments relient une requête à des documents et indiquent, pour chaque couple, si le document est pertinent et à quel degré. Ce sont les réponses de référence utilisées pour évaluer un classement.
Ces jugements doivent être établis par des humains, idéalement des experts métier, sans consulter les classements des systèmes comparés. On peut utiliser plusieurs niveaux de pertinence, par exemple :
Le corpus, les requêtes, le découpage documentaire, la tokenisation, les paramètres BM25 et le nombre de résultats restent identiques. La seule variable étudiée est l’expansion de requête. Les poids et les relations autorisées ne doivent pas être ajustés après avoir observé les résultats de la comparaison finale.
Que faudrait-il mesurer ?
Aucune des métriques ci-dessous n’est calculée ici. Elles indiquent seulement ce qu’il faudrait observer une fois les qrels disponibles.
Precision@k. Parmi les k premiers documents retournés, quelle proportion est réellement pertinente ? Elle permet notamment de vérifier que l’expansion n’ajoute pas trop de bruit dans le haut du classement.
Recall@k. Quelle proportion des documents pertinents disponibles apparaît dans le top-k ? Cette métrique est particulièrement importante ici. L’objectif de l’expansion est notamment de récupérer des documents que le décalage lexical faisait auparavant manquer.
nDCG@k. Cette métrique tient compte de l’ordre des résultats et, le cas échéant, de plusieurs niveaux de pertinence. Elle permet de vérifier que les meilleurs documents apparaissent suffisamment haut dans le classement.
MRR. Elle mesure à quelle position apparaît le premier document pertinent. Elle est particulièrement intuitive lorsque le RAG exploite surtout le haut de la liste.
MAP. Elle mesure plus globalement la qualité du classement de l’ensemble des documents pertinents, et pas seulement du premier.
Un gain de rappel lu seul pourrait simplement signifier que la requête a été élargie. Un gain de précision lu seul pourrait signifier que l’on range mieux des documents déjà trouvés, sans en récupérer de nouveaux. Les deux doivent être lus ensemble.
Compter aussi les requêtes dégradées
L’évaluation ne doit pas seulement chercher des améliorations. Elle doit mesurer explicitement les cas où l’expansion dégrade le retrieval.
puis compter les requêtes améliorées (\(\Delta > 0\)), inchangées (\(\Delta = 0\)) et dégradées (\(\Delta < 0\)).
Cette analyse permettrait ensuite d’examiner quelles relations SKOS sont réellement bénéfiques (prefLabel, altLabel, narrower, broader, related) et d’ajuster leur pondération. Le but n’est pas seulement de faire monter une moyenne. Il est de comprendre dans quels cas l’expansion aide, et dans quels cas elle crée du bruit ou une dérive de requête.
Cette évaluation porterait sur le retrieval. Elle ne dirait pas encore si les réponses générées par le RAG hallucinent moins. Cette seconde question demanderait un protocole distinct, avec le même modèle, le même prompt, et une annotation des réponses.
Conclusion
SKOS rend explicites des relations terminologiques que BM25 ne peut pas déduire seul. L’expansion contrôlée rapproche alors le vocabulaire de l’utilisateur du vocabulaire réellement présent dans les documents. Les poids et la provenance des termes conservent un mécanisme explicable. On peut désactiver une relation trop large, ou modifier sa pondération, sans réécrire le thésaurus métier.
Cette approche pourrait être particulièrement pertinente dans les domaines où le vocabulaire métier des experts constitue un signal fort de pertinence. Plutôt que de laisser exclusivement au modèle d’embedding la tâche de rapprocher le langage de l’utilisateur de celui des documents, le thésaurus permet d’expliciter une partie de ces correspondances terminologiques et de conserver la provenance des termes ajoutés. Elle n’a pas vocation à remplacer la recherche vectorielle. Elle constitue une brique lexicale, que l’on pourra ensuite étudier dans un retrieval hybride combinant signaux lexicaux et sémantiques.
L’exemple de Document A et Document B montre que l’implémentation produit le comportement attendu sur ce cas pédagogique. Il ne démontre pas que SKOS-BM25 est supérieur à BM25 en général. La prochaine étape consiste à construire un corpus réel, des requêtes indépendantes et des jugements de pertinence établis par des experts, puis à comparer les deux systèmes dans les mêmes conditions, y compris sur les requêtes où l’expansion dégrade le classement.
C’est cette expérience, et non l’exemple pédagogique, qui dira si la méthode mérite d’entrer dans un pipeline de production.
Comment estimer la pertinence d’un document pour une requête ?
Similarité
Afin de sélectionner des documents qui contiennent le bon contexte, le système doit estimer dans quelle mesure chacun répond à l’intention exprimée dans la requête de l’utilisateur. Cette intention ne peut pas être observée directement. La recherche d’information l’approche donc à partir de scores de similarité entre la requête et les documents.
Le concept de similarité dans la recherche d’informations peut être divisé en deux catégories :
Similarité lexicale : Elle mesure la similarité entre la requête et un document à partir des mots-clés ou expressions identiques qu’ils partagent.
Similarité sémantique : Elle mesure la similarité entre la requête et un document à partir du sens qu’ils partagent, même lorsque les mots ou expressions employés sont différents. Elle est notamment mise en œuvre par la recherche vectorielle, très couramment utilisée dans les systèmes RAG modernes.
On pourrait alors être tenté de considérer que la recherche vectorielle suffit à elle seule. Mais ce n’est pourtant pas toujours le cas. La recherche lexicale reste particulièrement efficace lorsque l’on doit retrouver précisément le nom d’une personne, une référence de contrat, un numéro de document, un code d’erreur, un identifiant technique, un vocabulaire métier très spécifique, un nom de produit, un acronyme ou tout autre terme qui ne doit pas être manqué. Certains termes ont donc une forte valeur discriminante et nécessitent une recherche lexicale.
Décalage lexical
Cependant, la similarité lexicale souffre du décalage lexical. Il survient lorsque le vocabulaire utilisé dans la requête de l’utilisateur diffère de celui employé dans les documents pertinents, alors qu’ils font référence au même concept. Ce décalage lexical peut engendrer un biais dans le calcul de la similarité entre la requête de l’utilisateur et le document.
Considérons maintenant un premier document pertinent pour cette requête :
Ici, la requête et le document sont sémantiquement liés, mais syntaxiquement différents. La requête ne contient pas les termes exacts du document, à l’exception du terme
l’assuré. Il s’agit d’un exemple classique de problème de décalage lexical.Considérons maintenant un second document, lexicalement proche de la requête mais non pertinent :
Document Bcontient les termes de la requête, mais il ne répond pas à l’intention de l’utilisateur, qui cherche à être indemnisé. Un algorithme de recherche lexicale est susceptible de mieux classerDocument BqueDocument Aen raison de sa plus forte correspondance lexicale avec la requête.Introduction à l’algorithme de BM25
Parmi les algorithmes de recherche lexicale, BM25 est l’un des plus utilisés. Il attribue un score de pertinence à chaque document en fonction des termes de la requête qu’il contient.
Avant d’effectuer une recherche, on commence par extraire le texte des documents et le découper en tokens, puis par construire un index inversé. Cette structure associe chaque terme aux documents qui le contiennent. Elle conserve aussi le nombre d’apparitions de chaque terme dans un document, le nombre de documents qui contiennent ce terme, le nombre total de documents, la longueur de chaque document et la longueur moyenne des documents du corpus.
Lorsqu’une question arrive, elle est elle aussi découpée en tokens. Chaque token est ensuite utilisé pour interroger l’index et retrouver directement les documents qui le contiennent.
Pour chaque token de la requête, BM25 calcule un score à partir des statistiques de l’index. Le score BM25 final d’un document correspond à la somme des scores obtenus pour les différents tokens de la requête.
Les documents sont ensuite classés selon leur score BM25.
Comment le score BM25 est-il calculé ?
\[ \operatorname{BM25}(Q, D) = \sum_{t \in Q} \operatorname{IDF}(t) \cdot \frac{f(t, D)\,(k_1 + 1)} {f(t, D) + k_1\left(1 - b + b\,\frac{|D|}{\operatorname{avgdl}}\right)} \tag{1}\]
Dans cette équation :
La rareté du terme est calculée par l’IDF. BM25S utilise par défaut la variante Lucene, dont l’IDF est défini ainsi.
\[ \operatorname{IDF}(t) = \log\left(1 + \frac{N - n(t) + 0.5}{n(t) + 0.5}\right) \tag{2}\]
Dans cette équation :
Plus \(n(t)\) est faible, plus le terme est rare et plus son poids est élevé.
Dans le code qui suit, BM25S utilise ses valeurs par défaut \(k_1 = 1.5\) et \(b = 0.75\).
Comment BM25 corrige-t-il les biais de la recherche lexicale ?
Le score BM25 repose principalement sur trois éléments : la fréquence du terme dans le document, sa rareté dans le corpus et la longueur du document. Chacun apporte un signal de pertinence tout en corrigeant un biais possible.
La fréquence du terme \(f(t,D)\) indique combien de fois le terme \(t\) apparaît dans le document \(D\). C’est un indice de pertinence, mais répéter cent fois le même mot ne doit pas donner un avantage cent fois plus grand. Le paramètre \(k_1\) permet donc de saturer progressivement le gain apporté par les répétitions successives.
La rareté du terme \(\operatorname{IDF}(t)\) augmente le poids des termes présents dans peu de documents du corpus. Un code d’erreur ou un acronyme rare distingue davantage un résultat qu’un mot présent dans presque tous les documents.
La longueur du document \(\frac{|D|}{\operatorname{avgdl}}\) compare la longueur du document à la longueur moyenne des documents du corpus. Sans cette correction, un document très long aurait davantage de chances de contenir les mots recherchés et pourrait être artificiellement favorisé. Le paramètre \(b\) contrôle l’importance de cette normalisation.
Retrieval lexical avec BM25S
Conséquences du décalage lexical dans un système RAG
Ce résultat met en évidence une limite inhérente à la recherche lexicale; le score ne peut exploiter que les termes présents dans la requête et dans les documents.
Ce décalage lexical affecte deux propriétés essentielles du retrieval :
Pour palier ce problème, nous allons donc faire recour à une solution bien connue: l’expansion de requête.