【问题标题】:Use spacy-lookup with lemmatized sentence?使用带有词形还原的句子的 spacy-lookup?
【发布时间】:2019-02-17 07:52:50
【问题描述】:

我输入的句子包含我需要匹配的自定义多词实体,因此为此我使用了出色的 spacy-lookup 库。但是,它有一个缺陷。它无法识别它作为实体的句子中的复数词。例如,如果我将banana 声明为一个实体,并将short blue bananas 作为一个句子,它不会识别出bananas 是一个实体。我目前对此的“修复”是做这样的事情:

# Start by lowering inputLine (just in case) and removing any whitespace trailing/leading.
doc = nlp(inputLine.lower().strip())
# Lemmatize the words so things like bananas => banana.
words = list(map(lambda token: token.lemma_, doc))
lemmatized = ' '.join(words)

基本上在原始句子上运行 nlp 并将引理串在一起以创建一个新句子。但是,这需要我在词形化的句子上运行 nlp 以使用 spacy-lookup 提取实体,而这只是感觉......错了。我是否在管道中遗漏了一些东西,使 spacy-lookup 能够检查引理而不是原始单词,因此只需要调用一次 nlp?

【问题讨论】:

  • 成员变量lemma_包含什么?
  • 它包含banana,这是我需要的。

标签: python nlp spacy


【解决方案1】:

您不会错过任何明显的解决方案来让 spacy-lookup 查看引理。 spacy-lookup 直接在自述文件中说(在使用部分的末尾):“spacy-lookup 只关心令牌文本”

你必须改变 spacy-lookup 让它做你想做的事,在here附近:

matches = self.keyword_processor.extract_keywords(doc.text, span_info=True)

您可能会在此处将doc.text 更改为其他内容(例如' '.join([token.lemma_ for token in doc])),但是您会遇到问题,因为 spacy-lookup 依赖于文档文本中的字符偏移量来处理实体跨度,因此您将有返工实体跨度检测/合并,使其使用标记偏移量而不是字符偏移量来将实体与原始文档文本对齐。 (可行,但有点麻烦。)

如果您只需要实体查找,您可以使用 spacy(或 NLTK 或其他东西)生成引理,然后自行使用 flashtext 来查找实体,完全跳过 spacy-lookup。如果您不需要任何进一步的 spacy 分析,那么这将是最简单的选择。

其他说明:

  • spacy-lookup 似乎有一个不区分大小写搜索的选项(通过传递给 flashtext 的选项)

  • 如果您想使用 spacy,并且如果 spacy 的词形还原足以满足您的需要(仔细检查!),则无需使用 NLTK;您可以创建一个更快的管道来禁用您不需要的组件:

    nlp = spacy.load('en', disable=['tagger', 'parser', 'ner'])
    

【讨论】:

  • 我实际上正在执行您建议的解决方案,我在 ' '.join(lemmas) 重构句子上使用 flashtext。但是我的问题是我需要为关键字找到任何否定词或其他形容词,例如如果输入是not soft bananassoft 会有一个孩子,其依赖关系是neg,我知道我需要否定soft。因此,每当我找到一个关键字时,我都需要在 nlp 运行中找到它的相关标记,以便我可以检查它,而这又需要实体,因此可以识别多字关键字(例如,我不知道 fancy banana)。
  • 如果您不想修改 spacy-lookup,那么我建议您使用 flashtext 以外的其他方法来查找关键字。如果您正在使用 spacy 解析文档,那么您也许可以处理一种稍微慢一些/更灵活的关键字检测方法,它会查看标记和引理?
  • 除了 flashtext 还有什么其他的选择?我可以使用稍微慢一些的方法,因为无论如何我都想获取依赖/否定信息。
  • 也许看看 spacy 的 Matcher 和 PhraseMatcher?我怀疑其中至少有一个可以做你想做的事。 (spacy.io/api/matcher / spacy.io/api/phrasematcher ) 没试过,不过好像这里有demo:explosion.ai/demos/matcher
  • 匹配器(至少来自演示)不适用于多词关键字,所以我尝试了短语匹配器。我从 API 页面上的最后一个示例中复制了示例代码,并将其粘贴到spacy.io/usage/spacy-101 中的一个可编辑代码示例中。看起来它仍然不适用于引理,因为它与测试句中的 healthcare reforms 不匹配,但是当我将其更改为 healthcare reform 时它确实如此。
【解决方案2】:

您可以像这样使用来自NLTK 模块的WordNet lemmatizer

>>> import nltk
>>> from nltk.stem import WordNetLemmatizer
>>>
>>> wordnet_lemmatizer = WordNetLemmatizer()
>>> wordnet_lemmatizer.lemmatize("bananas")
banana

因此,根据您的示例,您可以执行以下操作:

sentence = "short blue bananas"
for word in sentence.split(" "):
    word = word.lower()
    print(wordnet_lemmatizer.lemmatize(word))

它会打印short blue banana

如果您不知道如何使用nltk.. 请按照以下说明操作:

  1. 通过运行pip install nltk 安装 NLTK 模块
  2. 打开终端并输入以下内容以下载 NLTK 中的流行包。
$ python
Python 3.6.5 |Anaconda, Inc.| (default, Apr 29 2018, 16:14:56) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.

>>> import nltk
>>> nltk.download('popular')
>>> nltk.download('wordnet')

【讨论】:

  • 你如何建议我将它与 spacy-lookup 结合使用?我用实际的句子(比如我的short blue bananas 示例)对其进行了测试,但它未能正确地对“香蕉”进行词形还原。
  • 你需要逐字使用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多