-1

自然言語電卓を作るために、nltk の TrigramTagger を試してみました。与えられた文で掛け算と2つの数字をタグ付けしたい。例: 「5 と 7 の積は何ですか」。ここで、「product」は「binary.multiply」、「5」は「num-1」、「7」は「num-2」です。この 3 つにタグを付けることができれば、簡単に答えを計算できます。

しかし、以下の出力でわかるように、2 つの数字についてタガーをトレーニングすることができません。番号は、トレーニングされたものとまったく同じでなければなりません。それ以外の場合は、デフォルトで「CD」になります。正規表現などを使用して、num-1 と num-2 についてタガーをトレーニングするにはどうすればよいですか?

import nltk.tag, nltk.data
from nltk import word_tokenize
default_tagger = nltk.data.load(nltk.tag._POS_TAGGER)

def evaluate(tagger, sentences):
    good,total = 0,0.
    for sentence in sentences:
        tags = tagger.tag(nltk.word_tokenize(sentence))
        print tags

train_sents = [
    [('product', 'binary.multiply'), ('of', 'IN'), ('5', 'num-1'), ('and', 'CC'), ('7', 'num-2'), ('?', '.')],
    [ ('what', 'WP'), ('is', 'VBZ'),  ('product', 'binary.multiply'), ('of', 'IN'), ('5', 'num-1'), ('and', 'CC'), ('7', 'num-2'), ('?', '.')],
    [('what', 'WP'), ('happens', 'NNS'), ('when', 'WRB'), ('I', 'PRP'), ('multiply', 'binary.multiply'), ('5', 'num-1'), ('with', 'IN'), ('7', 'num-2'), ('?', '.')],
    [('5', 'num-1'), ('*', 'binary.multiply'), ('3.2','CD')],
    [('is', 'NNP'), ('it', 'PRP'), ('possible', 'JJ'), ('to', 'TO'), ('multiply', 'binary.multiply'), ('5', 'num-1'), ('with', 'IN'), ('7', 'num-2'), ('?', '.')],
    [('what', 'WP'), ('is', 'VBZ'), ('5', 'num-1'), ('times', 'binary.multiply'), ('7', 'num-2'), ('?', '.')]
]

sentences = [
    ('product of 5 and 7?'),
    ('what is product of 3 and 2.7?'),
    ('what happens when I multiply 0.1 with 5.21?'),
    ('9.1 * 3.2'),
    ('is it possible to multiply 5 with 7?'),
    ('what is 5 times 7?')
]

tagger = nltk.TrigramTagger(train_sents, backoff=default_tagger)
evaluate(tagger, sentences)
#model = tagger._context_to_tag

このプログラムの出力は num-1 と num-2 の異なる数字を認識しません。どうすれば認識させることができますか?

[('product', 'binary.multiply'), ('of', 'IN'), ('4', 'CD'), ('and', 'CC'), ('2', 'CD'), ('?', '.')]
[('what', 'WP'), ('is', 'VBZ'), ('product', 'binary.multiply'), ('of', 'IN'), ('3', 'CD'), ('and', 'CC'), ('2.7', 'CD'), ('?', '.')]
[('what', 'WP'), ('happens', 'NNS'), ('when', 'WRB'), ('I', 'PRP'), ('multiply', 'binary.multiply'), ('0.1', 'CD'), ('with', 'IN'), ('5.21', 'CD'), ('?', '.')]
[('9.1', 'CD'), ('*', '-NONE-'), ('3.2', 'CD')]
[('is', 'NNP'), ('it', 'PRP'), ('possible', 'JJ'), ('to', 'TO'), ('multiply', 'binary.multiply'), ('2', 'CD'), ('with', 'IN'), ('77', 'CD'), ('?', '.')]
[('what', 'WP'), ('is', 'VBZ'), ('15', 'CD'), ('times', 'NNS'), ('72', 'CD'), ('?', '.')]
4

1 に答える 1

1

これにはRegexTaggerを使用できると思います。RegexTagger は、一致するパターンに基づいてトークンにタグを割り当てる正規表現タガーです。

このコードを試してください

from nltk.tokenize import word_tokenize
import nltk.tag
patterns = [
      (r'product|multiply|times', 'binary.multiply'),               # gerunds
      (r'\*', 'binary.multiply'), 
      (r'\d+\.\d+|\d+', 'num'),
      (r'\w+', 'word'),
      (r'[^0-9a-zA-z\*]','sym')
      ]
sentences = [
('product of 5 and 7?'),
('what is product of 3 and 2.7?'),
('what happens when I multiply 0.1 with 5.21?'),
('9.1 * 3.2'),
('is it possible to multiply 5 with 7?'),
('what is 5 times 7?')
]

regexp_tagger = nltk.RegexpTagger(patterns)
regexp_tagger.tag(word_tokenize(sentences[0]))

出力

[('product', 'binary.multiply'),
 ('of', 'NN'),
 ('5', 'num'),
 ('and', 'NN'),
 ('7', 'num'),
 ('?', 'sym')]

出力リストから、1 番目の番号と 2 番目の番号を簡単に見つけることができます。

于 2016-01-18T12:13:43.647 に答える