Il s'agit d'une implémentation de base d'un moteur de recherche de fichiers basé sur Python pour répondre aux requêtes dans les fichiers texte sur un système local. Nous avons utilisé la « pondération des termes tf-idf » et la « similarité cosinus » pour classer la pertinence des documents correspondants. Les calculs tf-idf sont précalculés, ce qui rend la recherche beaucoup plus rapide. Également pour accélérer la recherche, Stemming (Porter Stemmer) a été utilisé. Une interface utilisateur de base utilisant la bibliothèque Tkinter de Python est fournie.
python2 createIndex_tfidf.py stopwords.dat testIndex.dat titleIndex.dat
createIndex_tfidf.py ne s'exécutera qu'une seule fois pour calculer les valeurs tdf-idf sur le corpus
python2 queryIndex_tfidf.py stopwords.dat testIndex.dat titleIndex.dat
Au total, trois fichiers différents sont créés au cours de cette étape :
titreIndex.dat
Ce fichier stocke le docId unique (identifiant du document) qui est attribué à chaque document du corpus.
testIndex.dat
Dans celui-ci, un fichier d'index est créé (également connu sous le nom de structure de données d'index inversé) qui contient des informations sur tous les termes uniques (à l'exception des mots vides) apparaissant dans tous les documents. Chaque document reçoit un identifiant unique commençant à 0 tel que stocké dans titleIndex. ce. Les informations sur un terme sont stockées dans le fichier d'index comme suit : term|docID0:pos1,pos2;docID1:pos3,pos4,pos5;…..|tf0,tf1,tf2...|idf Ici tf0,tf1,tf2 représente la fréquence du terme dans docID0, docID1, docID2 respectivement. idf représente la fréquence inverse du document et pos1 représente la position du terme dans le document respectif et ainsi de suite.
lignes.dat
Ce fichier stocke les informations sur les lignes dans lesquelles le terme est présent dans divers documents. Ces informations de ligne sont représentées par : term|docID0:line1,line2;docID1:line3,line4,line5
Avant la création de ces fichiers, tous les termes des documents sont vérifiés dans la liste des mots vides. Si un terme apparaît dans les mots vides, il est ignoré, sinon ses informations sont stockées dans ces fichiers ci-dessus. De plus, chaque terme est dérivé de Porter Stemmer avant d'être ajouté à l'index.
Dans ce cas, tout d'abord, toutes les informations des fichiers lines.dat, titleIndex.dat et testIndex.dat sont à nouveau stockées à l'aide d'un dictionnaire en Python.
Désormais, les différents types de Requêtes supportées sont :
Requêtes en un seul mot (OWQ) Il s'agit d'une requête à terme unique et sa sortie est une liste de documents contenant le terme demandé ainsi que les numéros de ligne où le terme est présent dans le document respectif.
Requêtes multi-mots (MWQ) L'entrée dans MWQ est une séquence de mots et la sortie est la liste des documents contenant l'un des termes de requête ainsi que les numéros de ligne.
Requêtes d'expressions (PQ) L'entrée dans PQ est à nouveau une séquence de mots, et les documents correspondants sont ceux qui contiennent tous les termes de requête dans l'ordre spécifié.
Maintenant que nous avons trouvé la liste des documents dans lesquels la requête est présente il est temps de les classer. Le système de classement que nous avons utilisé ici est basé sur tf-idf. Tf-Idf est un système de pondération qui attribue à chaque terme d'un document un poids basé sur la fréquence de son terme (tf) et sa fréquence inverse de document (idf). Les termes ayant des scores de pondération plus élevés sont considérés comme plus importants. Il s'agit de l'un des systèmes de pondération les plus populaires en matière de recherche d'informations.
La fréquence des termes (tf) d'un terme est spécifique au document. Il s'agit essentiellement du nombre d'occurrences du terme t dans le document D. Il est tout à fait logique de choisir tf comme paramètre car à mesure qu'un terme apparaît davantage dans le document, il devient plus important. On peut représenter un document par un vecteur dont la taille est égale au no. de termes uniques dans le document et chaque valeur indique le nombre de termes dans le document donné. La représentation de documents sous forme de vecteurs dans un espace vectoriel commun est connue sous le nom de modèle d'espace vectoriel et est fondamentale pour la recherche d'informations. Mais voici un inconvénient. À mesure que la taille du document augmentera, le poids de tf augmentera à mesure que la fréquence des termes augmentera. Ainsi, un document contenant les mêmes informations qu'un autre document, copié plus d'une fois, sera considéré comme plus important. Pour éradiquer cet inconvénient, nous diviserons chaque valeur d'un vecteur par sa norme afin que le vecteur devienne un vecteur unitaire.
Nous ne pouvons pas uniquement utiliser la fréquence des termes pour calculer le poids d'un terme dans le document, car tf considère tous les termes avec la même importance. Cependant, certains termes apparaissent plus rarement et sont plus discriminants que d’autres. Si nous utilisons uniquement tf comme mesure pour classer, alors si nous recherchons un sujet comme les ondes sonores, nous pourrions finir par obtenir de nombreux documents contenant des ondes lumineuses et d'autres ondes, car la fréquence du terme est le seul paramètre.
Pour atténuer cet effet, nous utilisons la fréquence inverse des documents. La fréquence des documents d'un terme correspond essentiellement au nombre de documents contenant le terme. Ainsi, la fréquence inverse des documents (idf) d'un terme est le nombre de documents dans le corpus divisé par la fréquence des documents d'un terme. Généralement, il a été constaté que le facteur idf est assez grand et que de meilleurs résultats sont obtenus si nous utilisons log(idf). Comme log est une fonction croissante, nous pouvons l’utiliser sans entraver nos résultats.
Nous avons défini à la fois tf et idf, et nous pouvons maintenant les combiner pour produire le score ultime d'un terme t dans le document d. Nous représenterons à nouveau le document sous forme de vecteur, chaque entrée étant le poids tf-idf du terme correspondant dans le document. Le poids tf-idf d'un terme t dans le document d est simplement la multiplication de son tf par son idf.
Maintenant que nous avons construit les vecteurs de chaque document en fonction du poids tf-idf. Il est temps de répondre à une requête en utilisant les vecteurs de documents donnés. Tout d'abord, nous allons créer un vecteur de requête lui-même sur une base similaire à celle que nous avons créée pour le vecteur de document, c'est-à-dire basé sur le score tf-idf (en considérant l'interrogation d'un document lui-même). Maintenant que notre vecteur de requête est prêt, nous trouverons tous les documents dans lesquels notre requête est présente. Nous allons maintenant prendre le produit scalaire du vecteur de requête et du vecteur de document dans lequel la requête est présente. Plus le produit scalaire est élevé, plus le vecteur de requête est similaire au vecteur de document, ce qui signifie que l'angle entre le vecteur de document et le vecteur de requête est petit. Cette technique permettant de rechercher une similarité entre une requête et un document est appelée similarité cosinus.