Академический Документы
Профессиональный Документы
Культура Документы
Marcelo Celeghini
SÃO PAULO
2012
RESUMO
CONVENÇÕES ADOTADAS
Sumário
INTRODUÇÃO ....................................................................................................................................... 12
1. PLN E PYTHON .................................................................................................................................. 14
1.1. O Processamento de Linguagem Natural .................................................................................. 14
1.2. A linguagem de programação Python ....................................................................................... 15
1.3. O Interpretador interativo ......................................................................................................... 16
1.4. Utilizando simples técnicas para processamento de textos ...................................................... 17
1.4.1. O uso de funções ................................................................................................................ 20
1.5. A biblioteca NLTK ...................................................................................................................... 22
1.6. Alguns desafios na área de Processamento de Linguagem Natural .......................................... 24
2. PROCESSAMENTO DE TEXTO BRUTO E O USO DE RECURSOS LÉXICOS ............................................ 26
2.1. Transformando um texto em tokens ......................................................................................... 26
2.2. Recursos léxicos ........................................................................................................................ 28
2.3. Stopwords ................................................................................................................................. 32
2.4. Expressões regulares e detecção de padrões ............................................................................ 33
3. AS CATEGORIAS LÉXICAS .................................................................................................................. 36
3.1. O processo de etiquetação ........................................................................................................ 38
3.1.1. Etiquetador padrão ............................................................................................................ 38
3.1.2. Avaliando a precisão de um etiquetador ............................................................................ 39
3.1.3. Etiquetador Unigram .......................................................................................................... 39
3.1.4. Combinando etiquetadores ................................................................................................ 42
4. ANÁLISE SINTÁTICA PARCIAL ............................................................................................................ 44
4.1. Expressões regulares para a identificação de padrões .............................................................. 44
4.2. Utilizando gramáticas para agrupar e desagrupar palavras....................................................... 46
5. CONSTRUINDO UM SISTEMA PARA CORREÇÃO VERBAL .................................................................. 48
5.1. Dicionários em Python .............................................................................................................. 49
5.2. Definindo os dicionários ............................................................................................................ 49
5.3. Definindo uma função auxiliar .................................................................................................. 51
5.4. Definindo uma função para correção Verbal ............................................................................. 52
6. CONCLUSÃO ..................................................................................................................................... 57
REFERÊNCIAS BIBLIOGRÁFICAS ............................................................................................................ 58
12
INTRODUÇÃO
Não seria bom poder dirigir um carro sem o uso das mãos, apenas
"conversando" com o automóvel?
1
http://tecnologia.uol.com.br/album/2011_falar_chines_aplicativos_album.jhtm?
13
Os livros que nos serviram de base para esse estudo foram “Natural
Language Processing with Python”, “Python Text Processing with NLTK 2.0
Cookbook”, “Mining the Social Web” e “Python 2.6 Text Processing Beginner's
Guide”.
1. PLN E PYTHON
- “Traduza esse blog do espanhol para o português, para que eu possa obter
as últimas informações sobre a erupção no Chile.” (Tradução Automática).
O PLN como área de estudos acadêmicos nunca foi mais relevante do que é
atualmente. E os sucessos obtidos nessa área devem-se à utilização de métodos
que são dirigidos por dados de linguagem natural em vez de usar métodos
puramente baseados no conhecimento ou baseados em regras, que além de não
serem tão robustas, possuem alto custo computacional.
2
Linguística é a ciência que estuda a linguagem verbal humana.
15
Várias linguagens de programação tem sido utilizadas para PLN, como por
exemplo Pearl, Prolog, Java, C ou Ruby. Mas essas linguagens apresentam uma
sintaxe mais complexa e portanto, uma curva de aprendizado mais acentuada.
Apesar de Python não ser tão veloz como linguagens compiladas como C ou
C++, a menor velocidade de execução não é percebida na maioria dos programas,
desse modo o menor tempo gasto em programação pode compensar o maior tempo
com a execução de código.
16
>>> len(objetivos_curso)
279
>>>
>>> dc = open(“dom_casmurro.txt”)
>>> texto = dc.read()
>>> len(texto)
373504
>>>
Uma string pode ser indexada e isso nos permite “fatiar” um texto. O índice
zero corresponde ao primeiro caractere da string e no nosso exemplo, o índice
373503 corresponde ao seu último caractere. Verificaremos agora quais são os
primeiros duzentos caracteres do nosso texto, os caracteres ‘\n’ representam uma
nova linha, e por convenção m:n significa o intervalo iniciando com o elemento m
até n-1, o intervalo abaixo inclui o elemento 0 até o elemento 199 (200 -1):
>>> texto[0:200]
'Romance, Dom Casmurro, 1899\n\nDom Casmurro\n\nTexto de
refer\xeancia:\n\nObras Completas de Machado de
Assis,\nvol. I,\n\nNova Aguilar, Rio de\nJaneiro,
19
Dom Casmurro
Texto de referência:
vol. I,
Janeiro, 1994.
Publicado originalmente
>>>
Essas operações com strings são importantes para o PLN, pois em muitos
casos teremos que fazer uso de expressões regulares nos algoritmos utilizados.
Para um aprofundamento no conhecimento das técnicas utilizadas para a
manipulação de strings e outras técnicas de programação em Python, pode-se
consultar a documentação em http://www.python.org.br/wiki/DocumentacaoPython.
20
Para definir uma função, nós usamos a palavra reservada ‘def’, seguida
pelo nome da função, e seguida por um par de parênteses que podem conter ou não
parâmetros (dados para serem usados pela função). Para finalizar a definição da
função usamos o símbolo de dois pontos.
>>> open_read_len("dom_casmurro.txt")
373504
Se quisermos reutilizar a mesma função, mas com outro texto, basta passar
um diferente argumento no momento da chamada da função, como no exemplo
abaixo:
Dessa vez passamos como argumento outro arquivo, contendo uma diferente
obra de Machado de Assis, o romance Memórias Póstumas de Brás Cubas. E o
valor retornado pela função foi o de 355706 caracteres.
3
Quebra uma string em tokens, que são os segmentos de texto ou símbolos que serão manipulados pelo
Analisador Sintático.
23
O texto ptext2 se refere ao livro Dom Casmurro. Só que nesse caso, como
já explicamos todas as suas palavras, símbolos e pontuações estão isolados na
forma de tokens, diferentemente do texto dom_casmurro.txt que foi usado na
seção 1.4 e que se refere a uma longa string.
Com o auxílio da função count() que conta o número de vezes que uma
específica string aparece numa lista, verificaremos agora a porcentagem que a
palavra “Deus” ocupa nos livros Gênesis e Dom Casmurro respectivamente:
4
A palavra ‘São’ de São Paulo está grafada incorretamente como ‘Sau’, provavelmente devido a uma falta de
atenção dos desenvolvedores do NLTK.
24
Uma máquina poderá um dia pensar? Esse é uma questão clássica na área
de inteligência artificial proposta por Alan Turing em 1950.
5
2001: A Space Odyssey (br: 2001: Uma Odisseia no Espaço) é um filme americano de 1968 dirigido e
produzido por Stanley Kubrick, co-escrito por Kubrick e Arthur C. Clarke. O filme lida com os elementos
temáticos da evolução humana, tecnologia, inteligência artificial e vida extraterrestre.
6
Blade Runner (br: Blade Runner: O Caçador de Andróides ) é um filme americano de 1982 dirigido por Ridley
Scott. No início do século XXI, uma grande corporação desenvolve um robô que é mais forte e ágil que o ser
humano e se equiparando em inteligência. São conhecidos como replicantes e utilizados como escravos na
colonização e exploração de outros planetas.
25
O que esperar então de um sistema para uma pergunta mais elaborada como:
Qual é a melhor época do ano para tirar férias e viajar para o Nordeste?
Não é preciso ser um agente de viagens para saber que a melhor época do
ano para aproveitar as férias no Nordeste é fora do conhecido período de chuvas.
Em uma conversa entre humanos nem precisaríamos citar que estamos nos
referindo ao nordeste brasileiro. Mas uma máquina precisaria armazenar e
manipular conhecimento para isso, ela teria que saber que durante as férias a
maioria dos brasileiros procura sol e calor e que isso corresponde ao adjetivo
“melhor” da pergunta. Também teria que saber em quais meses chove menos na
região nordeste do Brasil.
7
Inferência é o processo pela qual concluímos algo por meio de um raciocínio. De várias proposições nós
inferimos uma conclusão. Inferir é, portanto, chegar a uma resposta a partir de juízos anteriores.
26
8
A sumarização compreende dois processos: a seleção do conteúdo relevante de uma mensagem fonte
primária e sua organização coerente.
9
http://idgnow.uol.com.br/mercado/2010/08/06/reconhecimento-de-voz-vai-ficar-mais-esperto-promete-
pesquisador/#&panel2-1
27
Para continuar nosso estudo, precisamos transformar esse texto, que é uma
string (lista de caracteres), em uma lista de tokens. Esse processo é chamado de
tokenização e faz uso da função word_tokenize().
Obtemos agora um objeto da classe “texto NLTK”, pronto para o estudo dos
recursos léxicos da biblioteca NLTK.
28
Para o próximo exemplo usaremos um texto que não sabemos sobre qual
assunto trata, e com o uso de um recurso léxico simples chamado Distribuição de
Frequência, tentaremos descobrir o assunto do texto.
Analisando o resultado:
Em outras palavras, a variável 'w' que aqui poderia ser qualquer outro nome,
percorre cada item da lista vocabulario por intermédio do comando for, e se o
token é formado só por letras, ele é então convertido para minúsculas e o resultado
é atribuído à variável vocab_minusculas.
>>> dist_freq['reconhecimento']
24
>>> dist_freq['palavras']
20
>>>
Figura 2.1: Gráfico com a frequência acumulada dos 40 tokens mais usados no
texto, que juntos correspondem a quase metade dos 2805 tokens identificados.
32
2.3. Stopwords
, 123
" 46
. 34
reconhecimento 24
palavras 20
voz 19
sistema 17
fala 15
programa 15
sao 14
nao 13
sistemas 13
tambem 13
computador 11
usuarios 11
ser 10
som 10
( 9
) 9
>>>
Uma expressão regular pode ser vista como um conjunto de caracteres que
especificam um padrão. É uma maneira que o programador usa para dizer como o
computador deve procurar por certos formatos dentro do texto, e o que fazer após
encontrá-los.
>>> import re
>>> final_ido = [w for w in ptext4 if re.search('ido$',
w)][:20]
>>> type(final_ido)
<type 'list'>
>>> final_ido
[u'reduzido', u'abolido', u'abolido', u'pedido', u'sido',
u'marido', u'apreendido', u'r\xe1pido', u'r\xe1pido',
u'Devido', u'r\xe1pido', u'sido', u'r\xe1pido',
u'Partido', u'Unido', u'Partido', u'Unido', u'prometido',
u'sido', u'assumido']
>>>
10
O Padrão Unicode especifica a representação do texto em software e padrões modernos. O Unicode fornece
um único número para cada caractere, não importa a plataforma, não importa o programa, não importa a
língua. (Em: <http://unicode.org/standard/translations/portuguese.html>. Acesso em: 09 maio 2012.)
11
http://aurelio.net/regex/
36
Como resultado, obtemos uma lista com todas as ocorrências das vogais
minúsculas definidas entre os colchetes e encontradas na variável frase, incluindo
caracteres acentuados como á ou é, representados internamente nos formatos
hexadecimais e3 e e9, respectivamente. Os caracteres \x representam um escape
sequence (sequência de escape), como já vimos anteriormente na seção 1.4 deste
trabalho.
3. AS CATEGORIAS LÉXICAS
12
Mac-Morpho se trata de uma coleção de textos em português do Brasil, extraídos de diferentes seções do
jornal Folha de São Paulo de 1994. Esse corpus possui mais de um milhão de palavras já etiquetadas.
37
Uma tupla é uma sequência, assim como listas e strings. A diferença é que
ela é imutável, portanto, uma vez criada, não pode ser modificada. Ela também pode
ser indexada e isso permite que os seus elementos sejam acessados por índices. As
tuplas são criadas usando parênteses e seus elementos são separados por vírgulas.
Vamos imprimir o resultado do exemplo anterior em uma forma mais fácil para
leitura, usando o comando print:
Jersei N
atinge V
média N
de PREP
Cr$ CUR
1,4 NUM
milhão N
em PREP|+
a ART
venda N
>>>
Primeiro atribuímos à variável tuplas uma lista com as dez primeiras tuplas
do corpus Mac-Morho. Posteriormente utilizamos o comando for para percorrer
todos os elementos de tuplas e atribuímos o primeiro elemento de cada uma à
variável x, e o segundo a variável y. Na sequência usamos o comando print para
imprimir x (a palavra) e y (a etiqueta).
Apesar de não fazer muito sentido marcar toda palavra com a mesma
etiqueta, o etiquetador padrão é útil para etiquetar palavras desconhecidas. Assim,
ao combinarmos o etiquetador padrão com etiquetadores mais robustos, poderemos
agrupar todas as palavras desconhecidas em uma mesma categoria.
Para imprimir o resultado em uma forma mais legível podemos usar o comando
print, como já foi explicado nos capítulos anteriores.
processamento N
de PREP
linguagem N
natural ADJ
é V
uma ART
área N
da NPROP
inteligência N
artificial ADJ
>>>
>>> etiquetador.evaluate(sentencas_treinadoras)
0.87600245449464142
>>>
Expressões regulares também podem definir padrões para palavras que não
desejamos que façam parte de um bloco.
Para definir uma etiqueta, colocamo-la entre os sinais de menor que (<) e
maior que (>), como em <N>, que especifica uma etiqueta para um substantivo.
A sintaxe das expressões regulares pode ser utilizada tanto dentro como fora
dos símbolos < >.
45
Em <N.*> por exemplo, queremos encontrar qualquer etiqueta que inicie com
a letra N, seguida por qualquer outro símbolo (representado pelo sinal de
pontuação), zero ou mais vezes (representado pelo metacaractere asterisco).
Vamos agora criar uma gramática para extrair frases sem verbos de uma
sentença, e para isso usaremos regras de agrupamento e de desagrupamento. Em
seguida construiremos uma árvore de análise para a sentença.
Na terceira linha definimos a nossa gramática como ‘FN’ (frase nominal). Uma
frase nominal é aquela que não possui verbos.
A segunda regra, entre chaves opostas, diz que os verbos <V>, devem ser
desagrupados.
47
>>>analis_gram.parse([('O','ART'),('mundo', N'),('possui',
'V'), ('diversos', 'ADJ'), ('idiomas', 'N')])
Tree('S', [Tree('FN', [('O', 'ART'), ('mundo', 'N')]),
('possui', 'V'), Tree('FN', [('diversos','ADJ'),
('idiomas', 'N')])])
Existem outras regras para manipular blocos, como as regras de fusão, que
unem blocos distintos e as regras de divisão que dividem blocos.
A ideia que nos motivou a criar um corretor verbal foi a de demonstrar como
as metodologias e técnicas aplicadas nesse sistema, podem ser utilizadas em
sistemas semelhantes, como corretores ortográficos e outros mais complexos, como
os corretores gramaticais que fazem amplo uso dos conceitos do processamento de
linguagem natural.
Verbo ‘ser’
3ª. Pessoa do Singular 3ª. Pessoa do Plural
(VS) (ele/ela) (VP) (eles/elas)
Presente do Indicativo (PI) é são
Pretérito Imperfeito (PIm) era eram
>>> singular_plural = {
('é', 'VSPI'): ('são', 'VPPI'),
('era', 'VSPIm'): ('eram', 'VPPIm')
}
>>> plural_singular = {
('são', 'VPPI'): ('é', 'VSPI'),
('eram', 'VPPIm'): ('era', 'VSPIm')
}
>>>
Isso quer dizer que quando o corretor verbal solicitar a correção da palavra
‘é’, a chave-tupla ('é', 'VSPI') apontará para o valor ('são', 'VPPI').
Na primeira linha do código usamos a palavra chave def para definir uma
função que nomearemos de indice_atributo. A função possui quatro
parâmetros, o primeiro (frase) é uma lista de tuplas a ser analisada, o segundo
(atributo) é o resultado de uma função lambda que retorna a etiqueta
identificadora de um verbo ou de um substantivo. Os outros dois parâmetros
(inicio e incremento) já iniciam com valores padrões 0 e 1 respectivamente. O
parâmetro inicio se refere ao primeiro índice do bloco a ser analisado (índice 0), e
é incrementado pela variável incremento a cada looping.
Em indice_substantivo = indice_atributo(frase,
atributo_substantivo, inicio=indice_verbo+1), a variável
indice_substantivo receberá o índice da tupla onde o substantivo é encontrado
na frase.
Caso nenhum substantivo seja encontrado ao lado direito do verbo então ele
será procurado do lado esquerdo, conforme definido a seguir:
if indice_substantivo is None:
indice_substantivo = indice_atributo(frase,
atributo_substantivo, inicio=indice_verbo-1,
incremento=-1)
55
Caso ele também não seja encontrado do lado esquerdo, a frase será
impressa na tela sem modificações.
if indice_substantivo is None:
return frase
substantivo, etiqueta_substantivo =
frase[indice_substantivo]
if etiqueta_substantivo.endswith('S'):
frase[indice_verbo] = singular_plural.get((verbo,
etiqueta_verbo), (verbo, etiqueta_verbo))
else:
frase[indice_verbo] = plural_singular.get((verbo,
etiqueta_verbo), (verbo, etiqueta_verbo))
return frase
Para testar o nosso corretor verbal, criamos algumas frases com verbos e
substantivos no início e meio da frase:
6. CONCLUSÃO
REFERÊNCIAS BIBLIOGRÁFICAS
BIRD, Steven; KLEIN, Ewan; LOPER, Edward. Natural Language Processing with
Python. First Edition. Sebastopol, CA O’Reilly Media, Inc., 2009
PERKINS, Jacob. Python Text Processing with NLTK 2.0 Cookbook. First
Edition. Birmingham, UK. Packt Publishing Ltd.,2010
MCNEIL, Jeff. Python 2.6 Text Processing Beginner's Guide. First Edition.
Birmingham, UK. Packt Publishing Ltd.,2010
Sites na Internet:
http://www.python.org/
http://code.google.com/p/nltk/
http://nltk.org/