使用spaCy时如何同时去除停用词和词形还原?

How to remove stop words and lemmatize at the same time when using spaCy?

当我使用 spaCy 清理数据时,我 运行 以下行:

df['text'] = df.sentence.progress_apply(lambda text: " ".join(token.lemma_ for token in nlp(text) if not token.is_stop and token.is_alpha))

如果文本行中的每个词不是停用词,则对每个词进行词形还原。问题是 text.lemma_ 在检查标记是否为停用词后应用于标记。因此,如果停用词不是词形还原形式,则不会被视为停用词。例如,如果我将“friend”添加到停用词列表,如果原始标记是“friends”,输出仍将包含“friend”。简单的解决方案是 运行 这一行两次。但这听起来很傻。任何人都可以提出一个解决方案,以删除第一个 运行?

中不在词形化形式中的停用词

谢谢!

您可以简单地检查 token.lemma_ 是否存在于 nlp.Defaults.stop_words 中:

if token.lemma_.lower() not in nlp.Defaults.stop_words

例如:

df['text'] = df.sentence.progress_apply(
    lambda text: 
        " ".join(
            token.lemma_ for token in nlp(text)
                if token.lemma_.lower() not in nlp.Defaults.stop_words and token.is_alpha
        )
)

查看快速测试:

>>> import spacy
>>> nlp = spacy.load("en_core_web_sm")

>>> nlp.Defaults.stop_words.add("friend") # Adding "friend" to stopword list

>>> text = "I have a lot of friends"
>>> " ".join(token.lemma_ for token in nlp(text) if not token.is_stop and token.is_alpha)
'lot friend'

>>> " ".join(token.lemma_ for token in nlp(text) if token.lemma_.lower() not in nlp.Defaults.stop_words and token.is_alpha)
'lot'

如果将大写单词添加到停用词列表,则需要使用 if token.lemma_.lower() not in map(str.lower, nlp.Defaults.stop_words)