Análise de texto usando Python

A análise de texto (~text mining) consiste no processo de obter informações através de dados no formato de um texto. Por se tratar de dados não-estruturados, a limpeza e tratativa é parte relevante e pouco trivial do processo. Falei brevemente de text mining no post Introdução ao Text Mining com Python. Hoje, volto ao tema utilizando uma biblioteca que me deixou bastante surpreso com seu poder de análise: a texthero!

INTRODUÇÃO

Primeiro, gostaria de dizer que a análise foi quase que inteiramente retirada da documentação original e pode ser acessada aqui. Fiz pequenas adaptações/inclusões, além de incluir comentários e explicações para facilitar a vida do leitor. Não gostaria de deixar a impressão que quero levar crédito ou “roubar” conteúdo. Dito isto, vamos ao que importa…

Caso você nunca tenha utilizado a texthero, comece indo ao terminal e digitnado pip install texthero. Agora, abra o jupyter notebook, pois já podemos carregar a biblioteca texthero, o pandas – que servirá para carregar o dataset – e também o dataset que está num github específico:

# carrega bibliotecas
import texthero as hero
import pandas as pd

# carrega dataset para ser usado como exemplo
df = pd.read_csv(
"https://github.com/jbesomi/texthero/raw/master/dataset/bbcsport.csv"
)

Feito isso, vamos dar uma olhada nas primeiras linhas, mas antes de utilizar o comando head(), utilize set_option do Pandas para aumentar o limite de caracteres que não será ocultado. Afinal, é interessante entender um pouco melhor o campo texto aqui:

pd.set_option('max_colwidth', 300)
df.head(5)

Como você pode ver, temos um dataset cheio de textos e o tópico ao qual ele se refere. Ou seja, é um dataset com rótulos, onde você poderia tentar aplicar modelos de aprendizado supervisionado.

Limpeza e Pipeline

Deixando isso de lado por enquanto, vamos testar a primeira função interessante que aparece no tutorial da documentação, a função clean():

# Limpeza = letras minusculas, exclusao de apostrofos, aspas e coisas do tipo
df['clean_text'] = hero.clean(df['text'])
df.head(2)

Como você pode ver na comparação, o texto original possui alguns tipos de pontuações, além de misturar letras maiúsculas e minúsculas. Isso é ruim para a análise de texto, afinal, ter uma vírgula não significa nada, e a palavra ‘Pai’ não é diferente da palavra ‘pai’. Por isso, toda análise de texto envolve esse passo de ‘limpeza’. No texthero, deu para ver que é muito simples!

Isso poderia ser feito com a função pipe do Pandas:

# pipeline
df['clean_text'] = df['text'].pipe(hero.clean)

Ou ainda criar um pipeline customizável somente com algumas tratativas:

from texthero import preprocessing

# Pipeline customizado
custom_pipeline = [preprocessing.fillna,
preprocessing.lowercase,
preprocessing.remove_whitespace]
df['clean_text'] = hero.clean(df['text'], custom_pipeline)

As tratativas podem ser incluídas no seu pipeline são:

  • fillna(s): Substitui os valores nulos;
  • lowercase(s): Transforma o texto em minúsculo;
  • remove_digits(): Remove dígitos;
  • remove_punctuation(): Remove pontuações (!”#$%&'()*+,-./:;<=>?@[\]^_`{|}~)’
  • remove_diacritics(): Remove acentos;
  • remove_stopwords(): Remove algum grupo de palavras específicadas (ótimo para excluir preposições, pronomes e outras palavras que não te interessam);
  • remove_whitespace(): Remove espaços em branco.

E apenas para fechar, como você poderia aplicar seu pipeline customizável utilizando a função pipe do Pandas:

df['clean_text'] = df['clean_text'].pipe(hero.clean, custom_pipeline)

Não sabe o que é pipeline? Dá uma passadinha no post Introdução aos Pipelines no Scikit-Learn. Mas não tem segredo, é somente uma sequência de passos com tratativas ordenadas que você deseja fazer na base. Se você não utiliza ainda, trate de praticar porque é bastante importante!

Term Frequency-Inverse Document Frequency (TDIDF)

Agora, vamos falar de TFIDF. Se você nunca ouviu falar deste termo, ele significa term frequency-inverse document frequency e é uma estatística que serve para destacar a importância de alguma palavra no texto. Se quiser explorar mais da matemática desta medida, vale começar pelo Wikipedia: https://en.wikipedia.org/wiki/Tf–idf. Aqui, você só precisa saber que estamos falando de um fator de ponderação usado em text mining para identificar se a palavra tem alguma relevância. E, para variar, é super simples de se obter no texthero:

# TFIDF
df['tfidf_clean_text'] = hero.tfidf(df['clean_text'])
df.head(5)

Note que temos um vetor com diversos números. Como no nosso caso há muitas palavras irrelevantes, os pesos são baixos. Mas veja um exemplo melhor:

# Exemplo com tfidf
s = pd.Series(["Aluno Marcos de matemática do curso de matemática", "Aluna Maria de português do curso de português da academia de português"])
hero.tfidf(s)

Aliás, é possível receber os nomes de cada feature:

# Exemplo com tfidf
s = pd.Series(["Aluno Marcos de matemática do curso de matemática", "Aluna Maria de português do curso de português da academia de português"])
hero.tfidf(s, feature_names=True)

Além disso, se você tiver muitas palavras irrelevantes, pode limitar o número de palavras:

# Exemplo com tfidf
s = pd.Series(["Aluno Marcos de matemática do curso de matemática", "Aluna Maria de português do curso de português da academia de português"])
hero.tfidf(s, feature_names=True, max_features=3)

PCA (Principal Component Analysis)

Igualmente interessante pode ser gerar o PCA:

# abordagem PCA
df['pca_tfidf_clean_text'] = hero.pca(df['tfidf_clean_text'])

Que também pode ser inserido num pipeline (sempre opte por esse caminho):

# ou tudo num passo só:
df['pca'] = (df['text']
.pipe(hero.clean)
.pipe(hero.tfidf)
.pipe(hero.pca))

E se quiser plotá-lo:

hero.scatterplot(df, col='pca', color='topic', title="PCA BBC Sport news")

Modelagem: K-Means

De forma semelhante, podemos rodar um K-Means. No pipeline abaixo, limpamos o texto, obtemos o TD-IF e obtemos os grupos com K-Means:

df['kmeans'] = (df['text']
.pipe(hero.clean)
.pipe(hero.tfidf)
.pipe(hero.kmeans))

df.head(3)

Por fim, quer localizar as palavras que aparecem com maior frequência?

Palavras mais Frequentes

Igualmente,  o top_words! No exemplo abaixo, utilizamos uma função lambda para obter as 3 palavras mais frequentes de cada texto agrupado por tópicos:

# Palavras mais comuns
NUM_TOP_WORDS = 3
df.groupby('topic')['text'].apply(lambda x: hero.top_words(x)[:NUM_TOP_WORDS])

Em resumo dá para fazer tudo com essa biblioteca. Há mais ainda para ser explorado e espero que você aproveite bem. Que tal tentar brincar com alguns textos da sua empresa ou dos seus estudos acadêmicos? Dá uma chance que essa biblioteca vale a pena!

Gostou do conteúdo? Se inscreva para receber as novidades! Deixe seu e-mail em INSCREVA-SE na barra à direita, logo abaixo de pesquisar. E, por favor, não deixe de comentar, dar seu feedback e compartilhar com seus amigos. De verdade, isso faz toda a diferença. Você também pode acompanhar mais do meu trabalho seguindo a conta de Twitter @EstatSite ou por alguma das redes que você encontra em Sobre o Estatsite / Contato, como meu canal de Youtube Canal do Yukio.

Bons estudos!

2 comentários em “Análise de texto usando Python”

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *