如何使用spacy的词形还原器将一个单词转换为基本形式

39

我是spacy的新手,想使用它的词形还原功能,但我不知道如何使用它,比如将我输入的单词字符串转换成基本形式的字符串。

示例:

  • 'words'=> 'word'
  • 'did' => 'do'

谢谢。


http://textminingonline.com/getting-started-with-spacy - RAVI
1
https://spacy.io/docs - RAVI
谢谢,我之前看过这个网站,但是他们没有详细解释,好的,我会尝试这个网站的代码,再次感谢。 - yi wang
6个回答

76

之前的回答有些复杂,无法编辑,所以这里提供一个更加传统的回答。

# make sure your downloaded the english model with "python -m spacy download en"

import spacy
nlp = spacy.load('en')

doc = nlp(u"Apples and oranges are similar. Boots and hippos aren't.")

for token in doc:
    print(token, token.lemma, token.lemma_)

输出:

Apples 6617 apples
and 512 and
oranges 7024 orange
are 536 be
similar 1447 similar
. 453 .
Boots 4622 boot
and 512 and
hippos 98365 hippo
are 536 be
n't 538 not
. 453 .

官方快速开始指南中获取

将文本传递给 nlp 前,您需要指明该文本是否为 Unicode 编码吗?请参见此处 - Philip O'Brien
1
@PhilipO'Brien 可能在 Python 2 中是这样的,但我现在使用的是 Python 3。 - damio
1
啊,好的,使用Python 2时我必须明确指出它是Unicode。谢谢!(我真的应该转向3!) - Philip O'Brien
1
其中一个问题是任何代词都会被词形还原为“-PRON-”,这很困惑。它为什么不保留代词本身呢? - wordsforthewise
1
在这里搜索“-PRON-”链接以查看解决方案,但我认为这不应该是默认行为。这似乎很令人困惑。 - wordsforthewise
6
为什么“apple”保持不变,而其他复数形式却会变成单数形式? - Major Major

26

如果你只想使用词形归并器,可以按照以下方式操作:

from spacy.lemmatizer import Lemmatizer
from spacy.lang.en import LEMMA_INDEX, LEMMA_EXC, LEMMA_RULES

lemmatizer = Lemmatizer(LEMMA_INDEX, LEMMA_EXC, LEMMA_RULES)
lemmas = lemmatizer(u'ducks', u'NOUN')
print(lemmas)

输出

['duck']

更新

自从spacy 2.2版本以来,LEMMA_INDEX、LEMMA_EXC和LEMMA_RULES已经被打包成一个Lookups对象:

import spacy
nlp = spacy.load('en')

nlp.vocab.lookups
>>> <spacy.lookups.Lookups object at 0x7f89a59ea810>
nlp.vocab.lookups.tables
>>> ['lemma_lookup', 'lemma_rules', 'lemma_index', 'lemma_exc']
你仍然可以直接使用词形还原器,需要提供一个单词和它的词性标记(POS)。

You can still use the lemmatizer directly with a word and a POS (part of speech) tag:


返回翻译:

你仍然可以直接使用词形还原器,需要提供一个单词和它的词性标记(POS)。

from spacy.lemmatizer import Lemmatizer, ADJ, NOUN, VERB

lemmatizer = nlp.vocab.morphology.lemmatizer
lemmatizer('ducks', NOUN)
>>> ['duck']
您可以像上面那样将 POS 标签作为导入的常量传递,也可以作为字符串传递:
lemmatizer('ducks', 'NOUN')
>>> ['duck']

从spacy.lemmatizer模块中导入Lemmatizer、ADJ、NOUN、VERB。


5
我试了一下你的代码,但是出现了一个错误:无法从'spacy.lang.en'中导入'LEMMA_INDEX' - Daniel dos Santos

11

代码:

import os
from spacy.en import English, LOCAL_DATA_DIR

data_dir = os.environ.get('SPACY_DATA', LOCAL_DATA_DIR)

nlp = English(data_dir=data_dir)

doc3 = nlp(u"this is spacy lemmatize testing. programming books are more better than others")

for token in doc3:
    print token, token.lemma, token.lemma_

输出:

this 496 this
is 488 be
spacy 173779 spacy
lemmatize 1510965 lemmatize
testing 2900 testing
. 419 .
programming 3408 programming
books 1011 book
are 488 be
more 529 more
better 615 better
than 555 than
others 871 others

示例参考: 这里


nlp = English(data_dir=data_dir): data_dir = data_dir,这是什么意思?它们看起来一样。 - yi wang
传递变量。English()方法接受参数data_dir。所以你可以传递" data_dir = local_variable_name "。它也可以是这样的,d_dir = os.environ.get('SPACY_DATA', LOCAL_DATA_DIR) nlp = English(data_dir=d_dir),这只是基本的Python知识。 - RAVI
好的,我会尝试这些。 - yi wang
2
在当前版本(2.2)中会出现“ModuleNotFoundError: No module named 'spacy.en'”错误。 - Suzana

10

我使用的是 Spacy 2.x 版本。

import spacy
nlp = spacy.load('en_core_web_sm', disable=['parser', 'ner'])
doc = nlp('did displaying words')
print (" ".join([token.lemma_ for token in doc]))

并输出:

do display word
希望它能帮到你 :)

Hope it helps :)


1
只使用标记器组件是个好主意!这有时可以产生很大的差异并提高加载速度。 - Kirill Malakhov

2

要获取单词和它们的词形变化之间的映射关系,请使用以下内容:

import spacy
# instantiate pipeline with any model of your choosing
nlp = spacy.load("en_core_web_lg")

words = "Those quickest and brownest foxes jumped over the laziest ones."

# only enable the needed pipeline components to speed up processing
with nlp.select_pipes(enable=['tok2vec', 'tagger', 'attribute_ruler', 'lemmatizer']):
    doc = nlp(words)

lemma_mapping = dict([(token.text, token.lemma_) 
                       for token in doc if token.is_punct==False])

print(lemma_mapping)

输出

{'Those': 'those',
 'quickest': 'quick',
 'and': 'and',
 'brownest': 'brown',
 'foxes': 'fox',
 'jumped': 'jump',
 'over': 'over',
 'the': 'the',
 'laziest': 'lazy',
 'ones': 'one'}

-2

我使用了:

import spacy

nlp = en_core_web_sm.load()
doc = nlp("did displaying words")
print(" ".join([token.lemma_ for token in doc]))
>>> do display word

但它返回了

OSError: [E050] Can't find model 'en_core_web_sm'. It doesn't seem to be a shortcut link, a Python package or a valid path to a data directory.

我使用了:

pip3 install https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-2.2.0/en_core_web_sm-2.2.0.tar.gz

消除错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接