【问题标题】:How to solve Spanish lemmatization problems with SpaCy?如何使用 SpaCy 解决西班牙语词形还原问题?
【发布时间】:2020-03-04 21:30:46
【问题描述】:

当尝试 lemmatize in Spanish 超过 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

【问题讨论】:

  • 我对 SpaCy 不是很熟悉,但您是在数据上重新训练它还是直接使用它?
  • 有一次我尝试用西班牙语进行词形还原,但我发现唯一有用的是使用来自 NLTK 的SnowBallStemmer 进行词干提取。
  • 我不会说西班牙语,但对于英语词形还原,SpaCy 依赖于知道每个单词的词性。它在nlp(text) 的标记步骤中获取此信息,但它看起来不像您的文本是真实的句子,因此它可能使 POS 标签错误很多。这将导致错误。顺便说一句... SpaCy 对于英语词形还原只有大约 85% 的正确率。您可能想查看斯坦福的 CoreNLP 或 CLiPS/pattern.en,尽管所有这些解决方案都只能达到 90% 的低准确率,并且都需要知道单词的 POS。
  • 如果您知道每个单词的词性(即...如果它们都是名词),您可以跳过标记步骤 (nlp(text)) 并直接使用POS 类型。这将显着加快流程,并可能提高准确性。
  • 如果您知道每个单词的词性,请尝试直接调用词形还原器并传入词性。如果您不知道每个单词的词性,那么词干提取可能是您唯一的选择。

标签: python spacy lemmatization


【解决方案1】:

与英语词形还原器不同,spaCy 的西班牙语词形还原器根本不使用 PoS 信息。它依赖于一个变形动词和引理的查找列表(例如,ideo idear、ideaider、ideaider、ideamos idear 等)。它只会输出列表中的第一个匹配项,而不考虑它的 PoS。

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

同时,您也可以使用 Stanford CoreNLP 或 FreeLing。

【讨论】:

  • 项目完成后我会等你。同时,我将查找 Standford CoreNLP 和 FreeLing(根据您的经验,您推荐哪一个?)
  • 我认为两者都非常准确,但我没有太多使用它们来获得偏好。 FreeLing 是基于规则的,Stanford 是神经的。
  • 当您发布基于规则的新规则时,将其发布为您的答案的更新。这将非常有帮助。
  • !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')
  • @RubialesAlberto 它将与 spacy v3 一起发布
【解决方案2】:

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

这听起来很可怕,但不要害怕!做一个其实很简单。

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

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

总而言之,您必须:

  • 有一个词性标注器(你可以使用 spaCy 标注器)来标注输入词。
  • 获取词汇及其词条的语料库 - 在这里,我建议您下载西班牙语的 Universal Dependencies Corpus - 只需按照上述教程中的步骤操作即可。
  • 从语料库中提取的单词创建引理字典。
  • 保存 dict 并创建一个接收单词及其 PoS 的包装函数。

在代码中,它看起来像这样:

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

简单吧?

事实上,简单的词形还原并不像人们想象的那样需要大量的处理。困难的部分在于 PoS 标记,但你可以免费获得。无论哪种方式,如果您想自己进行标记,您可以查看我制作的其他教程:

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

希望你能解决。

【讨论】:

    【解决方案3】:

    你可以使用 spacy-stanza。它具有带有 Stanza 模型的 spaCy 的 API:

    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_)
    

    【讨论】:

      【解决方案4】:

      也许您可以使用FreeLing,该库提供西班牙语、加泰罗尼亚语、巴斯克语、意大利语和其他语言的许多功能。

      根据我的经验,西班牙语和加泰罗尼亚语的词形还原非常准确,虽然它本身支持 C++,但它有一个用于 Python 的 API 和另一个用于 Java 的 API。

      【讨论】:

        猜你喜欢
        • 2014-12-05
        • 2017-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多