【问题标题】:Detect stopword after lemma in Spacy在 Spacy 中的引理后检测停用词
【发布时间】:2018-05-11 09:51:19
【问题描述】:

如何在spaCy中进行词干提取和词形还原后检测单词是否为停用词?

假设句

s = "something good\nsomethings 2 bad"

在这种情况下,something 是一个停用词。显然(对我来说?)Somethingsomethings 也是停用词,但它需要在之前进行词干处理。下面的脚本会说第一个是真的,但后者不是。

import spacy
from spacy.tokenizer import Tokenizer
nlp = spacy.load('en')
tokenizer = Tokenizer(nlp.vocab)

s = "something good\nSomething 2 somethings"
tokens = tokenizer(s)

for token in tokens:
  print(token.lemma_, token.is_stop)

返回:

something True
good False
"\n" False
Something False
2 False
somethings False

有没有办法通过spaCy API 检测到?

【问题讨论】:

    标签: python nlp spacy stop-words lemmatization


    【解决方案1】:

    spaCy 中的停用词只是一组字符串,它们在词位上设置一个标志,词汇表中与上下文无关的条目(see here 用于英语停用列表)。该标志只检查是否text in STOP_WORDS,这就是为什么“something”为is_stop返回True,而“somethings”没有。

    但是,您可以做的是检查令牌的引理或小写形式是否是停止列表的一部分,可通过nlp.Defaults.stop_words 获得(即您使用的语言的默认值) ):

    def extended_is_stop(token):
        stop_words = nlp.Defaults.stop_words
        return token.is_stop or token.lower_ in stop_words or token.lemma_ in stop_words
    

    如果您使用 spaCy v2.0 并希望更优雅地解决此问题,您还可以通过 custom Token attribute extension 实现自己的 is_stop 函数。您可以为您的属性选择任何名称,它将通过token._. 可用,例如token._.is_stop

    from spacy.tokens import Token
    from spacy.lang.en.stop_words import STOP_WORDS  # import stop words from language data
    
    stop_words_getter = lambda token: token.is_stop or token.lower_ in STOP_WORDS or token.lemma_ in STOP_WORDS
    Token.set_extension('is_stop', getter=stop_words_getter)  # set attribute with getter
    
    nlp = spacy.load('en')
    doc = nlp("something Something somethings")
    assert doc[0]._.is_stop  # this was a stop word before, and still is
    assert doc[1]._.is_stop  # this is now also a stop word, because its lowercase form is
    assert doc[2]._.is_stop  # this is now also a stop word, because its lemma is
    

    【讨论】:

    • 谢谢,这很好,但希望我不必使用 Python 级别的方法。有一些较低级别的东西会很好。你认为这是唯一的选择吗?
    • 如果您想要非常低级别的访问权限,Cython API 实际上非常适合使用。您可以调用Lexeme.set_struct_attr(lex_ptr, attr_id, attr_value) 为词位设置一个值。您可以使用vocab.get()doc.c[i].lex 查找指向该词位的指针。对于后者,您需要通过 const 进行修改,因为相同类型的所有标记都指向相同的词素结构。共享词位的事实解释了为什么停用词的行为与它们的行为相同:标志设置在词位上,由精确的字符串作为键。
    猜你喜欢
    • 2021-06-13
    • 2019-09-12
    • 2018-09-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-14
    • 1970-01-01
    • 2019-02-19
    相关资源
    最近更新 更多