web-dev-qa-db-ja.com

数値を抽出する方法(比較形容詞または範囲とともに)

私はPythonで2つのNLPプロジェクトに取り組んでおり、どちらも次のように、文から数値を抽出し、比較演算子と同様のタスクを実行します。

"... greater than $10 ... ",
"... weight not more than 200lbs ...",
"... height in 5-7 feets ...",
"... faster than 30 seconds ... "

この問題を解決するための2つの異なるアプローチが見つかりました。

  • 非常に複雑な正規表現を使用します。
  • Named Entity Recognition を使用します(一部の正規表現も使用します)。

このような文から数値を解析するにはどうすればよいですか?これはNLPの一般的なタスクだと思います。


望ましい出力は次のようになります。

入力:

「10ドル超」

出力:

{'value': 10, 'unit': 'dollar', 'relation': 'gt', 'position': 3}
34
svfat

私はおそらくこれをチャンクタスクとしてアプローチし、nltkの品詞タガーとその正規表現チャンカーを組み合わせて使用​​します。これにより、単語そのものではなく、文中の単語の品詞に基づいて正規表現を定義できます。特定の文について、次のことができます。

import nltk

# example sentence
sent = 'send me a table with a price greater than $100'

私が最初に行うことは、品詞タガーをあまり混乱させないように文を少し修正することです。 (非常に単純な正規表現を使用して)実行できる変更の例をいくつか示しますが、他に変更がないかどうかを実験して確認できます。

$10 -> 10 dollars
200lbs -> 200 lbs
5-7 -> 5 - 7 OR 5 to 7

だから私たちは得る:

sent = 'send me a table with a price greater than 100 dollars'

これで、文章から品詞を取得できます。

sent_pos = nltk.pos_tag(sent.split())
print(sent_pos)

[('send', 'VB'), ('me', 'PRP'), ('a', 'DT'), ('table', 'NN'), ('with', 'IN'), ('a', 'DT'), ('price', 'NN'), ('greater', 'JJR'), ('than', 'IN'), ('100', 'CD'), ('dollars', 'NNS')]

chunker を作成して、(比較的)単純な正規表現に従ってPOSタグ付きテキストをチャンク化します。

grammar = 'NumericalPhrase: {<NN|NNS>?<RB>?<JJR><IN><CD><NN|NNS>?}'
parser = nltk.RegexpParser(grammar)

これは、数値フレーズ(ここではフレーズタイプと呼びます)を分割する文法を使用してパーサーを定義します。これは、数値フレーズを次のように定義します。オプションの名詞、オプションの副詞、比較形容詞、前置詞、数字、オプションの名詞。これは、フレーズを定義する方法の提案にすぎませんが、これは、単語自体に正規表現を使用するよりもはるかに簡単だと思います。

あなたができるあなたのフレーズを取得するには:

print(parser.parse(sent_pos))
(S
  send/VB
  me/PRP
  a/DT
  table/NN
  with/IN
  a/DT
  (NumericalPhrase price/NN greater/JJR than/IN 100/CD dollars/NNS))  

または、あなたができるあなたのフレーズだけを得るために:

print([tree.leaves() for tree in parser.parse(sent_pos).subtrees() if tree.label() == 'NumericalPhrase'])

[[('price', 'NN'),
  ('greater', 'JJR'),
  ('than', 'IN'),
  ('100', 'CD'),
  ('dollars', 'NNS')]]
31
bunji