如何使用SpaCy解决西班牙语词形还原问题?

10

当尝试对一个包含超过60,000个单词的csv文件进行西班牙语词形还原时,SpaCy没有正确识别某些单词,我知道这个模型并不是100%准确。然而,我没有找到其他解决方案,因为NLTK没有提供西班牙语核心。

我的朋友在西班牙语Stackoverflow上提出了这个问题,但由于这个社区相对较小,我们没有得到任何答案。

代码:

nlp = spacy.load('es_core_news_sm')

def lemmatizer(text):  
  doc = nlp(text)
  return ' '.join([word.lemma_ for word in doc])

df['column'] = df['column'].apply(lambda x: lemmatizer(x))

我尝试对一些我发现错误的单词进行词形还原,以证明SpaCy没有正确处理它们:

text = 'personas, ideas, cosas' 
# translation: persons, ideas, things

print(lemmatizer(text))

# Current output:
personar , ideo , coser 
# translation:
personify, ideo, sew

# The expected output should be:
persona, idea, cosa

# translation: 
person, idea, thing

1
我对SpaCy不是特别熟悉,但你是在你的数据上重新训练它还是直接使用它? - Engineero
1
有一次我尝试在西班牙语中进行词形还原,但我发现唯一有用的方法是使用NLTK中的SnowBallStemmer进行词干提取。 - jjsantoso
2
我不会说西班牙语,但对于英语词形还原,SpaCy需要知道每个单词的词性。它在nlp(text)的标记步骤中获取此信息,但看起来您的文本不是真正的句子,因此它可能会经常错误地获取POS标签。这将导致错误。顺便说一下... SpaCy仅对英语词形还原正确率约为85%。您可能需要查看斯坦福的CoreNLP或CLiPS/pattern.en,尽管所有这些解决方案的准确度仅达到低90%,并且都需要知道单词的POS。 - bivouac0
3
如果你知道每个单词的词性(例如...如果它们都是名词),你可以跳过标注步骤(nlp(text)),并直接使用词形归并器和词性类型进行处理。这将显著加快处理速度,并有可能提高准确性。 - bivouac0
1
如果您知道每个单词的词性,尝试直接调用词形还原器并传入词性。如果您不知道每个单词的词性,则使用词干提取可能是您唯一的选择。 - bivouac0
显示剩余6条评论
4个回答

19
与英语词形还原器不同,spaCy的西班牙语词形还原器完全不使用PoS信息。它依赖于一份屈折动词和词干的查找列表(例如:ideo idear、ideas idear、idea idear、ideamos idear等等)。它将只输出列表中的第一个匹配项,而不考虑其PoS。

实际上,我为spaCy开发了新的基于规则的西班牙语词形还原器,它考虑了PoS和形态学信息(例如时态、性别、数),这些精细的规则使其比当前的查找词形还原器更准确。它会很快发布!

与此同时,你可以尝试使用Stanford CoreNLP或FreeLing。


2
当你发布项目时,我会等待。与此同时,我会查阅Standford CoreNLP和FreeLing(在你的经验中,你推荐哪一个?)。 - Y4RD13
1
我认为两者都非常准确,但我没有使用它们来表达偏好。FreeLing是基于规则的,而Stanford是神经网络的。 - Guadalupe Romero
嗨@GuadalupeRomero。感谢你的提示!你会在SpaCy项目中发布新的西班牙语词形还原器吗?我怎么知道呢?此外,matcher和西班牙语是否也是如此?我尝试了很多不同的选项,但总是返回一个黑暗而令人沮丧的空虚。 - Juan Luis Chulilla
2
!pip install stanza import stanzastanza.download('es', package='ancora', processors='tokenize,mwt,pos,lemma', verbose=True) stNLP = stanza.Pipeline(processors='tokenize,mwt,pos,lemma', lang='es', use_gpu=True)doc = stNLP('Barack Obama nació en Hawaii.')print(*[f'word: {word.text+" "}\tlemma: {word.lemma}' for sent in doc.sentences for word in sent.words], sep='\n') - Y4RD13
2
@RubialesAlberto 它将在spacy v3发布时发布。 - Guadalupe Romero
显示剩余9条评论

3
也许您可以使用FreeLing,这个库提供了许多功能,包括西班牙语、加泰罗尼亚语、巴斯克语、意大利语和其他语言的词形还原。

根据我的经验,西班牙语和加泰罗尼亚语的词形还原相当准确,虽然它本身支持C++,但也具有Python和Java的API。


3

一种选择是制作自己的词形还原器。

这听起来可能有些可怕,但不用担心!实际上很简单。

我最近写了一个关于如何制作词形还原器的教程,链接在这里:

https://medium.com/analytics-vidhya/how-to-build-a-lemmatizer-7aeff7a1208c

总的来说,你需要:

  • 拥有一个POS标注器(你可以使用spaCy标注器)来标记输入的单词。
  • 获取一个单词及其词形还原形式的语料库 - 在这里,我建议你下载一个西班牙通用依存语料库 - 只需按照上述教程中的步骤进行操作。
  • 从语料库中提取的单词创建一个词形还原字典。
  • 保存该字典并创建一个包装函数,该函数接收单词和其PoS。

代码实现如下:

def lemmatize(word, pos):
   if word in dict:
      if pos in dict[word]:
          return dict[word][pos]
   return word

简单,对吧?

实际上,简单的词形还原并不需要太多的处理,但难点在于词性标注,不过这个你可以免费使用。无论如何,如果你想自己进行标注,可以查看我制作的另一个教程:

https://medium.com/analytics-vidhya/part-of-speech-tagging-what-when-why-and-how-9d250e634df6

希望你能解决它。


1
你可以使用spacy-stanza。它具有spaCy的API和Stanza的模型:
import stanza
from spacy_stanza import StanzaLanguage

text = "personas, ideas, cosas"

snlp = stanza.Pipeline(lang="es")
nlp = StanzaLanguage(snlp)
doc = nlp(text)
for token in doc:
    print(token.lemma_)

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