从句子中提取食物

时间:2017-05-11 08:13:32

标签: algorithm nlp

给出一句话:

  我有花生酱和果冻三明治和一杯咖啡   早餐

我希望能够从中提取以下食物:

花生酱和果冻三明治

咖啡

到目前为止,使用POS标签,我已经能够提取单个食品,即

花生,黄油,果冻,三明治,咖啡

但就像我说的那样,我需要的是花生酱和果冻三明治而不是个别物品。

有没有办法在没有后端食品的语料库或数据库的情况下这样做?

4 个答案:

答案 0 :(得分:9)

您可以在不使用包含食物文集的训练集的情况下尝试它,但该方法也可以在没有它的情况下工作。

不进行简单的POS标记,而是将依赖性解析与POS标记相结合。 这种方式可以找到短语的多个标记之间的关系,并使用限制条件解析依赖关系树,如名词 - 名词依赖关系,你应该能够找到相关的块。

您可以使用spacy for dep parsing。这是来自displacy的输出:

https://demos.explosion.ai/displacy/?text=peanut%20butter%20and%20jelly%20sandwich%20is%20delicious&model=en&cpu=1&cph=1

enter image description here

enter image description here

  • 您可以在此处使用免费提供的数据,或更好的内容: https://en.wikipedia.org/wiki/Lists_of_foods作为训练集 创建一组基本的食物项目(爬行树中的超链接)
  • 根据对新数据的依赖性解析,您可以保留 丰富基础数据。例如:if' butter'存在于你的 语料库和花生酱'是一对经常遇到的 令牌,那么'花生'和花生酱'也加入了 语料库。
  • 语料库可以保存在可以加载到内存中的文件中 处理时,或像redis,aerospike等数据库。
  • 确保您使用标准化,即小套管,特殊 字符清理,单词lemmatized / stemmed,在语料库和词汇 处理数据。这会增加你的覆盖面和准确性。

答案 1 :(得分:4)

首先使用NLTK的Chunking(从here复制的代码)提取所有名词短语:

import nltk
import re
import pprint
from nltk import Tree
import pdb


patterns="""
    NP: {<JJ>*<NN*>+}
    {<JJ>*<NN*><CC>*<NN*>+}
    {<NP><CC><NP>}
    {<RB><JJ>*<NN*>+}
    """

NPChunker = nltk.RegexpParser(patterns)

def prepare_text(input):
    sentences = nltk.sent_tokenize(input)
    sentences = [nltk.word_tokenize(sent) for sent in sentences] 
    sentences = [nltk.pos_tag(sent) for sent in sentences]
    sentences = [NPChunker.parse(sent) for sent in sentences]
    return sentences


def parsed_text_to_NP(sentences):
    nps = []
    for sent in sentences:
        tree = NPChunker.parse(sent)
        print(tree)
        for subtree in tree.subtrees():
            if subtree.label() == 'NP':
                t = subtree
                t = ' '.join(word for word, tag in t.leaves())
                nps.append(t)
    return nps


def sent_parse(input):
    sentences = prepare_text(input)
    nps = parsed_text_to_NP(sentences)
    return nps



if __name__ == '__main__':
    print(sent_parse('I ate peanut butter and beef burger and a cup of coffee for breakfast.'))

这将POS标记你的句子并使用正则表达式解析器来提取名词短语。

1.定义并优化名词短语正则表达式

您需要更改模式正则表达式来定义和优化您的名词短语。 例如,告诉解析器而不是NP,然后是协调器(CC),如''和'',另一个NP本身就是NP。

2.从NLTK POS tagger转换为Stanford POS tagger

另外我注意到NLTK的POS标签表现不佳(例如它认为花生作为动词短语。如果你愿意,可以将POS标签改为Stanford Parser。

3.删除较小的名词短语:

在为句子提取所有名词短语后,您可以删除属于较大名词短语的那些短语。例如,在以下示例中,应删除牛肉汉堡花生酱,因为 它们是一个更大的名词短语花生酱和牛肉汉堡的一部分。

4.删除食物词典中没有任何单词的名词短语

你会得到像校车这样的名词短语。如果没有学校和公共汽车在食品词典中,你可以从维基百科或WordNet编译,那么你删除名词短语。在这种情况下,请删除早餐,因为它们在食物词典中不是希望

当前代码返回

['peanut butter and beef burger', 'peanut butter', 'beef burger', 'cup', 'coffee', 'breakfast']
输入

print(sent_parse('I ate peanut butter and beef burger and a cup of coffee for breakfast.'))

答案 2 :(得分:1)

评论太多了,但不是真的答案:

我认为如果你有两种没有适当分离器的食物并将它们合并成一种食物,你至少会更接近。那会给花生酱,果冻三明治,咖啡。

如果您的英语正确,您可以通过计数/非计数来检测个案。将原件改为“我早餐有 花生酱和果冻三明治和一杯咖啡”。 黄油是不算数,你不能有“黄油”,但你可以有“三明治”。因此, a 必须适用于三明治,尽管“花生酱”和“果冻三明治”必须是同一项目 - “花生酱和果冻三明治”。不过,你错误的句子会用另一种方式解析!

如果你能提出涵盖所有案例的一般规则,我会感到非常惊讶。我会遇到这样的事情,认为有些人会泄漏并需要一个数据库来捕捉。

答案 3 :(得分:1)

基于规则的方法以及所有食品的词汇都适用于此。

您可以使用GATE并使用JAPE规则。

在上面的例子中,你的jape规则有条件找到所有(np cc np)&amp;&amp; np在“FOOD LEI​​XCON”中

可以在您计划前往此路线的活动中分享详细的开头代码。