首页 文章

NLP - 提取“正确的”名词短语

提问于
浏览
1

我遇到了与NLP有关的问题,我希望能得到一些建议来帮助解决这个问题 . 我目前正在编写一个程序,其中给定一个包含货币编号的句子,程序将能够返回与该编号对应的名词短语 . 例如,给出这句话:

“那辆自行车要花100美元 . ”

我将名词短语“bike”与“$ 100”匹配 . 我正在使用Stanford NLP的解析器来查找句子中的名词短语,并且如您所知,在名词短语中可能有名词短语 . 例如,在句子中:

“这些商品的购买价格为50美元 . ”

两个名词短语“购买价格”和“商品”都包含在名词短语“这些商品的购买价格”下,由斯坦福大学的解析器识别 . 因此,当匹配时,只考虑我所称的基本名词短语,或者其中不包含任何其他名词短语的名词短语,这是有意义的 . 但这并不总是有效,因为在这句话例如:

“他承担了与办公空间相关的23000美元的费用以及与办公用品相关的1万美元的费用 . ”

由解析器识别的基本名词短语将是“成本”x2,“办公用品”和“办公空间” . 但这些名词短语都没有恰当地描述数字“23000美元”和“万美元” . 我们真正需要的是更通用的名词短语“办公用品的成本”和“办公空间的成本”来充分描述数字 .

所以我一直试图找出一种方法来提取不太宽泛或太具体的名词短语,如前两个例子所示 . 但到目前为止,似乎还没有可能开发出适用于所有不同句子的方法 . 如果有人可以就如何解决这个问题提出任何建议,我们将不胜感激 .

在此先感谢您的时间 .

2 回答

  • 1

    这听起来像一个开放的问题,其中过于宽泛或过于具体的东西可能是特定的结构 . 因此,即使我们解决了这个句子,它也可能无法很好地传递给其他人 .

    在你的最后一个例子中,“他承担了与办公空间相关的23000美元的成本......”这是你想要的PP“23000美元”的“of”的论据 .

    如果你将句子放入解析器(有一个在线演示here),你就得到了

    (ROOT
      (S
        (NP (PRP He))
        (VP (VBD incurred)
        (NP
        (NP
          (NP
            (QP ($ $) (CD 23) (CD thousand)))
          (PP (IN of)
            (NP
              (NP (NNS costs))
              (VP (VBN related)
                (PP (TO to)
                  (NP (NN office) (NN space)))))))
    
    (...)
    

    因此,如果您能够识别出这种结构并找到美元数量,那么您可能只能采用其PP的参数:

    (NP
      (NP (NNS costs))
       (VP (VBN related)
            (PP (TO to)
              (NP (NN office) (NN space)))))
    

    同样,对于“购买价格”示例,您需要“for”的参数,即“这些商品” .

  • 1

    看看我最近实施的这个库:https://github.com/krzysiekfonal/grammaregex

    我认为这正是你所寻找的 - 所以你可以根据在句子树上处理的类似regex的过滤器来解析你的句子,找到一个匹配的单词 . 对你来说一个不方便的事情可能是它不使用coreNLP而是使用spacy库(https://spacy.io/) - 将来我想使它独立于NLP lib .

    在这个lib中考虑的主要问题 - 我认为你需要做的事情 - 不仅要考虑postags,还要考虑单词之间的依赖关系关系 . 这里有一个例子:

    >>>import spacy
    >>>from grammaregex import print_tree, match_tree, find_tokens
    >>>nlp = spacy.load("en") 
    >>>doc = nlp(u"Mrs. Robinson graduated from the Wharton School of the University of Pennsylvania in 1980.") 
    >>>sent = next(doc.sents)
    
    >>>print_tree(sent, "tag_")
    { { { Mrs.->compound(NNP) } Robinson->nsubj(NNP) } graduated->ROOT(VBD) { from->prep(IN) { { the->det(DT) } { Wharton->compound(NNP) } School->pobj(NNP) { of->prep(IN) { { the->det(DT) } University->pobj(NNP) { of->prep(IN) { Pennsylvania->pobj(NNP) } } } } } } { in->prep(IN) { 1980->pobj(CD) } } { .->punct(.) } }
    >>>match_tree(sent, "VBD/prep/IN/pobj/NNP")
    True
    >>>match_tree(sent, "VBD/prep/IN/pobj/VBD")
    False
    >>>match_tree(sent, "VBD/**/DT")
    True
    >>>find_tokens(sent, "VBD/prep/IN/pobj/*")
    [School, 1980]
    >>>find_tokens(sent, "VBD/prep/IN/*/[NNP,DT]")
    [School]
    >>>find_tokens(sent, "VBD/**/DT")
    [the, the]
    

    因此,您只需使用print_tree查看您的句子树(您还可以在https://displacy.spacy.io/上使用更好的图形可视化),然后调整将在find_tokens方法中使用的正则表达式字符串 .

    在这里你可以找到这个简单的lib的快速介绍:https://medium.com/@krzysiek89dev/grammaregex-library-regex-like-for-text-mining-49e5706c9c6d#.vrrm88bt4

相关问题