Mineração de texto


Atualmente, vivemos na era do Big Data, ou seja, estamos gerando dados a todo momento, porém, na maioria das vezes, são dados não estruturados, como notícias, e-mails e textos de forma geral. Mineração de textos ou do inglês Text Mining, tem como objetivo, encontrar termos relevantes e estabelecer relacionamento entre eles de acordo com a sua frequência e assim extrair informações de grandes volumes de textos.

Workflow

Ciclo de mineração

Agora, que sabemos que é possível obter informações, de grandes volumes de textos, vejamos como é o processo de obtenção dessas informações:

  • Começar com uma pergunta:
    Primeiramente, devemos ter um problema que queremos resolver, ou uma pergunta que desejamos responder, como, por exemplo: Qual o pet mais querido no momento?

  • Obter os dados:
    Agora, que temos um questionamento, precisamos conseguir os dados que o responda, sendo assim, utilizarei como fonte de dados, o que as pessoas estão conversando no Twitter.

  • Limpar:
    E com os nossos dados em mãos, iremos realizar outra etapa do processo, que é a limpeza dos nossos dados, removendo caracteres especiais, como acentos, pontuações, tranformando todas as palavras em uma só estrutura, como, minúsculo e removeremos todas as stopwords, que são palavras irrelevantes para a pergunta que queremos responder.

  • Analisar:
    Com os nossos dados prontos, iremos realizar uma das partes mais divertidas, que é analisar os nossos dados, onde poderemos aplicar diversas técnicas e verificar se com o dados que possuímos, responderemos à pergunta que nos motivou a analisar esses dados.

  • Visualizar:
    Nessa etapa, poderemos visualizar o resultado da nossa análise e assim gerar diversas opções de gráficos, como, por exemplo, nuvem de palavras.

  • Extrair conhecimento:
    E chegamos a última etapa, e se tudo estiver ocorrido bem, durante o processo de análise, teremos transformado os nossos dados em informação e agregando ao nosso entendimento prévio sobre o assunto, como resultado, gerado um conhecimento novo, sobre o fato que estávamos analisando.

Conceitos

Antes, de continuarmos, vamos conhecer alguns conceitos:

  • Corpus: Conjuntos de textos.
  • Stopwords: Como comentado anteriormente, são palavras que não adicionam sentido ao texto, como palavras de ligação por exemplo e existem listas de stopwords para vários idiomas na internet.

Código exemplo

Chegou o momento mais divertido onde criaremos um projeto básico de text mining, e para isso, utilizaremos a linguagem de programação R e os seguintes pacotes:

  • ‘rtweet’ É um pacote, que permitirá que você se conecte ao Twitter, caso você tenha uma conta, onde você poderá realizar buscas, com no máximo 18 mil tweets.
  • ‘tm’ O pacote tm de “Text Mining” é um pacote utilizado para trabalharmos com textos.
  • ‘wordcloud’ É um pacote que nos permite visualizar de forma rápida, as palavras, utilizando como critério de tamanho, a frequência.
  • ‘tydeverse’ É um pacote, que possui uma coleção de pacotes inclusos, para ajudar na manipulação dos dados.

Primeiramente, vamos instalar os pacotes que serão necessários durante o projeto:

# Instalando os pacotes
install.packages("rtweet")
install.packages("tm")
install.packages("wordcloud")
install.packages("tidyverse")

E com os pacotes instalados, devemos carregar os mesmos e assim poderemos utilizar as funções desses pacotes.

# Carregando os pacotes
library(tm)
library(rtweet)
library(wordcloud)
library(tidyverse)

Precisaremos de dados e vamos coletar esses dados utilizando a API do Twitter, usando a função de busca ‘search_tweets()’, onde poderemos passar a # que queremos buscar ou termo, o número de tweets, onde o número máximo é 18 mil e se queremos ou não os retweets e a linguagem dos tweets, que no nosso caso será em inglês.

# Buscando os tweets com #pets ou #pet
pets_tweets <- search_tweets(
  "#pets OR #pet",
  n = 18000,
  include_rts = FALSE,
  lang = "en"
)

Visualizando a frequência de tweets utilizando #pets ou #pet, no intervalo de 1 hora:

# Gerando um gráfico com a frequência dos tweets no intervalo de 1 hora
pets_tweets %>% 
  ts_plot("1 hours") +
  ggplot2::theme_minimal() +
  ggplot2::theme(plot.title = ggplot2::element_text(face = "bold")) +
  ggplot2::labs(
    x = NULL,
    y = NULL,
    title = "Frequência de Pets no Twitter",
    subtitle = "Tweets no intervalo de 1 hora",
    caption = "\nSource: Dados coletados no Twitter REST API via rteet"
  )

Gráfico de frequência

Vamos começar a mineração dos textos e para isso iremos pegar a (coluna) text e atribuir a uma variável.

# Atribuindo os textos a uma variável
pet_text <- pets_tweets %>% pull(text)

Tranformando os nossos textos em um corpus, para assim podermos realizar a limpeza utilizando a função tm_map, onde removeremos os caracteres especiais, transformaremos todas as letras para minúsculas, removeremos as pontuações e as stopwords em inglês.

# Transformando os textos em um corpus
pet_corpus <- VCorpus(VectorSource(pet_text))

# Realizando a limpeza dos dados e removendo os termos 'pet' e 'pets', 
# pois é óbvio que essas palavras estão na nossa busca e serão as mais frequentes
pet_corpus <- 
  tm_map(
    pet_corpus,
    content_transformer(
      function(x) iconv(x, from = 'UTF-8', to = 'ASCII//TRANSLIT')
    )
  ) %>% 
  tm_map(content_transformer(tolower)) %>% 
  tm_map(removePunctuation) %>% 
  tm_map(removeWords, stopwords("english")) %>% 
  tm_map(removeWords, c("pet", "pets"))

Após, realizar a limpeza dos nossos textos, chegou o momento de visualizar o resultado em uma nuvem de palavras e iremos utilizar a função brewer.pal, para gerar as cores em hexadecimal, para assim, colorirmos a nossa nuvem.

# Lista de cores em hexadecimal
paleta <- brewer.pal(8, "Dark2")

# Criando uma nuvem de palavras, com no máximo 100 palavras
# onde tenha se repetido ao menos 2 vezes
wordcloud(
  pet_corpus,
  min.freq = 2,
  max.words = 100,
  color = paleta
)

Nuvem de palavras

Criando uma matriz de documentos-termos (DocumentTermMatrix), onde posteriormente, removeremos os termos menos frequentes da matriz e somaremos os termos restantes para assim verificar quais são os termos mais utilizados.

# Criando uma matriz de termos
pets_document <- DocumentTermMatrix(pet_corpus)

# Removendo os termos menos frequentes
pets_doc <- removeSparseTerms(pets_document, 0.98)

# Gerando uma matrix ordenada, com o termos mais frequentes
pets_freq <- 
  pets_doc %>% 
  as.matrix() %>% 
  colSums() %>% 
  sort(decreasing = T)

Gerando um dataframe com os termos mais utilizados e visualizando em um gráfico.

# Criando um dataframe com as palavras mais frequentes
df_pets <- data.frame(
  word = names(pets_freq),
  freq = pets_freq
)

# Gerando um gráfico da frequência
df_pets %>%
  subset(freq > 450) %>% 
  ggplot(aes(x = reorder(word, freq),
             y = freq)) +
  geom_bar(stat = "identity", fill='#0c6cad', color="#075284") +
  theme(axis.text.x = element_text(angle = 45, hjus = 1)) +
  ggtitle("Termos relacionados a Pet ou Pets mais frequentes no Twitter") +
  labs(y = "Frequência", x = "Termos") +
  coord_flip()

Termos mais frequentes

E podemos visualizar o resultado em uma nuvem de palavras, porém utilizaremos outro pacote para gerar a nuvem que é o wordcloud2, pois ele gera uma nuvem de palavras mais bonita que o pacote que utilizamos até o momento, mas antes, temos que instalar o pacote em nosso computador e utilizamos o comando abaixo para realizar a instalação.

# Instalando o pacote 'devtools', caso não o tenha instalado em seu computador
if (!require(devtools)) install.packages("devtools")

# Carregando o pacote 'devtools'
library(devtools)

# Instalando o pacote 'wordcloud2' via github
devtools::install_github("lchiffon/wordcloud2", force = TRUE)

E após, instalarmos, carregaremos o pacote wordcloud2 e passaremos o nosso dataframe com os termos mais frequentes para a função wordcloud2 e teremos como resultado o seguinte gráfico.

# Carregando o pacote 'wordcloud2'
library(wordcloud2)

wordcloud2(data = df_pets)

Nuvem de palavras

E podemos visualizar como os nossos termos estão relacionados, e para isso produziremos um dendrograma de agrupamento hierárquico, que é um diagrama de árvore.

# Removendo os termos menos frequentes
pets_doc1 <- removeSparseTerms(pets_document, 0.95)

# Dendograma
distancia <- dist(t(pets_doc1), method = "euclidian")
dendograma <- hclust(d = distancia, method = "complete")
plot(dendograma, habg = -1, main = "Dendograma Tweets Pets ou Pet",
     xlab = "Distância",
     ylab = "Altura")

Dendograma

E outra possibilidade que temos ao realizar mineração de textos é classificar os sentimentos dos termos utilizados, no nosso caso não fará muito sentido, pois é óbvio que o sentimento das pessoas em relação aos pets é um sentimento positivo, mas somente para exemplificar a posibilidade, vamos realizar essa análise e para isso utilizaremos o pacote syuzhet.

# Instalando o pacote, caso não o tenha em seu PC.
install.packages("syuzhet")

# Carregando o pacote
library(syuzhet)

Agora, que instalamos e carregamos o pacote, realizaremos a análise dos sentimentos dos nossos tweets e para tal análise utilizaremos a função get_nrc_sentiment, onde passaremos como parâmetro, os termos da nossa matriz de documentos-termos. E após, obtermos as emoções dos nossos termos, faremos o calculo da frequência dos sentimentos que utilizaram a #pet ou #pets.

# Obtendo as emoções dos nossos termos
pets_sentimentos <- get_nrc_sentiment(
  pets_doc$dimnames$Terms,
  language = "english"
)

# Calculando a frequência dos sentimentos
pets_sentimentos_freq <- pets_sentimentos %>%
  colSums() %>% 
  sort(decreasing = T)

Com a frequência dos nossos sentimentos calculada, poderemos visualizar o resultado, mas antes, iremos traduzir os sentimentos do inglês para o português e tranformar o resultado em um dataframe para posterirmente gerarmos o gráfico.

# Criando um dataframe com os sentimentos traduzidos, que será utilizado como de-para. 
sentimetos_traducao <- 
  data.frame(
    sentiment = c(
      "positive",
      "negative",
      "trust",
      "anticipation",
      "fear",
      "joy",
      "sadness",
      "surprise",
      "anger",
      "disgust"
    ),
    sentimentos = c(
      "Positivo",
      "Negativo",
      "Confiança",
      "Antecipação",
      "Medo",
      "Alegria",
      "Tristeza",
      "Surpresa",
      "Raiva",
      "Nojo"
    )
  )


# Tranformando os resultados da frequência em um dataframe 
# e juntando ao dataframe de tradução
df_sentimento <- 
  data.frame(
    sentiment = names(pets_sentimentos_freq),
    freq = pets_sentimentos_freq
  ) %>% 
  left_join(sentimetos_traducao, by = "sentiment") %>% 
  dplyr::select(-sentiment) %>% 
  arrange(desc(freq))


# Visualizando a frequência dos sentimentos em relação a #pets
ggplot(data = df_sentimento,
       aes(x = reorder(sentimentos, -freq), y = freq)) +
  geom_bar(aes(fill=sentimentos), stat = "identity") +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, hjus = 1)) +
  xlab("Sentimentos") +
  ylab("Frequência") +
  ggtitle("Sentimentos das pessoas em relação aos Pets")

Gráfico de sentimentos

Então é isso, espero que tenha gostado desse post e até a próxima! Bye!