Trabalhando com o python NLTK: Como posso melhorar a precisão do marcador POS?

Eu tenho usado o tagger PDV da NLTK:

... nltk.pos_tag(nltk.word_tokenize(tfile[i])) ... 

mas às vezes eu recebo resultados imprecisos (NN quando eu deveria estar recebendo JJ, e assim por diante. O texto que eu quero marcar está dentro de um domínio de negócios bastante específico … Eu não tenho a liberdade de dizer qual domínio aqui). Evidentemente, eu não sou um especialista em Python ou NLTK (trabalhando nisso, no entanto), mas eu queria saber se havia alguma maneira de melhorar a precisão do tagger.

Acho que entendo que o tagger trabalha comparando o texto dado a um corpus de texto pretendido. Minha inclinação natural é tentar adicionar um conjunto de minhas próprias frases autotipadas a este corpus … mas não sei como fazer isso.

Eu apreciaria muito qualquer conselho sobre como adicionar (eu prefiro adicionar a um existente ao invés de iniciar um novo inteiramente) meu próprio texto para o corpus, ou se alguém tiver outras sugestões para melhorar a precisão do tagger para os meus propósitos, eu adoraria ouvir isso.

Obrigado!

Você provavelmente já viu o livro do GoogleCode em nltk . Eu tenho trabalhado muito lentamente por conta própria e enquanto eu ainda tenho que lidar com o POS-tagging, é uma das coisas que eu quero fazer quando me sinto bem o suficiente para usar a ferramenta. De qualquer forma, no Capítulo 5 , seção 2, você obtém o seguinte texto e exemplos sobre como criar seu próprio conjunto de tokens marcados (desculpas a todos, mas copiei diretamente do texto):

 >>> tagged_token = nltk.tag.str2tuple('fly/NN') >>> tagged_token ('fly', 'NN') >>> tagged_token[0] 'fly' >>> tagged_token[1] 'NN' 

Continuação da 5.2:

Podemos construir uma lista de tokens marcados diretamente de uma string. O primeiro passo é tokenizar a string para acessar as strings individuais de word / tag, e depois converter cada uma delas em uma tupla (usando str2tuple ()).

 >>> sent = ''' ... The/AT grand/JJ jury/NN commented/VBD on/IN a/AT number/NN of/IN ... other/AP topics/NNS ,/, AMONG/IN them/PPO the/AT Atlanta/NP and/CC ... Fulton/NP-tl County/NN-tl purchasing/VBG departments/NNS which/WDT it/PPS ... said/VBD ``/`` ARE/BER well/QL operated/VBN and/CC follow/VB generally/RB ... accepted/VBN practices/NNS which/WDT inure/VB to/IN the/AT best/JJT ... interest/NN of/IN both/ABX governments/NNS ''/'' ./. ... ''' >>> [nltk.tag.str2tuple(t) for t in sent.split()] [('The', 'AT'), ('grand', 'JJ'), ('jury', 'NN'), ('commented', 'VBD'), ('on', 'IN'), ('a', 'AT'), ('number', 'NN'), ... ('.', '.')] 

Aquela variável “enviada” acima é, na verdade, o texto marcado, como confirmado indo para o diretório nltk_data no meu próprio computador e procurando por qualquer coisa no corpora / brown /, então você poderia escrever seu próprio texto marcado usando esta formatação e Em seguida, crie seu próprio conjunto de tokens marcados com ele.

Depois de configurar seus próprios tokens marcados, você poderá configurar seu próprio marcador de unigram com base em seus tokens marcados (de 5.5):

 >>>unigram_tagger = nltk.UnigramTagger(YOUR_OWN_TAGGED_TOKENS) 

Por fim, como o texto marcado provavelmente é uma amostra muito pequena (e, portanto, impreciso), é possível listar um marcador substituto para que, quando ele falhar, o substituto venha para o resgate:

 >>> t0 = nltk.UnigramTagger(a_bigger_set_of_tagged_tokens) >>> t1 = nltk.UnigramTagger(your_own_tagged_tokens, backoff=t0) 

Por último, você deve olhar para as diferenças n-grama, bigrama, unigrama, etc., também abordadas no capítulo 5 acima mencionado.

De qualquer forma, se você continuar lendo o Capítulo 5, verá algumas maneiras diferentes de marcar texto (incluindo o meu favorito: o regex tagger!). Há muitas maneiras de fazer isso e muito complexo para cobrir adequadamente em um pequeno post como este.

Emptor de advertência: Eu não tentei todo esse código, então eu ofereço isso como uma solução que estou atualmente tentando resolver. Se eu cometi erros, por favor ajude-me a corrigi-los.

“Como faço para melhorar o tagger NLTK” é uma pergunta popular 🙂 Eu definitivamente não aconselho você a fazer um corpus para treinar um tagger com mão. Os taggers precisam de uma quantidade enorme de dados para funcionar corretamente no novo texto.

O que você poderia fazer, se você quer fazer o esforço, é “bootstrap” um corpus: Tag um monte de texto em seu domínio com o tagger NLTK, mão-corrigir os erros em um subconjunto (mais fácil se eles são previsíveis), use o resultado para treinar um tagger melhor. Você pode até mesmo repetir o processo para que você possa fazer uma limpeza manual de uma quantidade maior de seu próprio material. Seu novo tagger ainda será baseado em uma quantidade relativamente pequena de texto, para que você possa adicionar o tagger padrão como um substituto, como mostra @erewok. Veja também esta questão , que pede a mesma coisa.

Como @erewok apontou, usar um backoff tagger é uma boa maneira de melhorar as coisas. Comece com o mais preciso. Se não puder marcar, ou a probabilidade calculada estiver abaixo de um limite definido, tente o próximo método (menos preciso). Mesmo uma etapa final “suponha que seja um substantivo” pode fazer uma melhoria mensurável.

Coisas como os taggers unigram e bigram geralmente não são tão precisos. Eu recomendaria começar com um tagger Naive Bayes primeiro (estes são abordados no livro de O’Reilly). Isso poderia usar um tagger Unigram ou Wordnet (olha a palavra no Wordnet e usa o exemplo mais freqüente) como um back-tagger.

Em seguida, você pode mover para um tagger MaxEnt (Maximum Entropy) que é considerado mais preciso que o Naive Bayes devido ao seu suporte para resources dependentes. No entanto, é mais lento e requer mais esforço para implementar – o resultado final pode não valer a pena. A versão NLTK também pode ser um pouco difícil de usar.

Para treinar esses taggers, o NLTK vem com vários corpora. Não sabendo nada sobre o seu domínio, eu não sei o quão útil eles serão, mas eles incluem um subconjunto do Penn Treebank, alguns corpora específicos do domínio, vários idiomas, etc. Dar uma olhada.

Assim como o livro da O’Reilly, eu recomendaria o livro de receitas NLTK de processamento de textos em Python Jacob Perkins, que inclui exemplos práticos desse tipo de coisa.