使用语料库对西班牙语单词进行NLTK标注

21 投票
4 回答
39075 浏览
提问于 2025-04-17 14:58

我正在尝试学习如何使用NLTK给西班牙语单词打标签。

nltk书籍中,使用他们的例子给英语单词打标签非常简单。因为我对NLTK和语言处理都很陌生,所以我对接下来该怎么做感到有些困惑。

我已经下载了cess_esp语料库。请问有没有办法在nltk.pos_tag中指定一个语料库?我查看了pos_tag的文档,没有看到任何提示我可以这样做的内容。我觉得我可能错过了一些关键概念。我是否需要手动将我文本中的单词与cess_esp语料库进行对比打标签?(我所说的手动是指将我的句子分词,然后与语料库进行对比)还是说我完全走错了方向?谢谢!

4 个回答

7

根据之前回答中的教程,这里有一个来自“意大利面标签器”的更面向对象的方法:https://github.com/alvations/spaghetti-tagger

#-*- coding: utf8 -*-

from nltk import UnigramTagger as ut
from nltk import BigramTagger as bt
from cPickle import dump,load
        
def loadtagger(taggerfilename):
    infile = open(taggerfilename,'rb')
    tagger = load(infile); infile.close()
    return tagger

def traintag(corpusname, corpus):
    # Function to save tagger.
    def savetagger(tagfilename,tagger):
        outfile = open(tagfilename, 'wb')
        dump(tagger,outfile,-1); outfile.close()
        return
    # Training UnigramTagger.
    uni_tag = ut(corpus)
    savetagger(corpusname+'_unigram.tagger',uni_tag)
    # Training BigramTagger.
    bi_tag = bt(corpus)
    savetagger(corpusname+'_bigram.tagger',bi_tag)
    print "Tagger trained with",corpusname,"using" +\
                "UnigramTagger and BigramTagger."
    return
    
# Function to unchunk corpus.
def unchunk(corpus):
    nomwe_corpus = []
    for i in corpus:
        nomwe = " ".join([j[0].replace("_"," ") for j in i])
        nomwe_corpus.append(nomwe.split())
    return nomwe_corpus

class cesstag():
    def __init__(self,mwe=True):
        self.mwe = mwe
        # Train tagger if it's used for the first time.
        try:
            loadtagger('cess_unigram.tagger').tag(['estoy'])
            loadtagger('cess_bigram.tagger').tag(['estoy'])
        except IOError:
            print "*** First-time use of cess tagger ***"
            print "Training tagger ..."
            from nltk.corpus import cess_esp as cess
            cess_sents = cess.tagged_sents()
            traintag('cess',cess_sents)
            # Trains the tagger with no MWE.
            cess_nomwe = unchunk(cess.tagged_sents())
            tagged_cess_nomwe = batch_pos_tag(cess_nomwe)
            traintag('cess_nomwe',tagged_cess_nomwe)
            print
        # Load tagger.
        if self.mwe == True:
            self.uni = loadtagger('cess_unigram.tagger')
            self.bi = loadtagger('cess_bigram.tagger')
        elif self.mwe == False:
            self.uni = loadtagger('cess_nomwe_unigram.tagger')
            self.bi = loadtagger('cess_nomwe_bigram.tagger')

def pos_tag(tokens, mmwe=True):
    tagger = cesstag(mmwe)
    return tagger.uni.tag(tokens)
    
def batch_pos_tag(sentences, mmwe=True):
    tagger = cesstag(mmwe)
    return tagger.uni.batch_tag(sentences)

tagger = cesstag()
print tagger.uni.tag('Mi colega me ayuda a programar cosas .'.split())

免责声明:这是我自己写的GitHub库,算是自我宣传一下 =)

8

我来到这里是想找一些除了英语以外的词性标注工具。你可以试试Spacy这个库,它支持多种语言的词性标注,比如荷兰语、德语、法语、葡萄牙语、西班牙语、挪威语、意大利语、希腊语和立陶宛语。

根据Spacy的文档:

import es_core_news_sm
nlp = es_core_news_sm.load()
doc = nlp("El copal se usa principalmente para sahumar en distintas ocasiones como lo son las fiestas religiosas.")
print([(w.text, w.pos_) for w in doc])

这段代码的结果是:

[('El', 'DET'), ('copal', 'NOUN'), ('se', 'PRON'), ('usa', 'VERB'), ('principalmente', 'ADV'), ('para', 'ADP'), ('sahumar', 'VERB'), ('en', 'ADP'), ('distintas', 'DET'), ('ocasiones', 'NOUN'), ('como', 'SCONJ'), ('lo', 'PRON'), ('son', 'AUX'), ('las', 'DET'), ('fiestas', 'NOUN'), ('religiosas', 'ADJ'), ('.', 'PUNCT')]

如果你想在笔记本上可视化这个结果,可以参考:

displacy.render(doc, style='dep', jupyter = True, options = {'distance': 120})

这里输入图片描述

20

首先,你需要从一个语料库中读取带标签的句子。 NLTK提供了一个很好的接口,让你不用担心不同语料库的格式问题;你只需导入语料库,然后使用语料库对象的功能来访问数据。具体可以参考这个链接

接下来,你需要选择一个标注器并训练它。虽然有很多高级选项,但你可以先从N-gram标注器开始。

然后,你就可以使用这个标注器来标注你想要的句子。下面是一个示例代码:

from nltk.corpus import cess_esp as cess
from nltk import UnigramTagger as ut
from nltk import BigramTagger as bt

# Read the corpus into a list, 
# each entry in the list is one sentence.
cess_sents = cess.tagged_sents()

# Train the unigram tagger
uni_tag = ut(cess_sents)

sentence = "Hola , esta foo bar ."

# Tagger reads a list of tokens.
uni_tag.tag(sentence.split(" "))

# Split corpus into training and testing set.
train = int(len(cess_sents)*90/100) # 90%

# Train a bigram tagger with only training data.
bi_tag = bt(cess_sents[:train])

# Evaluates on testing data remaining 10%
bi_tag.evaluate(cess_sents[train+1:])

# Using the tagger.
bi_tag.tag(sentence.split(" "))

在一个大语料库上训练一个标注器可能需要相当长的时间。为了避免每次都训练一个标注器,我们可以把训练好的标注器保存到文件中,以便以后再使用。

请查看存储标注器部分,了解更多信息。

撰写回答