Boîte à outils en langage naturel - Combiner des tagueurs

Combiner des tagueurs

Combiner des marqueurs ou enchaîner des étiqueteurs les uns avec les autres est l'une des caractéristiques importantes de NLTK. Le concept principal derrière la combinaison des marqueurs est que, au cas où un marqueur ne sait pas comment étiqueter un mot, il serait passé au marqueur enchaîné. Pour atteindre cet objectif,SequentialBackoffTagger nous fournit le Backoff tagging fonctionnalité.

Balisage d'interruption

Comme indiqué précédemment, le balisage d'interruption est l'une des caractéristiques importantes de SequentialBackoffTagger, ce qui nous permet de combiner des tagueurs de telle sorte que si un tagueur ne sait pas comment taguer un mot, le mot serait passé au tagger suivant et ainsi de suite jusqu'à ce qu'il n'y ait plus de taggeurs backoff à vérifier.

Comment ça marche?

En fait, chaque sous-classe de SequentialBackoffTaggerpeut prendre un argument de mot-clé «backoff». La valeur de cet argument de mot-clé est une autre instance d'unSequentialBackoffTagger. Maintenant chaque fois que çaSequentialBackoffTaggerclass est initialisée, une liste interne de taggers backoff (avec elle-même comme premier élément) sera créée. De plus, si un tagger backoff est donné, la liste interne de ces taggers backoff sera ajoutée.

Dans l'exemple ci-dessous, nous prenons DefaulTagger comme tagger backoff dans la recette Python ci-dessus avec laquelle nous avons formé le UnigramTagger.

Exemple

Dans cet exemple, nous utilisons DefaulTaggeren tant que tagueur de backoff. Chaque fois que leUnigramTagger ne peut pas baliser un mot, backoff tagger, ie DefaulTagger, dans notre cas, le marquera avec «NN».

from nltk.tag import UnigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Uni_tagger = UnigramTagger(train_sentences, backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Uni_tagger.evaluate(test_sentences)

Production

0.9061975746536931

À partir de la sortie ci-dessus, vous pouvez observer qu'en ajoutant un tagger backoff, la précision est augmentée d'environ 2%.

Sauver les tagueurs avec du cornichon

Comme nous l'avons vu, la formation d'un tagueur est très lourde et prend également du temps. Pour gagner du temps, nous pouvons choisir un tagueur entraîné pour l'utiliser plus tard. Dans l'exemple ci-dessous, nous allons faire cela à notre tagueur déjà entraîné nommé‘Uni_tagger’.

Exemple

import pickle
f = open('Uni_tagger.pickle','wb')
pickle.dump(Uni_tagger, f)
f.close()
f = open('Uni_tagger.pickle','rb')
Uni_tagger = pickle.load(f)

Classe NgramTagger

À partir du diagramme hiérarchique discuté dans l'unité précédente, UnigramTagger est hérité de NgarmTagger class mais nous avons encore deux sous-classes de NgarmTagger classe -

Sous-classe BigramTagger

En fait, un ngram est une sous-séquence de n éléments, donc, comme son nom l'indique, BigramTaggerla sous-classe examine les deux éléments. Le premier élément est le mot étiqueté précédent et le deuxième élément est le mot étiqueté actuel.

Sous-classe TrigramTagger

Sur la même note de BigramTagger, TrigramTagger la sous-classe examine les trois éléments, c'est-à-dire deux mots étiquetés précédents et un mot étiqueté courant.

Pratiquement si nous postulons BigramTagger et TrigramTaggersous-classes individuellement comme nous l'avons fait avec la sous-classe UnigramTagger, elles fonctionnent toutes deux très mal. Voyons dans les exemples ci-dessous:

Utilisation de la sous-classe BigramTagger

from nltk.tag import BigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Bi_tagger = BigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Bi_tagger.evaluate(test_sentences)

Production

0.44669191071913594

Utilisation de la sous-classe TrigramTagger

from nltk.tag import TrigramTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Tri_tagger = TrigramTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Tri_tagger.evaluate(test_sentences)

Production

0.41949863394526193

Vous pouvez comparer les performances de UnigramTagger, que nous avons utilisé précédemment (donne une précision d'environ 89%) avec BigramTagger (donne une précision d'environ 44%) et TrigramTagger (donne une précision d'environ 41%). La raison en est que les tagueurs Bigram et Trigram ne peuvent pas apprendre le contexte à partir du ou des premiers mots d'une phrase. D'autre part, la classe UnigramTagger ne se soucie pas du contexte précédent et devine la balise la plus courante pour chaque mot, donc capable d'avoir une précision de base élevée.

Combiner des taggers ngram

À partir des exemples ci-dessus, il est évident que les tagueurs Bigram et Trigram peuvent contribuer lorsque nous les combinons avec le marquage backoff. Dans l'exemple ci-dessous, nous combinons des taggers Unigram, Bigram et Trigram avec un marquage backoff. Le concept est le même que la recette précédente en combinant l'UnigramTagger avec le tagger backoff. La seule différence est que nous utilisons la fonction nommée backoff_tagger () de tagger_util.py, donnée ci-dessous, pour l'opération d'interruption.

def backoff_tagger(train_sentences, tagger_classes, backoff=None):
   for cls in tagger_classes:
      backoff = cls(train_sentences, backoff=backoff)
   return backoff

Exemple

from tagger_util import backoff_tagger
from nltk.tag import UnigramTagger
from nltk.tag import BigramTagger
from nltk.tag import TrigramTagger
from nltk.tag import DefaultTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
back_tagger = DefaultTagger('NN')
Combine_tagger = backoff_tagger(train_sentences,
[UnigramTagger, BigramTagger, TrigramTagger], backoff = back_tagger)
test_sentences = treebank.tagged_sents()[1500:]
Combine_tagger.evaluate(test_sentences)

Production

0.9234530029238365

À partir de la sortie ci-dessus, nous pouvons voir qu'il augmente la précision d'environ 3%.