我可能会将此作为一个分块任务,并使用nltk
的词类标记器与其正则表达式chunker结合使用。这将允许您根据句子中的单词的词性而不是单词本身来定义正则表达式。对于给定的句子,你可以做到以下几点:
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')]]
使用CogComp-量词封装:https://开头github上。com/CogComp/cogcomp-nlp/tree/master/pipeline它可以提取数量,并标准化它们的单位。 – Daniel
Facebook小鸭适合这项任务https://github.com/facebookincubator/duckling –