Implémentation d’un séparateur de mots et d’un stemmeur

Microsoft fournit des analyseurs de mots et des générateurs de formes dérivées pour un certain nombre de langues. Cette rubrique explique comment implémenter et utiliser des analyseurs de mots personnalisés et des lemmatiseurs pour les langues et les localités au-delà de ceux fournis par Microsoft.

Note

Temporairement, les analyseurs de mots personnalisés n'ont pas été pris en charge. En juillet 2018, une modification a été apportée à Windows Server 2019 qui empêchait les DLL sans signature Microsoft d’être chargées par SearchIndexer.exe. Cette limitation a été levée en janvier 2021.

Cette rubrique est organisée comme suit :

Enregistrement d’une DLL de ressource de langage

Chaque DLL de ressource de langage doit implémenter et exporter les points d’entrée suivants. La DLL peut être inscrite dans n’importe quel dossier.

  • DllMain est le point d’entrée standard vers LA DLL.
  • DllRegisterServer inscrit la DLL dans le Registre, par exemple regsvr32.exe %SystemRoot%\MyFolder\wordbreaker.dll
  • DllCanUnloadNow permet aux clients d’appeler ce point d’entrée via com (Component Object Model) pour déterminer s’il est possible de décharger la DLL de ressource de langage.
  • DllUnRegisterServer supprime la DLL du registre.

Inscription d’une langue

Le Registre contient des entrées propres à la langue indexée, et ces entrées contrôlent les parties des processus d’indexation et de requête spécifiques à la langue. Ces entrées de Registre se trouvent sous la clé de Registre suivante.

HKEY_LOCAL_MACHINE
   SYSTEM
      CurrentControlSet
         ContentIndex
            Control
               Language
                  

Implémentation d’un beaker Word

Les séparateurs de mots implémentent IWordBreaker. La méthode IWordBreaker ::BreakText effectue tout le traitement et l’analyse de texte. Pour implémenter un composant analyseur de mots, vous devez avoir des heuristiques linguistiques pour votre langue. Cela inclut des informations sur la syntaxe et la morphologie. Vous pouvez également avoir besoin d’une liste de mots pour exclure ou inclure. Vous construisez le fichier de mots parasites pour votre configuration régionale linguistique à partir de la liste des mots exclus. Pour plus d’informations sur les considérations linguistiques et sur la façon dont ces considérations affectent les implémentations d’analyseur de mots, consultez Considérations linguistiques et Unicode.

L’objectif principal de IWordBreaker ::BreakText est de traiter le texte en continu à partir de l’TEXT_SOURCE jusqu’à ce que tout le texte soit traité, ou jusqu’à ce que l’analyseur de mots rencontre une erreur. Dans cette boucle de traitement des données, IWordBreaker ::BreakText appelle l’analyse et les méthodes utilitaires qui effectuent des tâches spécifiques pour ce processus. Par exemple, le disjoncteur allemand peut gérer des mots composés, tandis que le disjoncteur français peut traiter des diacritiques ou des clitiques. Les fonctions spécifiques effectuées par l’analyseur de mots et la stratégie qu’elle utilise pour effectuer ces tâches dépendent entièrement des exigences de cette langue.

Lors de la segmentation du texte, les séparateurs de mots identifient des formes « alternatives » pour les mots qui peuvent avoir plusieurs représentations. Aucune relation sémantique n’est implicite entre les mots générés. En fait, le mot d’origine ne peut pas être inclus dans la liste des alternatives. Les autres formulaires sont enregistrés à la même position dans l’index que le mot d’origine pour indiquer qu’ils sont identiques.

Lorsqu’un document est inclus dans l’index, chaque mot reçoit une valeur entière qui représente le décalage ou la distance du mot depuis le début d’un document. La distance relative entre les mots d’une requête est comparée aux décalages stockés dans l’index de texte intégral. La requête « Where is Kyle’s document » correspond à tout document avec « Where » au décalage n, « is » à n+1, « Kyle' s » à n+2 et « document » à n+3. « Où le document de Kyle est-il déposé dans la base de données ? » est représenté comme suit :

               
Where est Kyle Kyle's
document Déposé in le base de données

 

Dans cet exemple, le séparateur de mots stocke des formes alternatives pour « Kyle » (« Kyle's ») et « base de données » (« data base ») dans l'index. Le disjoncteur de mots génère et stocke d’autres mots pendant le processus de création d’index dans les conditions suivantes :

  • Si un mot de remplacement est susceptible d’apparaître en tant que mot unique dans une requête
  • Si un algorithme de racinisation n'est pas susceptible de dériver le mot d'origine à partir de l'alternative

La génération de formulaires de mots alternatifs augmente le nombre de façons dont les requêtes représentent et correspondent à une phrase, comme illustré dans les variantes suivantes :

  1. Où se trouve le document Kyle déposé dans la base de données
  2. Où est le document de Kyle déposé dans la base de données
  3. Où est le document Kyle déposé dans la base de données
  4. Où est le document de Kyle déposé dans la base de données

WordSink et PhraseSink

Les analyseurs Word utilisent les objets IWordSink et IPhraseSink pour collecter et stocker tous les mots et expressions qu’ils extraient du texte. Un analyseur de mots stocke les mots sous une forme aussi proche que possible de la forme originale dans le document. IPhraseSink stocke les expressions au moment de la requête. Les expressions améliorent la pertinence des résultats de requête, car les séquences de mots plus longues sont plus rares et offrent une distinction plus grande que les phrases plus petites. Lorsque l’indexeur place une expression dans iPhraseSink au moment de la requête, elle crée une instance du analyseur de mots pour décomposer l’expression en mots. L’indexeur évalue ensuite l’expression en vérifiant si les mots de l’expression se produisent adjacents les uns aux autres dans l’index. Par exemple, si « ABCD » se produit dans l’index aux positions x, x+1, x+2 et x+3, la correspondance d’expressions se produit si une sous-chaîne adjacente de « ABCD » est envoyée dans une requête. Cette stratégie est efficace pour les découpeurs de mots basés sur des caractères qui fractionnent des expressions et des mots longs pendant la création d’index et qui génèrent des expressions lors de l'exécution de la requête.

Interruptions

Les espaces sont les distances entre les mots. Espace blanc, ponctuation, mise en forme ou simplement la nature de la langue elle-même peut provoquer des ruptures. Il existe quatre types de sauts différents que l’indexeur utilise : fin de mot (EOW), fin de phrase (EOS), fin du paragraphe (EOP) et fin du chapitre (EOC). La pause EOW est la pause par défaut. Après chaque jeton, chaque pause indique un écart sémantique différent entre les mots de chaque côté. Les mots séparés par EOW ont le lien sémantique le plus étroit, suivi d’EOS, EOP et EOC. Plusieurs appels à IWordSink::PutBreak sont cumulatifs et sont analogues à l’insertion de mots ou de phrases nulles.

Scalabilité, exécution et sécurité

La façon dont le segmentateur de mots répond aux appels simultanés est largement déterminée par votre choix de modèle de gestion des threads. L’indexeur est une application monothread. Pour que les analyseurs de mots fonctionnent dans un environnement monothread, les analyseurs de mots doivent être écrits à l’aide d’un modèle de thread « libre » ou « les deux ». Les séparateurs de mots ne doivent pas s’inscrire auprès de COM en utilisant le modèle de threading « appartement ».

Nous recommandons que les séparateurs de mots évitent les états globaux et stockent les données dans l'instance du séparateur de mots. Le seul contenu qui doit être stocké dans l’implémentation de l’analyseur de mots concerne les paramètres fQuery et ulMaxTokenSize. Les analyseurs de mots ne doivent pas être plus de deux fois plus lents que le benchmark établi par l’analyseur de mots anglais. Les performances du segmentateur de mots devraient également s’améliorer avec une puissance matérielle accrue.

Les séparateurs de mots pour l’indexeur s’exécutent dans le contexte de sécurité du système local. Ils doivent être conçus pour gérer les mémoires tampons et pour s'empiler correctement. Toutes les copies de chaîne doivent avoir des vérifications explicites pour se protéger contre les débordements de mémoire tampon. Vous devez toujours vérifier la taille allouée de la mémoire tampon et tester la taille des données par rapport à la taille de la mémoire tampon. Les analyseurs de mots ne peuvent pas supposer que le texte passé à la méthode IWordBreaker::BreakText est bien formé. Pour plus d’informations sur la résolution des problèmes liés aux séparateurs de mots, consultez Résolution des problèmes liés aux ressources linguistiques et aux meilleures pratiques.

Implémentation d’un stemmer

Les stemmers implémentent l’interface IStemmer. La méthode IStemmer ::GenerateWordForms génère une liste de formulaires de mots inlectés pour un mot d’entrée particulier. Pour implémenter un composant de générateur de formes dérivées, vous devez avoir des heuristiques linguistiques pour votre langue. Cela inclut des informations sur la morphologie. Vous pouvez également avoir besoin d’une liste de mots pour exclure ou inclure. Pour plus d’informations sur les considérations linguistiques et sur la façon dont ces considérations affectent les implémentations de générateur de formes dérivées, consultez Considérations linguistiques et Unicode.

Nous vous recommandons de ne pas générer le génitif, ou le cas possessif, pour les mots. Par exemple, « David » n’est pas généré comme une forme alternative pour « David's ». L'analyseur de mots génère à la fois « David » et « de David » quand il analyse « David’s ».

Le générateur de formes dérivées utilise l’objet IWordFormSink pour rassembler la liste des mots alternatifs. IWordFormSink::PutWord génère le mot final à partir de l'analyseur morphologique. Dans tous les cas, ce dernier mot est identique au mot d’entrée de IStemmer ::GenerateWordForms. Par exemple, étant donné le mot « nager », le stemming génère les formes de mots suivantes : « nage », « nageant », « nageur », « nageait » et « nagé », par le biais d’appels à IWordFormSink::PutAltWord. Le générateur de tiges génère « nager » via IWordFormSink ::P utWord.

Scalabilité, exécution et sécurité

Les lemmatiseurs, comme les séparateurs de mots, doivent utiliser un modèle de thread « libre » et s’inscrire auprès de COM avec leur modèle de threading défini sur « libre » ou « les deux ». Windows Search appelle des instances distinctes du lemmatiseur à partir de différents threads en même temps. Les générateurs de formes dérivées doivent donc avoir des données d’instance minimales.

La précision du racineur a un impact significatif sur la pertinence des requêtes. Si le générateur de formes dérivées génère le texte de manière incorrecte, les requêtes peuvent retourner des résultats imprévisibles et incorrects. Les analyseurs morphologiques doivent gérer des centaines de requêtes par seconde sans affecter négativement la performance des requêtes. Les performances du générateur de souches doivent s’améliorer avec une capacité matérielle accrue. Pour plus d’informations sur la résolution des problèmes liés aux générateurs de formes dérivées, consultez Résolution des problèmes liés aux ressources linguistiques et aux meilleures pratiques.

Les racineurs pour Windows Search s’exécutent dans le contexte de sécurité locale. Ils doivent être conçus pour gérer les mémoires tampons et pour s'empiler correctement. Toutes les copies de chaîne doivent avoir des vérifications explicites pour se protéger contre les débordements de mémoire tampon. Vous devez toujours vérifier la taille allouée de la mémoire tampon et tester la taille des données par rapport à la taille de la mémoire tampon.

Extension des ressources linguistiques

Présentation des composants de ressources de langage

Considérations linguistiques et Unicode

Résolution des problèmes liés aux ressources linguistiques et aux meilleures pratiques