Nltk: Discussion : Ressusciter le modèle Ngram

Créé le 25 mars 2016  ·  21Commentaires  ·  Source: nltk/nltk

Salut les gens!

Je travaille pour m'assurer que le module Ngram Model pourrait être rajouté dans NLTK et j'aimerais soulever quelques problèmes pour discussion.

Numéro 1
Ici, @afourney a dit qu'il serait bien d'ajouter l'interpolation comme alternative au backoff Katz par défaut comme moyen de gérer les ngrams invisibles. J'y ai réfléchi et j'ai peut-être une idée de comment cela pourrait fonctionner. Je voudrais l'exécuter par toutes les parties intéressées.

La structure de classe actuelle du module model est la suivante :

  • model.api.ModelI -> c'est censé être une classe abstraite ou une interface, je suppose.
  • model.ngram.NgramModel -> s'étend au-dessus de la classe, contient l'implémentation actuelle du modèle ngram.

Voici ce que je propose :

  • model.api.Model -> Honnêtement, je ne suis pas sûr d'en voir l'intérêt, ambivalent quant à savoir s'il faut le garder ou l'abandonner.
  • model.ngram.BasicNgramModel -> C'est la même chose que NgramModel , moins tout ce qui a à voir avec le backoff. Fondamentalement, il ne peut pas gérer les ngrams invisibles à l'entraînement. « Pourquoi avoir ça ? » - vous pourriez demander. Je pense que ce serait une excellente démonstration du besoin de backoff/interpolation. Les étudiants peuvent simplement l'essayer et voir à quel point il fonctionne mal pour se convaincre d'utiliser les autres classes.
  • model.ngram.BackoffNgramModel -> hérite de BasicNgramModel pour produire l'implémentation actuelle de NgramModel , sauf que c'est plus explicite sur la partie backoff.
  • model.ngram.InterpolatedNgramModel -> hérite également de BasicNgramModel , mais utilise l'interpolation au lieu du backoff.

Les objectifs à long terme sont ici :

a) pour permettre à n'importe quelle classe ProbDist d'être utilisée comme estimateur de probabilité puisque l'interpolation/l'attente sont (principalement) indépendantes de l'algorithme de lissage utilisé.
b) pour permettre à quiconque souhaite _optimiser_ un NgramModel à ses propres fins d'hériter facilement de certaines valeurs par défaut utiles des classes de NLTK.

Numéro 2
Malheureusement, le module de probabilité a ses propres problèmes (par exemple, #602 et (mon) implémentation Kneser-Ney est bancale). Donc, pour l'instant, je ne teste l'exactitude qu'avec LidstoneProbDist , car il est facile à calculer à la main. Dois-je m'inquiéter du manque de prise en charge des méthodes de lissage les plus avancées ? Ou voulons-nous peut-être procéder de cette façon pour nous assurer au moins que le modèle Ngram fonctionne, et _ensuite_ aborder les classes de probabilité problématiques séparément ?

Python 3 super()
Lorsque j'appelle super() , dois-je m'inquiéter de la prise en charge de python 2 ? Voir ceci pour le contexte.

corpus enhancement language-model nice idea tests

Commentaire le plus utile

Je pense que cela vaut vraiment la peine d'avoir dans NLTK; c'est une partie essentielle de quand je
enseigner la PNL.

NLTK prend-il en charge les LM profonds maintenant ? Cette API est-elle compatible avec cela ?


Jordan Boyd Graber

Voix : 920.524.9464
[email protected]

http://boydgraber.org

Le mardi 3 octobre 2017 à 23h32, alvations [email protected] a écrit :

@Copper-Head https://github.com/copper-head @jacobheil
https://github.com/jacobheil et les utilisateurs/devs NLTK qui sont intéressés par
Modèles de langage n-gramme.

Tout comme pour vérifier l'état actuel du sous-module de modèle.

  • Pensez-vous qu'il est prêt à le pousser dans le développement/master
    branche?
  • Est-ce toujours un sujet que les gens poursuivent activement et veulent voir sur
    NLTK ?

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nltk/nltk/issues/1342#issuecomment-334041035 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAhoqh5oxzo2Y9mp88I8uwy4lmyNz9Amks5sovxngaJpZM4H4nGe
.

Tous les 21 commentaires

Ce serait bien d'avoir une bibliothèque n-gram fonctionnelle dans NLTK. SRILM a quelques wrappers Python pour l'inférence, mais il a une licence restrictive. KenLM a un wrapper Python pour faire de l'inférence, mais il a des dépendances dans la compilation. Ni l'un ni l'autre n'a de support pour l'estimation. Il n'y a donc actuellement aucun outil n-gram bien testé disponible pour Python NLP.

@anttttti Merci pour le retour, je me sens très motivé pour soumettre un patch vu toute cette demande pour la fonctionnalité :)

Avez-vous des idées sur les problèmes spécifiques que j'ai publiés?

Les méthodes de lissage avancées sont simples à mettre en œuvre une fois que vous comprenez qu'elles ne diffèrent que par la manière dont l'actualisation et l'interpolation sont définies. Les articles antérieurs et la plupart des descriptions des manuels donnent l'impression que les modèles sont plus compliqués qu'ils ne le sont, car les gens ne comprenaient pas bien les liens plus tôt. Il ne devrait pas y avoir besoin de modules séparés, juste la configuration du lissage. Les anciens modèles de backoff qui n'étaient pas correctement normalisés ne sont pas utilisés de nos jours, voir "A Bit of Progress in Language Modeling" de Joshua Goodman pour un excellent résumé. http://arxiv.org/pdf/1602.02332.pdf page 63 résume quelques choix pour l'actualisation et l'interpolation pour un cas d'unigramme, les modèles d'ordre supérieur utilisent le même récursivement. Kneser-Ney est un peu plus délicat avec les backoffs modifiés.

Le lissage n'est pas si critique pour la plupart des utilisations. Avec suffisamment de données, même optimisé, Kneser-Ney n'est pas meilleur que Stupid Backoff. Donc, avoir simplement des n-grammes d'ordre élevé disponibles en Python avec n'importe quel lissage de base serait bien. Lidstone ou Jelinek-Mercer pour chaque commande devrait fonctionner parfaitement.

Problème 1) Une chose que je pense serait très utile est d'avoir un utilitaire pour construire un vocabulaire et censurer les jetons OOV. Cela corrigerait bon nombre des erreurs stupides qui ont frustré les utilisateurs avec les anciennes versions. Je joins un code qui fait cela (n'hésitez pas à utiliser ou à copier)
lm.txt

Question 2a) Je pense qu'il est toujours utile d'avoir Kneser-Ney ; c'est couramment enseigné et il est utile d'avoir une implémentation de référence.
Problème 2b) Je crains que le couplage de ProDist ne rende cela beaucoup plus compliqué qu'il ne devrait l'être. Il pourrait être plus simple de conserver l'estimation de probabilité dans le modèle de langage pour des choses comme KN. Pour d'autres modèles, il peut être judicieux d'utiliser ProbDist.

@anttttti "_Les méthodes de lissage avancées sont simples à mettre en œuvre une fois que vous comprenez qu'elles ne diffèrent que par la façon dont l'actualisation et l'interpolation sont définies_"

@ezubaric "_Issue 2b) Je crains que le couplage de ProbDist ne rende cela beaucoup plus compliqué qu'il ne devrait l'être_"

Bien que je n'aie pas regardé ce code depuis un moment, j'ai l'impression que ces deux déclarations sont vraies.

Si je me souviens bien, ConditionalProbDist (et plus généralement ProbDist) sont normalisés trop tôt pour être utilisés dans les modèles ngram lissés. Par exemple, bien que nous sachions quelle est la probabilité d'un mot dans un contexte donné, nous avons du mal à raisonner sur les contextes eux-mêmes (je crois qu'un correctif précédent a tenté de corriger ce problème - malgré tous les efforts, c'était un peu compliqué [https : //github.com/nltk/nltk/pull/800]).

À mon humble avis, le tout est légèrement surconçu.

@afourney

À mon humble avis, le tout est légèrement surconçu.

Amen à cela! J'essaie de faire en sorte que cela fonctionne depuis toujours (j'ai soumis le #800 et oui, ce n'était pas du tout élégant) et je commence aussi à penser qu'il y a trop de pièces mobiles pour que ce soit raisonnable.

@ezubaric merci beaucoup pour ce fichier,

Sur la base de tous ces retours, voici ma nouvelle vision de la structure du module. Nous n'avons qu'une seule classe : model.ngram.NgramModelCounter .

Il s'agit essentiellement de plusieurs compteurs FreqDist combinés dans une interface claire. _Entraînement_ consiste simplement à compter de manière récursive le nombre de ngrams ainsi qu'à garder une trace de la taille du vocabulaire (avec potentiellement "finaliser" certains de ces décomptes pour empêcher les mises à jour une fois l'entraînement terminé). @alvations Je sais que vous aimeriez une implémentation trie pour cela, mais je pense que nous pouvons commencer avec un compteur récursif inefficace pour le moment et refactoriser le backend plus tard car cela ne devrait pas beaucoup affecter l'interface.

Fondamentalement, cette classe ne traite pas des probabilités du tout. Cela devrait rendre les choses beaucoup plus simples et en même temps plus flexibles. Tout ce que n'importe qui a besoin de faire pour ajouter des probabilités est d'utiliser sa méthode de POO préférée (par exemple l'héritage ou la composition) pour écrire une classe qui utilise les attributs de NgramModel pour construire sa propre méthode prob() .

Si j'ai le temps, je soumettrai un (ou deux !) exemples de la façon dont l'ajout de probabilités à NgramModelCounter pourrait fonctionner.

Qu'en pensez-vous?

@Copper-Head ayant autant que possible une interface similaire à KenLM serait bon pour une intégration future : https://github.com/kpu/kenlm/blob/master/python/example.py

Je pense qu'après la mise en place d'une version stable de NgramModel de NLTK, je peux essayer de refactoriser kenlm wrapper pour utiliser une interface similaire à celle de NLTK, comme ce que nous avons fait pour scikit-learn .

Cette fonction aiderait aussi dans le rembourrage : https://github.com/nltk/nltk/blob/develop/nltk/util.py#L381

Je pense que @Copper-Head suggère une classe qui compte les unigrammes, les bigrammes, les trigrammes, etc. d'une manière coordonnée qui est pratique à consommer par les modèles de langage en aval. Dans ce cas, je pense que l'API kenlm ne s'applique pas encore. (Je me trompe peut-être, mais d'après l'exemple publié, cela ne ressemble pas aux offres de l'API kenlm en nombre de fréquences brutes)

Je pense qu'il vaut également la peine d'envisager une API de modèle de langage minimal qui consomme ces nombres de ngrams. Comme le suggère @Copper-Head, ce serait une sous-classe, ou mieux encore, une interface complètement séparée (permettant des implémentations très différentes comme https://www.projectoxford.ai/weblm). Ici, je pense qu'il peut être raisonnable d'adopter l'API kenlm, mais je pense que l'interface _any_ ngram LM devrait être suffisamment simple pour que les adaptateurs puissent être facilement écrits.

Je pense qu'une API ngram minimale n'a vraiment besoin que de méthodes pour (1) calculer la probabilité conditionnelle d'un jeton étant donné un contexte ou une séquence, et (2) rendre compte de la taille et de la composition du vocabulaire connu. Presque tout le reste peut être calculé via des méthodes d'assistance, y compris les calculs de probabilité conjointe, ainsi que la génération de langage. Ces aides peuvent ou non faire partie de l'interface.

Hum, point intéressant. Je me demande cependant si le suivi de ces comptes pour GT pourrait ralentir un peu l'entraînement et inutilement pour les gens qui ne veulent pas utiliser ce lissage particulier. Je pense qu'il pourrait être plus logique de faire le minimum dans la classe de base NgramCounter puis d'étendre simplement sa méthode d'entraînement (ou __init__ ) dans une sous-classe spécialisée pour le Good-Turing, ou même dans un implémentation de l'API ngram orientée vers le calcul des probabilités de Good-Turing.
Mais je ne fais que m'asseoir pour écrire certains de ces trucs, alors peut-être que cela ne finira pas par être un problème à la fin.

Désolé, il semble que j'ai accidentellement supprimé un message. Pour combler le contexte manquant pour les futurs lecteurs : Je pense qu'il serait bon d'envisager des techniques de lissage courantes lors de la conception de l'API NgramModelCounter. Par exemple, permettre aux utilisateurs d'interroger le nombre d'_espèces_ observées une fois, deux fois ou N fois est important pour le lissage de Good-Turing (ainsi que le lissage de Witten-Bell, etc.)

Edit : il semble que la classe FreqDist en ait déjà une (voir : FreqDist.hapaxes et FreqDist.r_Nr) Je me demande si elle peut être réutilisée ? Ou si FreqDist doit être le point de départ.

J'aime l'idée d'avoir simplement un objet counts qui peut ensuite être interrogé avec des sous-classes qui implémentent des méthodes de lissage spécifiques.

Ma seule préoccupation est que la formation aura des problèmes si nous n'avons pas la possibilité de corriger le vocabulaire tôt : cela ne sera pas cohérent avec les processus de formation LM standard, et le suivi de tout le vocabulaire ferait exploser la mémoire (ce qui était un gros problème avec l'ancien LM aussi).

Noté. J'ai des idées pour résoudre ce problème. Je posterai un PR plus tard aujourd'hui.

PR #1351 est en place !! Apportez les questions / pinailles :)

@Copper-Head - à quelle distance sommes-nous de pouvoir fusionner cela dans la branche principale?

En regardant ma liste de choses à faire, je dirais que j'ai besoin de 2-3 jours de travail ciblé.
Considérant que je suis de retour à travailler là-dessus pendant mon temps libre après l'école et mon travail de jour, je lui donnerais entre 2 semaines et un mois avant d'avoir fini avec tous mes problèmes en suspens. Cela ne tient naturellement pas compte des éléments aléatoires qui pourraient être portés à mon attention à ce moment-là.

@Copper-Head @jacobheil et les utilisateurs/devs NLTK qui s'intéressent aux modèles de langage N-gram.

Tout comme pour vérifier l'état actuel du sous-module model .

  • Pensez-vous qu'il est prêt à le pousser dans la branche develop/master ?
  • Est-ce toujours un sujet que les gens poursuivent activement et veulent voir sur NLTK ?

Je pense que cela vaut vraiment la peine d'avoir dans NLTK; c'est une partie essentielle de quand je
enseigner la PNL.

NLTK prend-il en charge les LM profonds maintenant ? Cette API est-elle compatible avec cela ?


Jordan Boyd Graber

Voix : 920.524.9464
[email protected]

http://boydgraber.org

Le mardi 3 octobre 2017 à 23h32, alvations [email protected] a écrit :

@Copper-Head https://github.com/copper-head @jacobheil
https://github.com/jacobheil et les utilisateurs/devs NLTK qui sont intéressés par
Modèles de langage n-gramme.

Tout comme pour vérifier l'état actuel du sous-module de modèle.

  • Pensez-vous qu'il est prêt à le pousser dans le développement/master
    branche?
  • Est-ce toujours un sujet que les gens poursuivent activement et veulent voir sur
    NLTK ?

-
Vous recevez ceci parce que vous avez été mentionné.
Répondez directement à cet e-mail, consultez-le sur GitHub
https://github.com/nltk/nltk/issues/1342#issuecomment-334041035 , ou couper le son
le fil
https://github.com/notifications/unsubscribe-auth/AAhoqh5oxzo2Y9mp88I8uwy4lmyNz9Amks5sovxngaJpZM4H4nGe
.

Salut - J'aimerais utiliser l'"ancienne" fonctionnalité du modèle de langue dans NLTK. Quelle est la dernière version qui possède toujours le modèle linguistique pré-entraîné (pour l'anglais) ?

Pour ceux qui trouvent ce fil, j'ai en quelque sorte assemblé un sous-module contenant l'ancien code de modèle.

https://github.com/sleepyfoxen/nltk_model

@stevenbird, je pense que nous pouvons enfin fermer ça :)

Pour obtenir des commentaires concrets sur la mise en œuvre existante, les utilisateurs peuvent ouvrir des problèmes distincts.

@Copper-Head oui je suis d'accord. Toutes nos félicitations! :)

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

stevenbird picture stevenbird  ·  3Commentaires

libingnan54321 picture libingnan54321  ·  3Commentaires

peterbe picture peterbe  ·  5Commentaires

alvations picture alvations  ·  4Commentaires

stevenbird picture stevenbird  ·  4Commentaires