Natural-language-toolkit-combining-taggers

提供:Dev Guides
移動先:案内検索

自然言語ツールキット-タガーの組み合わせ

タガーを組み合わせる

タガーの組み合わせまたはタガー同士のチェーンは、NLTKの重要な機能の1つです。 タガーの組み合わせの背後にある主な概念は、1つのタガーが単語のタグ付け方法を知らない場合、チェーンされたタガーに渡されるということです。 この目的を達成するために、 SequentialBackoffTaggerBackoff tagging 機能を提供します。

バックオフのタグ付け

前に述べたように、バックオフタグ付けは SequentialBackoffTagger の重要な機能の1つです。これにより、1つのタガーが単語のタグ付け方法を知らない場合、単語が次のタガーに渡され、確認するバックオフタガーがなくなるまで続けます。

それはどのように機能しますか?

実際、 SequentialBackoffTagger のすべてのサブクラスは、「backoff」キーワード引数を取ることができます。 このキーワード引数の値は、 SequentialBackoffTagger の別のインスタンスです。 これで、この SequentialBackoffTagger クラスが初期化されるたびに、バックオフタガーの内部リスト(それ自体が最初の要素として)が作成されます。 さらに、バックオフタガーが指定されている場合、このバックオフタガーの内部リストが追加されます。

以下の例では、 UnigramTagger をトレーニングした上記のPythonレシピのバックオフタガーとして DefaulTagger を使用しています。

この例では、 DefaulTagger をバックオフタガーとして使用しています。 UnigramTagger が単語にタグ付けできない場合は常に、バックオフタガー、つまり この場合、 DefaulTagger は「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)

出力

0.9061975746536931

上記の出力から、バックオフタガーを追加することにより、精度が約2%向上することがわかります。

ピクルスでタガーを保存する

タガーのトレーニングは非常に面倒で時間がかかることもわかっています。 時間を節約するために、訓練されたタガーを後でピクルすることができます。 以下の例では、これを ‘Uni_tagger’ という名前のトレーニング済みのタガーに対して実行します。

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)

NgramTaggerクラス

前のユニットで説明した階層図から、 UnigramTaggerNgarmTagger クラスから継承されていますが、 NgarmTagger クラスのサブクラスが2つあります-

BigramTaggerサブクラス

実際、ngramはn項目のサブシーケンスであるため、名前が示すように、 BigramTagger サブクラスは2つの項目を調べます。 最初のアイテムは以前にタグ付けされた単語で、2番目のアイテムは現在タグ付けされた単語です。

TrigramTaggerサブクラス

*BigramTaggerの同じメモで、TrigramTagger* サブクラスは3つの項目、つまり 以前にタグ付けされた2つの単語と現在タグ付けされている1つの単語。

実際には、UnigramTaggerサブクラスで行ったように、 BigramTagger および TrigramTagger サブクラスを個別に適用すると、どちらも非常にパフォーマンスが低下します。 以下の例を見てみましょう。

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)

出力

0.44669191071913594

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)

出力

0.41949863394526193

以前使用していたUnigramTaggerのパフォーマンスを比較できます(精度は約89%を提供)。 その理由は、バイグラムとトライグラムのタガーは、文の最初の単語からコンテキストを学習できないためです。 一方、UnigramTaggerクラスは以前のコンテキストを気にせず、各単語の最も一般的なタグを推測するため、ベースラインの精度が高くなります。

Ngramタガーの組み合わせ

上記の例からわかるように、BigramとTrigramのタグ付け機能がバックオフのタグ付けと組み合わせると、これらの機能が貢献できることは明らかです。 以下の例では、Unigram、Bigram、Trigramのタグ付け機能とバックオフのタグ付けを組み合わせています。 コンセプトは前のレシピと同じですが、UnigramTaggerとバックオフタガーを組み合わせています。 唯一の違いは、バックオフ操作に、以下に示すtagger_util.pyのbackoff_tagger()という名前の関数を使用していることです。

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

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)

出力

0.9234530029238365

上記の出力から、精度が約3%向上していることがわかります。