Introdução a NLTK com Dom Casmurro
Uma análise de uma das obras mais renomadas de Machado de Assis utilizando uma das principais biblioteca de NLP
Texto escrito por Guilherme Fernandes e Vitoria Rodrigues.
Olá, queridos leitores. Bem vindo a mais um Turing Talks! Desta vez, abordaremos um assunto que diz respeito a área de Processamento de Linguagem Natural, mais especificamente, vamos abordar uma breve introdução a NLTK, uma das principais bibliotecas de NLP. Para isso, vamos utilizar uma das renomadas obras de Machado de Assis: Dom Casmurro!
O que é NLTK?
NLTK, que significa Natural Language Toolkit, é uma biblioteca disponível na linguagem Python para realizar tarefas de NLP. É uma das principais bibliotecas de estudo para quem está ingressando nessa área, pois nela se encontram datasets e alguns algoritmos essenciais para análise e pré-processamento textual.
Como importar as obras de Machado de Assis na NLTK?
Por meio da biblioteca NLTK é possível acessar diversos corpus, isto é, dataset de textos. Cada obra apresentada no link contém um id dentro da NLTK, esse identificador será utilizado para acessar os dados via interface python, conforme veremos a seguir:
Pré-processamento do texto com NLTK
Antes da análise, precisamos preparar nosso texto. Fazemos isso porque, para a máquina, algumas palavras ou estruturas dele não importam e não fazem diferença — essa ideia ficará mais clara ao longo do nosso post, mas para se aprofundar melhor nesse assunto, recomendamos este artigo sobre Introdução ao Processamento de Linguagem Natural, em especial a sessão que trata sobre Pré-processamento.
A biblioteca NLTK oferece praticamente todas as ferramentas necessárias para um bom pré-processamento, vamos vê-las a seguir:
Stopwords
Existem palavras na construção textual chamadas de stopwords, tais palavras, dentro de uma abordagem de NLP, são irrelevantes e sua remoção colaboram com a analise textual. Alguns exemplos de stopwords comuns no português são preposições (em, na, no, etc), artigos (a, o,os, etc),conjunções (e, mas, etc), entre outras. Quando analisadas pela máquina essas palavras não possuem significância, podendo apenas atrapalhar os processos de aprendizado de máquina. Por esse motivo, geralmente, no pré-processamento removemos essas palavras.
A biblioteca NLTK mais uma vez auxilia nesse processo, pois fornece as stopwords de uma língua.
Assim, podemos removê-las de um texto, comparando-as com as palavras do nosso texto e mantendo somente as que não são stopwords, como veremos ao longo do texto.
Lemmatização e Stemmatização
Assim como Stopwords, ter verbos conjugados em um texto não faz diferença quando a máquina vai processá-lo. Por isso, existem duas ferramentas chamadas Lemmatização e Stemmatização. Ambas fazem a mesma coisa: Quando passado um texto como argumento, elas reduzem todas as formas conjugadas à sua raiz. A única diferença, entretanto, é que a função que lemmatiza seu texto reduz todos os verbos a forma verdadeira da raiz — por isso quanto maior seu texto, mais tempo essa função demora para rodar no código — , enquanto a função que stemmatiza apenas “corta” as palavras no meio usando a raiz como base, o que pode gerar palavras que não existem.
Por exemplo, ao lemmatizar o verbo “andando” teríamos “andar” (sua forma reduzida corretamente), mas ao stemmatizar provavelmente teríamos “anda”, já que ele cortaria o verbo apenas usando como base a raiz, e não fazendo a mudança necessária. Por fim, para entender como essas duas funções funcionam vamos pegar uma frase como exemplo: “Eu fui andando enquanto bebia um café”. Passando ela por um lemmatizador, teremos então “Eu ir andar enquanto beber um café”.
Na biblioteca NLTK temos dois stemmatizadores:
E um lemmatizador:
Tokenização com word_tokenize e sent_tokenize
Outra parte importante no pré-processamento de um texto é a tokenização. Isto é, transformar elementos do seu texto em tokens, ou seja, strings dentro de uma lista — ou, se você não tiver conhecimento de python, transformar todas as palavras do texto em elementos individuais separados por aspas.
Podemos tokenizar palavras com word_tokenize, essa função recebe o texto como argumento e retorna todas as palavras do texto em forma de tokens.
Já com sent_tokenize, podemos tokenizar as frases do texto, ou seja, dividir o texto em frases. Vale ressaltar que para isso, o texto precisa estar com pontuação, já que essa função utiliza os pontos finais como parâmetro de onde cortar o texto.
Função completa
Um outro pré-processamento necessário é selecionar apenas letras — para evitar que pontuações interfiram na análise — e fazemos isso com REGEX, uma outra biblioteca de Python e, já que o foco desse texto é NLTK, não vamos nos aprofundar nesse assunto.
Por fim, nossa função de pré-processamento completa deve ficar assim:
Análise
Com nosso pré-processamento feito, podemos partir para a análise! Vamos analisar algumas informações relativas ao livro, como contagem de vocabulário, bigramas, frequência de palavras e outros conceitos. Bora lá!
Análise de Frequência com FreqDist
Um tipo de análise recorrente quando estamos tratando de dados textuais é realizada por meio de contagem de palavras.
Mas, para que essa análise seja bem feita, é necessário que haja o pré-processamento. Por exemplo, suponha que deixamos de remover as stopwords, nesse caso as palavras mais frequentes acabam sendo artigos, pontuação e preposições. Esse é um dos motivos pelos quais processar/preparar seu texto é tão importante!
Ali em cima criamos a função de pré-processamento, aqui neste exemplo vamos aplicá-la ao nosso corpus (outra palavra para se referir ao livro Dom Casmurro) e depois plotar um gráfico mostrando quais são as palavras mais frequentes na nossa obra:
Concordância
Essa função serve para nos mostrar em quais contextos determinada palavra aparece, ela nos retorna o contexto que cerca o argumento. Isso é feito colando a palavra no centro das frases onde ela tende a aparecer através da função .concordance, que por sua vez recebe a palavra como argumento. Aqui vamos ver a palavra “capitu” em seus contextos:
Similaridade
Usando a função ‘similar’ temos uma lista de palavras que tendem a ocorrer no mesmo contexto. Nesse caso, o contexto são apenas as palavras que ocorrem frequentemente de qualquer lado da palavra.
Bigramas
Encontrar bigramas é uma parte importante para a análise de um texto. Mas primeiro, o que são bigramas? São palavras no texto que possuem um sentido único estando juntas, podendo até ocorrer separadas, mas com um sentido quando juntas. Por exemplo, nomes compostos (João Alfredo, Maria Júlia) ou nomes de cidades (São Paulo, Rio de Janeiro, Nova Iorque) são exemplos claros de bigramas, essas palavras podem ocorrer sozinhas, mas ocorrendo juntas possuem um significado.
Para encontrar os bigramas de um texto com NLTK, basta chamar a função ‘collocations’:
Gráfico de Dispersão
Por fim, vamos analisar uma ferramenta incrível da NLTK: O Gráfico de dispersão. Essa função serve para analisar a ocorrência das palavras ao longo de todo o texto — no nosso caso, do livro — e mostra nos riscos do eixo horizontal quando essa palavra tende a ocorrer nele! Vamos dar uma olhada como plotar esse gráfico e dar uma analisada nas ocorrências:
Primeiro, temos que importar a biblioteca matplotlib — aquela famosa biblioteca de python para criar gráficos — , depois, definimos o tamanho do gráfico, neste caso será 15x10, e chamamos a função “.dispersion_plot” que leva no argumento todas as palavras que queremos analisar, aqui escolhemos “capitu”, “mãe”, “olhos”, “seminário”, “amor”, “bentinho” , “escobar” e “ezequiel”:
Vamos ver como fica o gráfico?
Com esse gráfico fica claro que, embora Capitu não apareça nos primeiros capítulos, uma vez que ela entra na história tende a aparecer durante todo o livro. Também podemos ver que a mãe de Bentinho está presente durante praticamente toda a obra, assim como a ocorrência da palavra “seminário”, parte importante da vida do protagonista. Já Escobar, entra na história apenas a partir do meio do livro, pois ele e Bentinho se conhecem no seminário, e Ezequiel, seu filho, aparece quase ao fim do livro, já que nasce quando Bentinho já é adulto.
Conclusão
Nesse Turing Talks vimos algumas funções da biblioteca NLTK para ajudar no pré-processamento e na análise do seu texto, porém, essa foi apenas uma pequena fração da capacidade dessa biblioteca enorme. Recomendamos que, caso você tenha interesse, dê uma lida no NLTK Book — de onde os códigos desse artigo foram tirados — , um livro que introduz a biblioteca desde o básico, como abordado nesse texto, até o avançado, como formas de construir modelos de aprendizado de máquina!
Não deixe de acompanhar o Grupo Turing no Facebook, Linkedin, Instagram e nossos posts do Medium =)
Bons estudos e até a próxima!
Agradecimentos especiais à Julia Pociotti.