2013-07-17 10 views
9

私はUnicode文字で英語以外のパーサーに取り組んでいます。そのために、NLTKを使うことにしました。NLTK文脈自由文法の制作

しかし、それは以下のように事前に定義された文脈自由文法を必要とします。私のアプリで

S -> NP VP 
    VP -> V NP | V NP PP 
    PP -> P NP 
    V -> "saw" | "ate" | "walked" 
    NP -> "John" | "Mary" | "Bob" | Det N | Det N PP 
    Det -> "a" | "an" | "the" | "my" 
    N -> "man" | "dog" | "cat" | "telescope" | "park" 
    P -> "in" | "on" | "by" | "with" 

は、Iは、ルールベースの文法を使用してハードコーディング最小限にすることが出来るのです。 たとえば、-edまたは-ingで終わる単語を動詞として想定できます。したがって、任意のコンテキストで動作するはずです。

どのようにNLTKにそのような文法規則を与えることができますか?または、Finite State Machineを使用して動的に生成しますか?

+1

[この回答](http://stackoverflow.com/questions/14096237/can-someone-give-a-simple-but-non-toy-example-of-a-context-sensitive -grammar/14099421#14099421)は、CFGを作成しているためです。 –

+0

ありがとうございます。私は見ましたが、それを理解できませんでした。 CFGにPython変数を与える方法はありますか? – ChamingaD

+0

CFGルールを自動的に学習したい場合は、次のURLを実装してみてください。www.aclweb.org/anthology/O06-1004 =) – alvas

答えて

2

多分あなたはparse_cfg()をお探しですか? NLTK帳のChapter 7から

> grammar = nltk.parse_cfg(""" 
S -> NP VP 
VP -> V NP | V NP PP 
V -> "saw" | "ate" 
NP -> "John" | "Mary" | "Bob" | Det N | Det N PP 
Det -> "a" | "an" | "the" | "my" 
N -> "dog" | "cat" | "cookie" | "park" 
PP -> P NP 
P -> "in" | "on" | "by" | "with" 
""") 

> sent = "Mary saw Bob".split() 
> rd_parser = nltk.RecursiveDescentParser(grammar) 
> for p in rd_parser.nbest_parse(sent): 
     print p 
(S (NP Mary) (VP (V saw) (NP Bob))) 
+0

ありがとうございます。しかし、それらの動詞や名詞はまだ難しいコードですか? CFGに文字列の値を渡すためにとにかくありますか? like V = variable_a – ChamingaD

+0

私はあなたが文字列を連結してからそれらを渡すことができると確信しています! http://stackoverflow.com/questions/12169839/ – arturomp

+0

実際に、あなたの元の質問で理解していることから、試してみるべきもう一つのことは、可能であれば完全にはわからない。部分的なPOSタグ付けは、あなたはCFGのVルールについて心配する必要はありません。 – arturomp

7

パーサーを作成する場合は、あなたが実際に解析する前に、POSタグ付けする工程を追加するを持っている- に成功する方法はありません文脈外の単語のPOSタグを決定する。たとえば、 'closed'は形容詞または動詞です。 POS-taggerは単語の文脈から正しいタグを見つけます。次に、POSタグャーの出力を使用してCFGを作成することができます。

既存の多くのPOSタグを使用できます。出力がされます

import nltk 
input_sentence = "Dogs chase cats" 
text = nltk.word_tokenize(input_sentence) 
list_of_tokens = nltk.pos_tag(text) 
print list_of_tokens 

:あなたは文法文字列を作成し、nltk.parse_cfg()にそれを供給するために使用することができます

[('Dogs', 'NN'), ('chase', 'VB'), ('cats', 'NN')] 

NLTKでは、あなたは、単にような何かを行うことができます。

+0

ありがとうございます。英語以外のパーサーで作業してもらえますか? – ChamingaD

+0

いいえ、しかし、NLTKでは非常に簡単な方法で独自のタグを訓練することができます。しかし、そうするためには、統計モデルを訓練するために、あなたの言語のタグ付きコーパスが必要になります。そのようなリソースにアクセスできますか?あなたが取り組んでいる言語は何ですか? – dkar

+0

ルールベースの文法生成メソッドが必要です。たとえば、-edまたは-ingで終わる単語を動詞として使用します(私のアプリでは、Unicode文字を使用します)。とにかくNLTKでそれをするには? – ChamingaD

0

今のところnltkでこの種のルールを書くことはできませんが、何か手間をかけることはできます。

たとえば、あなたの文章を単語の有益なラベルで書き換え、それに従って文法規則を書いてください。 (ラベルとしてPOSタグを使用して)例えば

Dogs eat bones. 

は次のようになります。

NN V NN. 

と文法端末ルールの例:

V -> 'V' 

それが十分でない場合は、あなたが取る必要がありますより柔軟な形式表現の実装を探します。

1

トークンを決定する正規表現能力を持つNLTK RegexTaggerを使用できます。これはちょうどあなたの場合に必要性が必要です。 'ing'で終わるトークンはgerundsとしてタグ付けされ、 'ed'で終わるトークンは動詞pastでタグ付けされます。以下の例を参照してください。

patterns = [ 
    (r'.*ing$', 'VBG'), # gerunds 
    (r'.*ed$', 'VBD'), # simple past 
    (r'.*es$', 'VBZ'), # 3rd singular present 
    (r'.*ould$', 'MD'), # modals 
    (r'.*\'s$', 'NN$'), # possessive nouns 
    (r'.*s$', 'NNS') # plural nouns 
] 

これらは順番に処理され、最初に一致するものが適用されます。今度は タガーを設定して、それを使用してセンテンスにタグを付けることができます。このステップの後、それは正しい時間の についてです。

regexp_tagger = nltk.RegexpTagger(patterns) 
regexp_tagger.tag(your_sent) 

あなたは順番に一括して複数のタグ付けを使用するための組み合わせるタガーを使用することができます。

関連する問題