Więcej tagerów do narzędzi w języku naturalnym
Affix Tagger
Kolejną ważną klasą podklasy ContextTagger jest AffixTagger. W klasie AffixTagger kontekstem jest prefiks lub sufiks słowa. To jest powód, dla którego klasa AffixTagger może uczyć się tagów na podstawie podciągów o stałej długości początku lub końca słowa.
Jak to działa?
Jego działanie zależy od argumentu o nazwie długość_drostka, który określa długość przedrostka lub sufiksu. Wartością domyślną jest 3. Ale w jaki sposób rozróżnia, czy klasa AffixTagger ma przedrostek czy sufiks słowa?
affix_length=positive - Jeśli wartość affix_lenght jest dodatnia, oznacza to, że klasa AffixTagger nauczy się przedrostków słów.
affix_length=negative - Jeśli wartość affix_lenght jest ujemna, oznacza to, że klasa AffixTagger nauczy się przyrostków słów.
Aby było to bardziej zrozumiałe, w poniższym przykładzie będziemy używać klasy AffixTagger na tagowanych zdaniach banku drzewa.
Przykład
W tym przykładzie AffixTagger nauczy się przedrostka słowa, ponieważ nie określamy żadnej wartości dla argumentu długość_drostka. Argument przyjmie domyślną wartość 3 -
from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Prefix_tagger = AffixTagger(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
Prefix_tagger.evaluate(test_sentences)
Wynik
0.2800492099250667
Zobaczmy w poniższym przykładzie, jaka będzie dokładność, gdy podamy wartość 4 do argumentu długość_drostka -
from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Prefix_tagger = AffixTagger(train_sentences, affix_length=4 )
test_sentences = treebank.tagged_sents()[1500:]
Prefix_tagger.evaluate(test_sentences)
Wynik
0.18154947354966527
Przykład
W tym przykładzie AffixTagger nauczy się sufiksu słowa, ponieważ określimy wartość ujemną argumentu długość_drostka.
from nltk.tag import AffixTagger
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
Suffix_tagger = AffixTagger(train_sentences, affix_length = -3)
test_sentences = treebank.tagged_sents()[1500:]
Suffix_tagger.evaluate(test_sentences)
Wynik
0.2800492099250667
Brill Tagger
Brill Tagger to tagger oparty na transformacji. NLTK zapewniaBrillTagger klasa, która jest pierwszym taggerem, który nie jest podklasą SequentialBackoffTagger. W przeciwieństwie do niego, szereg reguł korygujących wyniki początkowego taggera jest używany przezBrillTagger.
Jak to działa?
Aby wyszkolić BrillTagger klasa przy użyciu BrillTaggerTrainer definiujemy następującą funkcję -
def train_brill_tagger(initial_tagger, train_sentences, **kwargs) -
templates = [
brill.Template(brill.Pos([-1])),
brill.Template(brill.Pos([1])),
brill.Template(brill.Pos([-2])),
brill.Template(brill.Pos([2])),
brill.Template(brill.Pos([-2, -1])),
brill.Template(brill.Pos([1, 2])),
brill.Template(brill.Pos([-3, -2, -1])),
brill.Template(brill.Pos([1, 2, 3])),
brill.Template(brill.Pos([-1]), brill.Pos([1])),
brill.Template(brill.Word([-1])),
brill.Template(brill.Word([1])),
brill.Template(brill.Word([-2])),
brill.Template(brill.Word([2])),
brill.Template(brill.Word([-2, -1])),
brill.Template(brill.Word([1, 2])),
brill.Template(brill.Word([-3, -2, -1])),
brill.Template(brill.Word([1, 2, 3])),
brill.Template(brill.Word([-1]), brill.Word([1])),
]
trainer = brill_trainer.BrillTaggerTrainer(initial_tagger, templates, deterministic=True)
return trainer.train(train_sentences, **kwargs)
Jak widać, ta funkcja wymaga initial_tagger i train_sentences. To zajmujeinitial_tagger argument i listę szablonów, które implementują BrillTemplateberło. PlikBrillTemplate interfejs znajduje się w nltk.tbl.templatemoduł. Jedną z takich implementacji jestbrill.Template klasa.
Główną rolą taggera opartego na transformacji jest generowanie reguł transformacji, które korygują wyjściowe dane wyjściowe taggera, aby były bardziej zgodne ze zdaniami szkoleniowymi. Zobaczmy poniżej przepływ pracy -
Przykład
W tym przykładzie będziemy używać combine_tagger który stworzyliśmy podczas przeczesywania taggerów (w poprzedniej recepturze) z łańcucha wycofywania plików NgramTagger klasy, jak initial_tagger. Najpierw oceńmy wynik za pomocąCombine.tagger a następnie użyj tego jako initial_tagger trenować brill tagger.
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)
Wynik
0.9234530029238365
Zobaczmy teraz, kiedy wynik oceny Combine_tagger jest używany jako initial_tagger trenować brill tagger -
from tagger_util import train_brill_tagger
brill_tagger = train_brill_tagger(combine_tagger, train_sentences)
brill_tagger.evaluate(test_sentences)
Wynik
0.9246832510505041
Możemy to zauważyć BrillTagger klasa ma nieznacznie zwiększoną dokładność w stosunku do Combine_tagger.
Kompletny przykład wdrożenia
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)
from tagger_util import train_brill_tagger
brill_tagger = train_brill_tagger(combine_tagger, train_sentences)
brill_tagger.evaluate(test_sentences)
Wynik
0.9234530029238365
0.9246832510505041
TnT Tagger
TnT Tagger, skrót od Trigrams'nTags, jest taggerem statystycznym opartym na modelach Markowa drugiego rzędu.
Jak to działa?
Możemy zrozumieć działanie taggera TnT za pomocą następujących kroków -
Najpierw w oparciu o dane treningowe, TnT tegger utrzymuje kilka wewnętrznych FreqDist i ConditionalFreqDist instancje.
Po tym unigramach, bigramach i trygramach zostaną zliczone przez te rozkłady częstotliwości.
Teraz, podczas tagowania, używając częstotliwości, obliczy prawdopodobieństwo możliwych tagów dla każdego słowa.
Dlatego zamiast tworzyć łańcuch wycofywania NgramTagger, używa wszystkich modeli ngram razem, aby wybrać najlepszy znacznik dla każdego słowa. Oceńmy dokładność ze znacznikiem TnT w następującym przykładzie -
from nltk.tag import tnt
from nltk.corpus import treebank
train_sentences = treebank.tagged_sents()[:2500]
tnt_tagger = tnt.TnT()
tnt_tagger.train(train_sentences)
test_sentences = treebank.tagged_sents()[1500:]
tnt_tagger.evaluate(test_sentences)
Wynik
0.9165508316157791
Mamy trochę mniej dokładności niż Brill Tagger.
Pamiętaj, że musimy zadzwonić train() przed evaluate() w przeciwnym razie uzyskamy 0% dokładności.