Console
Clique sur « Exécuter » pour lancer le programme.
Code CoddyRun
@ Fonctions de préparation du texte
fonction tokeniser(contenu)
contenuNormalise est un texte
mots est un tableau
contenuNormalise vaut supprime_espace(minuscules(normaliser(contenu)))
mots vaut decouper(contenuNormalise, " ")
retourne mots
fin fonction
fonction frequenceTerme(motsDocument, termeRecherche)
occurrences est un nombre
indiceMot est un nombre
occurrences vaut 0
pour indiceMot de 0 à longueur(motsDocument) - 1
si motsDocument[indiceMot] = termeRecherche alors
occurrences ajoute 1
fin si
fin pour
retourne occurrences
fin fonction
fonction contientTerme(motsDocument, termeRecherche)
indiceMot est un nombre
pour indiceMot de 0 à longueur(motsDocument) - 1
si motsDocument[indiceMot] = termeRecherche alors
retourne vrai
fin si
fin pour
retourne faux
fin fonction
fonction frequenceDocumentaire(corpusTokenise, termeRecherche)
nbDocuments est un nombre
indiceDocument est un nombre
documentCourant est un tableau
nbDocuments vaut 0
pour indiceDocument de 0 à longueur(corpusTokenise) - 1
documentCourant vaut corpusTokenise[indiceDocument]
si contientTerme(documentCourant, termeRecherche) alors
nbDocuments ajoute 1
fin si
fin pour
retourne nbDocuments
fin fonction
fonction calculerIdf(nbTotalDocuments, nbDocumentsAvecTerme)
numerateurIdf est un nombre
denominIdf est un nombre
valeurIdf est un nombre
numerateurIdf vaut nbTotalDocuments - nbDocumentsAvecTerme + 0,5
denominIdf vaut nbDocumentsAvecTerme + 0,5
valeurIdf vaut logarithme((numerateurIdf / denominIdf) + 1)
retourne valeurIdf
fin fonction
fonction scoreBm25Document(motsDocument, termesRequete, corpusTokenise, longueurMoyenne, parametreK1, parametreB)
scoreDocument est un nombre
indiceTerme est un nombre
termeCourant est un texte
frequence est un nombre
frequenceDocs est un nombre
idfCourant est un nombre
normalisationLongueur est un nombre
numerateurScore est un nombre
denominScore est un nombre
contribution est un nombre
nbTotalDocuments est un nombre
scoreDocument vaut 0
nbTotalDocuments vaut longueur(corpusTokenise)
pour indiceTerme de 0 à longueur(termesRequete) - 1
termeCourant vaut termesRequete[indiceTerme]
frequence vaut frequenceTerme(motsDocument, termeCourant)
si frequence > 0 alors
frequenceDocs vaut frequenceDocumentaire(corpusTokenise, termeCourant)
idfCourant vaut calculerIdf(nbTotalDocuments, frequenceDocs)
normalisationLongueur vaut 1 - parametreB + parametreB * longueur(motsDocument) / longueurMoyenne
numerateurScore vaut frequence * (parametreK1 + 1)
denominScore vaut frequence + parametreK1 * normalisationLongueur
contribution vaut idfCourant * numerateurScore / denominScore
scoreDocument vaut scoreDocument + contribution
fin si
fin pour
retourne scoreDocument
fin fonction
@ Constitution du corpus
titres est un tableau
documents est un tableau
corpusTokenise est un tableau
// Les titres et les documents utilisent le même index.
titres ajoute "Introduction à la recherche d'information"
documents ajoute "La recherche d information permet de trouver des documents pertinents dans une collection de textes"
titres ajoute "Présentation de BM25"
documents ajoute "BM25 est un algorithme de classement qui utilise la fréquence des termes et la longueur des documents"
titres ajoute "Moteurs de recherche"
documents ajoute "Un moteur de recherche indexe les pages puis classe les résultats selon leur pertinence pour la requête"
titres ajoute "Traitement automatique du langage"
documents ajoute "Le traitement du langage analyse les mots les textes et les requêtes pour extraire des informations"
titres ajoute "Apprentissage automatique"
documents ajoute "L apprentissage automatique construit des modèles à partir de données pour effectuer des prédictions"
// Tokenisation de chaque document.
indiceDocument est un nombre
motsCourants est un tableau
pour indiceDocument de 0 à longueur(documents) - 1
motsCourants vaut tokeniser(documents[indiceDocument])
corpusTokenise ajoute motsCourants
fin pour
@ Paramètres BM25
// Valeurs classiques de démonstration : k1 = 1,5 et b = 0,75.
parametreK1 est un nombre
parametreB est un nombre
parametreK1 vaut 1,5
parametreB vaut 0,75
// Calcul de la longueur moyenne des documents.
longueurTotale est un nombre
longueurMoyenne est un nombre
longueurTotale vaut 0
pour indiceDocument de 0 à longueur(corpusTokenise) - 1
motsCourants vaut corpusTokenise[indiceDocument]
longueurTotale vaut longueurTotale + longueur(motsCourants)
fin pour
longueurMoyenne vaut longueurTotale / longueur(corpusTokenise)
@ Saisie de la requête
requeteUtilisateur est un texte
termesRequete est un tableau
affiche "=== Recherche BM25 ==="
affiche "Corpus chargé : " + convertir_texte(longueur(documents)) + " documents"
demande "Saisis une requête : " dans requeteUtilisateur
si est_vide(supprime_espace(requeteUtilisateur)) alors
affiche "La requête est vide. Arrêt du programme."
terminer
fin si
// unique évite de compter plusieurs fois un même mot de la requête.
termesRequete vaut unique(tokeniser(requeteUtilisateur))
@ Calcul des scores
scores est un tableau
ordreResultats est un tableau
scoreCourant est un nombre
pour indiceDocument de 0 à longueur(corpusTokenise) - 1
motsCourants vaut corpusTokenise[indiceDocument]
scoreCourant vaut scoreBm25Document(motsCourants, termesRequete, corpusTokenise, longueurMoyenne, parametreK1, parametreB)
scores ajoute scoreCourant
ordreResultats ajoute indiceDocument
fin pour
@ Tri décroissant des résultats
// Tri par sélection des index, selon les scores associés.
positionTri est un nombre
positionCandidate est un nombre
positionMeilleure est un nombre
indexTemporaire est un nombre
indexMeilleur est un nombre
indexCandidate est un nombre
pour positionTri de 0 à longueur(ordreResultats) - 2
positionMeilleure vaut positionTri
indexMeilleur vaut ordreResultats[positionMeilleure]
pour positionCandidate de positionTri + 1 à longueur(ordreResultats) - 1
indexCandidate vaut ordreResultats[positionCandidate]
si scores[indexCandidate] > scores[indexMeilleur] alors
positionMeilleure vaut positionCandidate
indexMeilleur vaut indexCandidate
fin si
fin pour
si positionMeilleure <> positionTri alors
indexTemporaire vaut ordreResultats[positionTri]
ordreResultats[positionTri] vaut ordreResultats[positionMeilleure]
ordreResultats[positionMeilleure] vaut indexTemporaire
fin si
fin pour
@ Affichage du classement
rang est un nombre
indexResultat est un nombre
nbResultats est un nombre
nbResultats vaut 0
affiche ""
affiche "Résultats pour : " + requeteUtilisateur
affiche "Longueur moyenne des documents : " + convertir_texte(decimal(longueurMoyenne, 2))
affiche ""
pour positionTri de 0 à longueur(ordreResultats) - 1
indexResultat vaut ordreResultats[positionTri]
si scores[indexResultat] > 0 alors
rang vaut nbResultats + 1
affiche convertir_texte(rang) + ". " + titres[indexResultat]
affiche " Score BM25 : " + convertir_texte(decimal(scores[indexResultat], 4))
affiche " Document : " + documents[indexResultat]
affiche ""
nbResultats ajoute 1
fin si
fin pour
si nbResultats = 0 alors
affiche "Aucun document ne contient les termes de la requête."
sinon
affiche convertir_texte(nbResultats) + " document(s) pertinent(s) trouvé(s)."
fin si
@ Détail pédagogique des termes
affiche ""
affiche "=== Informations sur les termes ==="
indiceTerme est un nombre
termeCourant est un texte
frequenceDocs est un nombre
idfCourant est un nombre
pour indiceTerme de 0 à longueur(termesRequete) - 1
termeCourant vaut termesRequete[indiceTerme]
frequenceDocs vaut frequenceDocumentaire(corpusTokenise, termeCourant)
idfCourant vaut calculerIdf(longueur(corpusTokenise), frequenceDocs)
affiche termeCourant + " : présent dans " + convertir_texte(frequenceDocs) + " document(s), IDF = " + convertir_texte(decimal(idfCourant, 4))
fin pour