Moteur de recherche : introduction aux méthodes courantes de recherche d'informations et implémentation de l'index inversé (Python)

1. Méthode de recherche d'informations

(1) Balayage linéaire

Les ordinateurs ont de nombreuses façons possibles de récupérer le contenu du document, comme parcourir directement du début à la fin et extraire le contenu en fonction des mots-clés que nous avons entrés.

Ce type de méthode de récupération est le même que nos habitudes de lecture humaines, il est donc simple à mettre en œuvre et facilement accepté.

Si on vous demande si l'expression "Parler contre le confucianisme" existe dans "Le Roman des Trois Royaumes", nous choisissons souvent de parcourir le texte intégral pour trouver les mots correspondants.



Et il ne faudra pas trop de temps pour extraire des mots clés de "Le Roman des Trois Royaumes" grâce à des ordinateurs modernes ;

Mais que se passe-t-il si l'objectif est une collection de littérature mondiale ? Qu'en est-il du rapport financier annuel de l'entreprise ? Ou les plus grandes collections de documents produites par le monde moderne de l'information.

Malgré la puissance de calcul des ordinateurs, la méthode de recherche d'informations par balayage linéaire ne peut être utilisée que pour le traitement de petits textes.

(2) Matrice d'association terme-document

En conséquence, la matrice de corrélation terme-document a été générée et nous avons utilisé la puissance de calcul inactive pour construire la matrice à l'avance dans l'ordinateur.

Trois Royaumes Rêve de manoirs rouges Hors-la-loi du Marais voyage à l'ouest Wukong
Sun Wu Kong 0 0 0 1 1
Jia Baoyu 0 1 0 0 0

Lorsque nous saisissons le mot-clé Sun Wukong, les deux documents "Journey to the West" et "The Legend of Wukong" sont renvoyés comme résultats.

Cette méthode améliore considérablement la vitesse de recherche

Les termes sont l'unité d'indexation et les documents sont les résultats renvoyés.

Du point de vue de la ligne, le vecteur de document du terme correspondant peut être obtenu ; du point de vue de la colonne, le vecteur de terme du document peut être obtenu.

Bien sûr, cette méthode a aussi des défauts majeurs.Comme le tableau que j'ai illustré ci-dessus, vous pouvez voir que la valeur 0 dans la matrice représente une proportion très élevée.

Tout en causant une charge, cela ralentit également considérablement la vitesse de récupération.

(3) Index inversé

Les étudiants qui se sont familiarisés avec les structures de données devraient bientôt être capables de penser à des méthodes d'optimisation - des tableaux clairsemés.

Nous construisons des dictionnaires de termes et des listes de publication pour récupérer efficacement les documents.

dictionnaire de termes Messages
Sun Wu Kong 4—>5
Jia Baoyu 2

Les deux parties de l'index inversé. La partie dictionnaire est souvent placée en mémoire, tandis que chaque liste de publication pointée par un pointeur est généralement stockée sur disque.

2. Implémentation de l'index inversé et méthodes communes de traitement des corpus

(1) Pour atteindre l'objectif

Lire des fichiers texte pour lemmatiser et normaliser différents documents d'une seule ligne,

Faites attention au filtrage des signes de ponctuation, au filtrage des mots vides et à la conversion des majuscules et des minuscules.

Construire un dictionnaire inversé index/termes.

(2) Code complet

 import re
 import string
 from stop_words import get_stop_words
 from nltk.stem.porter import PorterStemmer
 
 
 # 列表去重
 def unique(word_list):
     return list(dict.fromkeys(word_list))
 
 
 # 移除停用词
 def stop_word(token):
     en_stop = get_stop_words('en')
     stopped_tokens = [i for i in token if i not in en_stop]
     return stopped_tokens
 
 
 # 词干提取
 def stem_extracting(stopped_tokens):
     p_stemmer = PorterStemmer()
     texts = [p_stemmer.stem(i) for i in stopped_tokens]
     return texts
 
 
 # Porter stemmer 并不是要把单词变为规范的那种原来的样子,
 # 它只是把很多基于这个单词的变种变为某一种形式!换句话说,
 # 它不能保证还原到单词的原本,也就是"created"不一定能还原到"create",
 # 但却可以使"create" 和 "created" ,都得到"creat" !
 
 def incidence_matrix(text, docID):
     # 目的:
     # 传入一段文本及其文档号
     # 获取其词项列表
 
     # 1.清除英文标点符号
     punctuation_string = string.punctuation
     lines = re.sub('[{}]'.format(punctuation_string), " ", text)
     # 2.将英文文本内容切片
     lsplit = lines.split()
     # 3.大小写转换
     for num in range(len(lsplit)):
         lsplit[num] = lsplit[num].lower()
     # 4.移除停用词 词干提取
     # lsplit = stem_extracting(stop_word(lsplit))
     # 5.去重并转字典
     lsplit_dic = dict.fromkeys(lsplit)
     # 6.记录文档号
     for word in lsplit_dic.keys():
         lsplit_dic[word] = [docID]
     return lsplit_dic
 
 
 def read_file(filename):
     result = {
    
    }
     count = 0
     with open(filename, 'r') as file_to_read:
         # 以只读形式打开该文件
         while True:
             # 以行为单位进行读取
             lines = file_to_read.readline()
             # 当某行内容为空时 停止读取
             if len(lines) == 0:
                 break
             count = count + 1
             lsplot = incidence_matrix(lines, count)
             result = dic_zip(result, lsplot)
     # 关闭文件读取
     file_to_read.close()
     return result
 
 
 def dic_sort(a_dic):
     b_dic = dict.fromkeys(sorted(a_dic))
     for word in b_dic.keys():
         b_dic[word] = a_dic[word]
     return b_dic
 
 
 # 不同文档字典 同一词项合并
 def dic_zip(a_dic, b_dic):
     # 将b_dic并入a_dic中
     for word in b_dic.keys():
         if a_dic.get(word, None):
             a_dic[word].extend(b_dic[word])
         else:
             a_dic[word] = b_dic[word]
     return a_dic
 
 
 def show_dic(a_dic):
     # 文档频率可用于做查询优化
     tplt = "{0:^10}\t{1:{3}^10}\t{2:^40}"
     print(tplt.format("词项", "文档频率", "倒排记录", chr(12288)))
     for word in a_dic.keys():
         print(tplt.format(word, len(a_dic[word]), str(a_dic[word]), chr(12288)))
 
 
 def main():
     # 读取filename下的英文文本文件 将每一行作为单独的文本
     # 建立倒排索引。
     filename = './Reverse_Index_Word2.txt'
     matrix = dic_sort(read_file(filename=filename))
     show_dic(matrix)
 
 
 if __name__ == '__main__':
     main()

(3) Résultats en cours d'exécution

Les documents à plus grande échelle peuvent être lus, et le petit texte est sélectionné ici pour faciliter l'affichage.

Le processus de normalisation est commenté par moi et le symbole # peut être supprimé si nécessaire.

 #读入的文档
 new home sales top forecasts
 home sales rise in july
 increase in home sales in july
 july new home sales rise
 
 # 运行结果
 "D:\Program Files\Python\python.exe" 
     词项        文档频率                     倒排记录                  
 forecasts       1                         [1]                   
    home         4                     [1, 2, 3, 4]              
     in          2                        [2, 3]                 
  increase       1                         [3]                   
    july         3                      [2, 3, 4]                
    new          2                        [1, 4]                 
    rise         2                        [2, 4]                 
   sales         4                     [1, 2, 3, 4]              
    top          1                         [1]                   
 
 Process finished with exit code 0
 

Je suppose que tu aimes

Origine blog.csdn.net/yt266666/article/details/127405088
conseillé
Classement