Natural-language-toolkit-transforming-chunks

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

自然言語ツールキット-チャンクの変換

チャンクを変換する理由

これまで、文からチャンクまたはフレーズを取得しましたが、それらをどうするかです。 重要なタスクの1つは、それらを変換することです。 しかし、なぜ? それは次のことをすることです-

  • 文法修正と
  • フレーズの並べ替え

重要でない/役に立たない単語のフィルタリング

フレーズの意味を判断したい場合、「the」、「a」などの一般的に使用される多くの単語が重要ではないか、役に立たないとします。 たとえば、次のフレーズを参照してください-

「映画は良かった」。

ここで最も重要な言葉は「映画」と「良い」です。 つまり、「the」と「was」はどちらも役に立たないか、意味がありません。 それがなければ、フレーズの意味も同じになるからです。 '良い映画'。

次のpythonレシピでは、不要な/重要でない単語を削除し、POSタグを使用して重要な単語を保持する方法を学習します。

まず、 treebank コーパスを調べてストップワードを探し、重要な品詞タグと重要でないものを決定する必要があります。 意味のない単語とタグの次の表を見てみましょう-

Word Tag
a DT
All PDT
An DT
And CC
Or CC
That WDT
The DT

上記の表から、CC以外がわかります。他のすべてのタグはDTで終わります。つまり、タグのサフィックスを調べることで、意味のない単語を除外できます。

この例では、* filter()*という名前の関数を使用します。この関数は、単一のチャンクを取得し、意味のないタグ付き単語なしで新しいチャンクを返します。 この関数は、DTまたはCCで終わるタグをすべて除外します。

import nltk
def filter(chunk, tag_suffixes=['DT', 'CC']):
   significant = []
   for word, tag in chunk:
      ok = True
      for suffix in tag_suffixes:
         if tag.endswith(suffix):
            ok = False
            break
      if ok:
         significant.append((word, tag))
   return (significant)

次に、Pythonレシピでこの関数filter()を使用して、重要でない単語を削除します-

from chunk_parse import filter
filter([('the', 'DT'),('good', 'JJ'),('movie', 'NN')])

出力

[('good', 'JJ'), ('movie', 'NN')]

動詞修正

多くの場合、実際の言語では、動詞の形式が正しくありません。 たとえば、「あなたは元気ですか?」は正しくありません。 この文では、動詞の形式が正しくありません。 センテンスは「大丈夫ですか?」とする必要があります。NLTKは、動詞修正マッピングを作成することにより、そのような間違いを修正する方法を提供します。 これらの修正マッピングは、チャンクに複数の名詞があるのか​​、単数の名詞があるのか​​に応じて使用されます。

Pythonレシピを実装するには、まず動詞修正マッピングを定義する必要があります。 次のように2つのマッピングを作成しましょう-

複数から単数へのマッピング

plural= {
   ('is', 'VBZ'): ('are', 'VBP'),
   ('was', 'VBD'): ('were', 'VBD')
}

単数から複数へのマッピング

singular = {
   ('are', 'VBP'): ('is', 'VBZ'),
   ('were', 'VBD'): ('was', 'VBD')
}

上記のように、各マッピングには、別のタグ付き動詞にマップするタグ付き動詞があります。 この例の初期マッピングは、 _ is to are、was to was_ 、およびその逆の基本的なマッピングをカバーしています。

次に、* verbs()という名前の関数を定義します。この関数では、不適切な動詞の形式でチャンクを渡し、修正されたチャンクを取得できます。 それを行うために、 verb()関数は index_chunk()*という名前のヘルパー関数を使用します。これは、チャンクで最初のタグ付けされた単語の位置を検索します。

これらの関数を見てみましょう-

def index_chunk(chunk, pred, start = 0, step = 1):
   l = len(chunk)
   end = l if step > 0 else -1
   for i in range(start, end, step):
      if pred(chunk[i]):
         return i
      return None
def tag_startswith(prefix):
   def f(wt):
      return wt[1].startswith(prefix)
   return f

def verbs(chunk):
   vbidx = index_chunk(chunk, tag_startswith('VB'))
   if vbidx is None:
      return chunk
   verb, vbtag = chunk[vbidx]
   nnpred = tag_startswith('NN')
   nnidx = index_chunk(chunk, nnpred, start = vbidx+1)
   if nnidx is None:
      nnidx = index_chunk(chunk, nnpred, start = vbidx-1, step = -1)
   if nnidx is None:
      return chunk
   noun, nntag = chunk[nnidx]
   if nntag.endswith('S'):
      chunk[vbidx] = plural.get((verb, vbtag), (verb, vbtag))
   else:
      chunk[vbidx] = singular.get((verb, vbtag), (verb, vbtag))
   return chunk

これらの関数を、PythonまたはAnacondaがインストールされているローカルディレクトリのPythonファイルに保存し、実行します。 verbcorrect.py として保存しました。

今度は、* verbs()関数をタグ付きのPOSで呼び出しましょう *is you fine チャンク-

from verbcorrect import verbs
verbs([('is', 'VBZ'), ('you', 'PRP$'), ('fine', 'VBG')])

出力

[('are', 'VBP'), ('you', 'PRP$'), ('fine','VBG')]

フレーズからの受動態の排除

もう1つの便利なタスクは、フレーズから受動態を排除することです。 これは、動詞の前後の単語を交換することで実行できます。 たとえば、 _ ‘the tutorial was great' ' は ' ‘the great tutorial’ _ に変換できます。

これを実現するために、動詞をピボットポイントとして使用して、チャンクの右側と左側を入れ替える* eliminate_passive()という名前の関数を定義しています。 ピボットする動詞を見つけるために、上で定義した index_chunk()*関数も使用します。

def eliminate_passive(chunk):
   def vbpred(wt):
      word, tag = wt
      return tag != 'VBG' and tag.startswith('VB') and len(tag) > 2
   vbidx = index_chunk(chunk, vbpred)
   if vbidx is None:
      return chunk
   return chunk[vbidx+1:] + chunk[:vbidx]

今、私たちはタグ付けされたPOSで* eliminate_passive()*関数を呼び出しましょう*チュートリアルは素晴らしかった*チャンク-

from passiveverb import eliminate_passive
eliminate_passive(
   [
      ('the', 'DT'), ('tutorial', 'NN'), ('was', 'VBD'), ('great', 'JJ')
   ]
)

出力

[('great', 'JJ'), ('the', 'DT'), ('tutorial', 'NN')]

名詞の枢機卿の入れ替え

ご存知のように、5などの主要な単語はチャンク内のCDとしてタグ付けされます。 これらの主要な単語は、名詞の前または後に現れることがよくありますが、正規化の目的では、常に名詞の前に置くと便利です。 たとえば、日付 January 55 January と書くことができます。 次の例でそれを理解しましょう。

これを実現するために、名詞の直後に発生する基数を名詞と交換する* swapping_cardinals()という名前の関数を定義しています。 これにより、枢機卿は名詞の直前に出現します。 指定されたタグとの等価比較を行うために、 tag_eql()*という名前のヘルパー関数を使用します。

def tag_eql(tag):
   def f(wt):
      return wt[1] == tag
   return f

今、私たちはswapping_cardinals()を定義することができます-

def swapping_cardinals (chunk):
   cdidx = index_chunk(chunk, tag_eql('CD'))
   if not cdidx or not chunk[cdidx-1][1].startswith('NN'):
      return chunk
   noun, nntag = chunk[cdidx-1]
   chunk[cdidx-1] = chunk[cdidx]
   chunk[cdidx] = noun, nntag
   return chunk

ここで、日付に* swapping_cardinals()関数を呼び出しましょう「1月5日」*-

from Cardinals import swapping_cardinals()
swapping_cardinals([('Janaury', 'NNP'), ('5', 'CD')])

出力

[('10', 'CD'), ('January', 'NNP')]
10 January