如何提取数字(以及比较形容词或范围)
How to extract numbers (along with comparison adjectives or ranges)
我在 Python 从事两个 NLP 项目,两者都有类似的任务 从句子中提取数值和比较运算符 ,如下所示:
"... greater than ... ",
"... weight not more than 200lbs ...",
"... height in 5-7 feets ...",
"... faster than 30 seconds ... "
我找到了两种不同的方法来解决这个问题:
- 使用非常复杂的正则表达式。
- 使用 Named Entity Recognition(以及一些正则表达式)。
如何从这些句子中解析数值?我认为这是 NLP 中的常见任务。
所需的输出类似于:
输入:
"greater than "
输出:
{'value': 10, 'unit': 'dollar', 'relation': 'gt', 'position': 3}
我可能会将其作为分块任务来处理,并使用 nltk
的词性标注器与其正则表达式分词器相结合。这将允许您根据句子中单词的词性而不是单词本身来定义正则表达式。对于给定的句子,您可以执行以下操作:
import nltk
# example sentence
sent = 'send me a table with a price greater than 0'
我要做的第一件事是稍微修改一下你的句子,这样你就不会太混淆词性标注器。以下是您可以进行的一些更改示例(使用非常简单的正则表达式),但您可以尝试看看是否还有其他更改:
-> 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')]]
我在 Python 从事两个 NLP 项目,两者都有类似的任务 从句子中提取数值和比较运算符 ,如下所示:
"... greater than ... ",
"... weight not more than 200lbs ...",
"... height in 5-7 feets ...",
"... faster than 30 seconds ... "
我找到了两种不同的方法来解决这个问题:
- 使用非常复杂的正则表达式。
- 使用 Named Entity Recognition(以及一些正则表达式)。
如何从这些句子中解析数值?我认为这是 NLP 中的常见任务。
所需的输出类似于:
输入:
"greater than "
输出:
{'value': 10, 'unit': 'dollar', 'relation': 'gt', 'position': 3}
我可能会将其作为分块任务来处理,并使用 nltk
的词性标注器与其正则表达式分词器相结合。这将允许您根据句子中单词的词性而不是单词本身来定义正则表达式。对于给定的句子,您可以执行以下操作:
import nltk
# example sentence
sent = 'send me a table with a price greater than 0'
我要做的第一件事是稍微修改一下你的句子,这样你就不会太混淆词性标注器。以下是您可以进行的一些更改示例(使用非常简单的正则表达式),但您可以尝试看看是否还有其他更改:
-> 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')]]