Modelagem de Tópicos em Python utilizando o Modelo de Alocação Latente de Dirichlet (LDA)

A modelagem de tópicos é um método que extrai tópicos ocultos de grandes volumes de texto. Ela utiliza as aplicações do processamento de linguagem natural para extrair os tópicos que as pessoas estão mais discutindo, dentre os volumes de texto apresentados.

E o modelo Latent Dirichlet Allocation (LDA) é um algoritmo utilizado para modelagem de tópicos que tem implementações no pacote Gensim do Python.

Esse processo é bem importante para as empresas que querem criar estratégias de monetização e melhoria de serviços, por exemplo, seja analisando avaliações de clientes, feedbacks de usuários, notícias, redes sociais, etc.

Sendo assim, o objetivo deste artigo é de criar um algoritmo automatizado que possa ler documentos e gerar os tópicos mais discutidos.

Para isso, é de extrema importância que os dados tenham qualidade no pré-processamento do texto e na melhor estratégia para encontrar o número de tópicos. Isso pode garantir uma qualidade maior, clareza e significância nos tópicos extraídos.

Esta análise foi realizada com dados extraídos de um repositório do Github nomeado “Manchetes Brasil”, de Paula Dornhofer Paro Costa (Costa, PDP), 2017. Essa base conta com dados de 500 manchetes de jornais brasileiros em datas específicas de dezembro de 2016 a agosto de 2017. Os jornais são: Valor Econômico, O Globo, Folha de S. Paulo e O Estado de S. Paulo.

O link para a base de dados pode ser acessada no https://github.com/pdpcosta/manchetesBrasildatabase

Como será estruturado este documento:

  1. Importação de pacotes
  2. Coleta de dados
  3. Limpeza de dados
  4. Modelagem de bigramas e trigramas
  5. Transformação de dados: corpus e dicionário
  6. Aplicação do modelo LDA
  7. Métricas: coerência e complexidade
  8. Encontrando o número ideal de tópicos
  9. Conclusão
  10. Referências

1. IMPORTAÇÃO DE BIBLIOTECAS

Para começar, foi necessário importar algumas bibliotecas importantes, dentre elas o pandas, numpy, matplotlib, nltk, re e gensim:

import re
import numpy as np
import pandas as pd
from pprint import pprint
import unicodedata

# Importando a library Natural Language Toolkit - NLTK para tratamento de linguagem natural.
import nltk
nltk.download('wordnet')
nltk.download('punkt')

#Importando as stopwords
from nltk.corpus import stopwords
nltk.download('stopwords')
language = 'portuguese'
stopwords = stopwords.words(language)
stopwords = list(set(stopwords))

#Gensim
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel

#Plotagem
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from wordcloud import WordCloud, STOPWORDS
%matplotlib inline

import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.ERROR)

import warnings
warnings.filterwarnings("ignore",category=DeprecationWarning)

2. COLETA DE DADOS

O conjunto de dados utilizado, como foi mencionado anteriormente, é a base de manchetes brasileiras.

Portanto, foi importado para dentro do Google Colab o arquivo csv, através do código abaixo. O arquivo contém colunas de dia, mês, ano, jornal e as headlines(notícias).

Para visualizar, foi aplicado o método head() que traz os 5 primeiros dados do nosso dataset:

caminho = '/content/manchetesBrasildatabase.csv'
dataframe = pd.read_csv(caminho, quotechar="'", header = None, names = ["Day", "Month", "Year", "Company", "Headline"]) dataframe.head()

Para este artigo, foi realizada a modelagem de tópicos somente para o jornal Folha de São Paulo, portanto, aplicou-se o método loc() para selecionar somente este jornal, atribuindo a uma nova variável, como mostra abaixo:

dataframe_folha = dataframe.loc[dataframe['Company'] == 'Folha'] dataframe_folha

Sendo assim, o dataframe ficou com 127 colunas e 5 colunas.

3. LIMPEZA DOS DADOS

Como é possível visualizar na coluna Headline, os textos apresentam pontuações, acentuações, letras maiúsculas, stopwords… Para aplicação do modelo LDA é necessário que as palavras estejam sem essas distrações.

Além disso, para ser consumido pelo LDA, é necessário fazer uma quebra de cada frase em palavras através da tokeinização.

Portando o seguinte processo foi realizado:

a) Conversão da coluna para lista, remoção de novas linhas e distrações:

# Convertendo para lista
data = dataframe_folha.Headline.values.tolist()
# Removendo novas linhas
data = [re.sub('\s+', ' ', sent) for sent in data]
# Removendo distrações
data = [re.sub("\'", "", sent) for sent in data]

b) Substituição de letras maiúsculas por letras minúsculas:

#Aplicando função para deixar somente letras minúsculas.
def to_lowercase(words):

new_words = [] for word in words:
new_word = word.lower()
new_words.append(new_word)
return new_words

c) Remoção de caracteres NON-ASCII:

#Aplicando função para remover os caracteres Non ASCII
def remove_non_ascii(words):
"""Remove non-ASCII characters from list of tokenized words"""
new_words = []
for word in words:
new_word = unicodedata.normalize('NFKD', word).encode('ascii', 'ignore').decode('utf-8', 'ignore')
new_words.append(new_word)
return new_words

d) Remoção de stop words:

As stop words (ou palavras de parada) são palavras que podem ser consideradas irrelevantes para um conjunto de documentos. Ex: e, os, de, para, com, sem, foi.

def remove_stopwords(texts):
return [[word for word in simple_preprocess(str(doc)) if word not in stopwords] for doc in texts]
# Removendo Stop Words
data_words_nostops = remove_stopwords(data_words)

Somente aplicando as stopwords do NLTK não é suficiente para as palavras em português, pois não possui uma base tão boa. Por isso, aplicou-se o método append() para algumas palavras identificadas na análise, adicionando-as à biblioteca de stopwords.

#Adicionando novas stopwords em português
stopwords = nltk.corpus.stopwords.words('portuguese') stopwords.append('ja')
stopwords.append('viu')
stopwords.append('vai')
stopwords.append('ne')
stopwords.append('ai')
stopwords.append('ta')
stopwords.append('gente')
stopwords.append('nao')
stopwords.append('aqui')
stopwords.append('tambem')
stopwords.append('vc')
stopwords.append('voce')
stopwords.append('entao')
stopwords.append('ate')
stopwords.append('agora')
stopwords.append('ser')
stopwords.append('sempre')
stopwords.append('ter')
stopwords.append('so')
stopwords.append('porque')
stopwords.append('sobre')
stopwords.append('ainda')
stopwords.append('la')
stopwords.append('tudo')
stopwords.append('ninguem')
stopwords.append('de')

e) Remoção de pontuação e tokeinização através do simple_preprocess do Geisim:

#Removendo pontuação e fazendo a tokeinização (para conseguir aplicar o modelo LDA)
def sent_to_words(sentences):
for sentence in sentences:
yield(gensim.utils.simple_preprocess(str(sentence), deacc=True)) # deacc=True removes punctuations

data_words = list(sent_to_words(data))


Comments

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *