Mineração de Texto no R

Uma Aplicação com Tweets sobre a COVID-19

Prof. Letícia Raposo

UNIRIO

Imagem criada pelo DALL·E 2

💪 Motivação

Sempre quis trabalhar com dados não estruturados. Por que não tentar trabalhar com textos? E que tal os tweets?

🐦 O Twitter como fonte de dados

Existem várias razões pelas quais os tweets podem ser utilizados como dados para estudos:

  • Grande volume de dados;
  • Acesso a opiniões e sentimentos;
  • Diversidade de tópicos;
  • Acesso a dados públicos;
  • Tempo real e dados geolocalizados;
  • Interação social e redes.

💡 Ideia

Por que não trabalhar com os tweets criados na época da pandemia da COVID-19? O que de interessante eles podem nos mostrar?

Etapas

  1. Coleta dos dados
  2. Pré-processamento dos dados
  3. Visualização dos dados
  4. Análise de sentimentos

📊 Coleta de dados

  • O Academic Research Access do Twitter é um programa oferecido pela plataforma para conceder acesso especial a pesquisadores acadêmicos a determinados recursos e dados do Twitter.
  • Para obter acesso ao programa, os pesquisadores precisam se inscrever e passar por um processo de revisão e aprovação para garantir a utilização ética e adequada dos dados do Twitter em seus estudos acadêmicos.

📊 Coleta de dados

Como coletar no R
# Baixando os tweets pelo R
library(academictwitteR)
tweets <-
  get_all_tweets(

    # contendo uma ou outra palavra
    query = c("covid19", "covid-19", "covid",
              "sars-cov-2", "sarscov2",
              "corona", "covid", "ncov", "ncov-19",
              "pandemia", "quarentena"),
    
    # Periodo de buscas
    start_tweets = "2020-03-11T00:00:00Z",
    end_tweets = "2022-11-04T00:00:00Z",
    
    # Local onde salvara a busca
    data_path = "DadosCovid",
    
    # nao gera um data frame
    bind_tweets = FALSE,
    
    # numero de tweets
    n = 1000000000000000,
    
    # pais
    country = "BR",
    
    # lingua
    lang = "pt",
    
    # pegando quem tem localizacao geografica
    has_geo = T,
    
    # excluindo retweets
    is_retweet = F
    
  )

🔄 Pré-processamento dos dados

O pré-processamento dos tweets é uma etapa essencial na análise de dados de tweets e desempenha um papel importante por várias razões:

  • Limpeza dos dados: os tweets podem conter ruídos e elementos indesejados, como URLs, caracteres especiais, emojis, menções a usuários e hashtags.
Limpeza no R
# Limpeza dos tweets
remover_acentos <- function(texto) {
  texto_sem_acentos <- gsub("[àáâãäå]", "a", texto)
  texto_sem_acentos <- gsub("[èéêë]", "e", texto_sem_acentos)
  texto_sem_acentos <- gsub("[ìíîï]", "i", texto_sem_acentos)
  texto_sem_acentos <- gsub("[òóôõö]", "o", texto_sem_acentos)
  texto_sem_acentos <- gsub("[ùúûü]", "u", texto_sem_acentos)
  texto_sem_acentos <- gsub("[ç]", "c", texto_sem_acentos)
  return(texto_sem_acentos)
}

# Funcao para limpar tweets
clean_tweets <- function(tweets) {
  # Remover URLs
  tweets <- gsub("http\\S+", "", tweets)
  
  # Remover hashtags
  tweets <- gsub("#\\S+", "", tweets)
  
  # Remover menções de usuário
  tweets <- gsub("@\\S+", "", tweets)
  
  # Remover emojis
  tweets <- gsub("[^[:alnum:][:space:]]", "", tweets)
  
  # Substituir & por e
  tweets <- gsub("&", "e", tweets)
  
  # Remover pontuação
  tweets <- gsub("[[:punct:]]", "", tweets)
  
  # Remover "RT:" do início dos retweets
  tweets <- gsub("^RT:", "", tweets)
  
  # Substituir novas linhas em caracteres
  tweets <- gsub("\n", " ", tweets)
  
  # Converter o texto para minúsculas
  tweets <- tolower(tweets)
  
  # Remover espaços em branco extras
  tweets <- gsub("\\s+", " ", tweets)
  
  # Remover acentos e cedilhas
  tweets <- remover_acentos(tweets)
  
  return(tweets)
}

cleaned_tweets <- clean_tweets(tweets$text)

# Coloca os dados em uma nova coluna
tweets["fix_text"] <- cleaned_tweets

# Removendo tweets duplicados
tweets["DuplicateFlag"] <- duplicated(tweets$fix_text)
tweets <- subset(tweets,
                 tweets$DuplicateFlag == "FALSE")
tweets <- subset(tweets,
                 select = -c(DuplicateFlag))

🔄 Pré-processamento dos dados

  • Padronização do texto: conversão de todas as letras para minúsculas, redução das palavras a sua forma base ou raiz.
    • Stemização: processo de remoção de afixos (sufixos e prefixos) de uma palavra, preservando apenas a raiz ou o “stem” da palavra. Por exemplo, o stemizador pode transformar as palavras “correr”, “correndo” e “corrida” em seu stem comum “corr”.
    • Lematização: envolve a redução de palavras a sua forma canônica ou base, conhecida como “lema”. A lematização considera o contexto e a morfologia da palavra para produzir o lema correto. Isso significa que as palavras são reduzidas a uma forma que faz sentido gramaticalmente. Por exemplo, a lematização transformaria as palavras “correr”, “correndo” e “corrida” em seu lema comum “correr”.

🔄 O pré-processamento dos dados

  • Tokenização: envolve a divisão do texto dos tweets em unidades significativas, geralmente palavras individuais. Isso permite uma análise mais granular, como contagem de palavras, identificação de padrões e análise de sentimentos.
  • Remoção de stopwords: as stopwords são palavras comuns, como artigos, preposições e pronomes, que geralmente não contribuem significativamente para a análise.

👀 Visualização dos dados

  • Etapa de criação de gráficos e nuvens de palavras com base nos tweets coletados.
  • Pode ajudar a identificar tendências, padrões e insights interessantes.

😃😔 Análise de sentimentos

  • A análise de sentimentos é uma técnica que permite determinar a polaridade emocional de um tweet, ou seja, se o tweet expressa um sentimento positivo, negativo ou neutro.
  • Muito útil para compreender a opinião e o sentimento das pessoas em relação a determinados tópicos, produtos, eventos ou situações.

🔍 Alguns achados

Entre 11 de março de 2020 a 04 de novembro de 2022, foram coletados 1.985.792 tweets. A visualização dos tweets foi realizada considerando a data de postagem e a variante da COVID-19 predominante no Brasil na respectiva ocasião.

🤔 E se observássemos termos referentes a sintomas mencionados neste período?

Para isso, usamos termos relacionados a diferentes grupos de sintomas, como respiratório, imunológico, neurológico, gastrointestinal, muscular, cardiovascular, renal, mental… Ao filtrarmos os tweets para aqueles que continham pelo menos um dos termos informados, ficamos com 70.723 tweets.

Filtrando os sintomas no R
# Gerando os sintomas
respiratorio <- c("respir",
                  "falta de ar",
                  "sufoca",
                  "ofegante",
                  "dor no peito",
                  "aperto no peito",
                  "tosse",
                  "catarr",
                  "nariz",
                  "congestao nasal",
                  "nasal",
                  "secrec",
                  "coriza",
                  "espirr",
                  "alergia",
                  "resfri",
                  "rinit",
                  "gargant")

imunologico <- c("febr",
                 "calafrio",
                 "suor",
                 "inflama",
                 "tremor",
                 "arrepio",
                 "calafrio",
                 "arritmia",
                 "transpir",
                 "suor",
                 "sudorese",
                 "desidrat")

neurologico <- c("paladar",
                 "olfato",
                 "anosmia",
                 "dor de cabeca",
                 "cefaleia",
                 "enxaqueca",
                 "insonia",
                 "tontura", 
                 "zumbido no ouvido")

gastrointestinal <- c("enjoo",
                      "vomit",
                      "mal-estar",
                      "mal estar",
                      "nausea",
                      "dor abdominal",
                      "dores abdominais",
                      "diarreia",
                      "gastrointestin",
                      "flatulencia",
                      "gases",
                      "perda de apetite",
                      "disfagia")
muscular <- c("fadiga",
              "cansad",
              "fatigad",
              "cansaco",
              "exaustao",
              "falta de energia",
              "fraqueza",
              "sonolen",
              "dor no corpo",
              "dor muscular",
              "dores no corpo", 
              "dores musculares",
              "dor na articulacao",
              "dores na articulacao",
              "dores nas articulacoes")

pele <- c("cutanea",
          "lesao na pele",
          "lesoes na pele",
          "rash",
          "coceira")

cardiovascular <- c("coagulo",
                    "arritmia")

olhos <- c("conjuntivite",
           "dor no olho",
           "dor nos olhos",
           "ocular")

renal <- c("renal")

mental <- c(
  "ansiedade",
  "ansios",
  "estress",
  "palpitac",
  "panico",
  "nervos",
  "inquiet",
  "irrita",
  "confusao",
  "desorienta",
  "vertigem",
  "desmai",
  "tontura"
)

sinais_sintomas <- c(
cardiovascular,
gastrointestinal,
imunologico,
mental,
muscular,
neurologico,
olhos,
pele,
renal,
respiratorio
)

# Fazendo a primeira filtragem pelos sintomas
sintomas_tweets <- subset(tweets,
                          grepl(paste(sinais_sintomas,
                                      collapse = "|"),
                                fix_text,
                                ignore.case = T))

A partir do processo de tokenização, remoção de stopwords, stematização e lematização, observamos os seguintes sintomas mais citados:

Observando os 15 sintomas mais citados ao longo do tempo:

😃😔 Análise de Sentimentos

VADER (Valence Aware Dictionary and sEntiment Reasoner)

  • Algoritmo de análise de sentimentos projetado para lidar com textos de mídia social, como tweets, posts em fóruns e avaliações de produtos.
  • Baseado em um dicionário léxico especializado que atribui pontuações a palavras individuais em relação a sua polaridade (positiva ou negativa) e intensidade.
    • Dicionário expandido para incluir palavras e expressões específicas encontradas em mídias sociais, como emojis, abreviações e gírias.

VADER

  • Dicionário Léxico: O VADER utiliza um dicionário léxico especializado que atribui pontuações de sentimentos a palavras individuais. Cada palavra é avaliada em relação à sua polaridade (positiva ou negativa) e intensidade. O dicionário é pré-construído e contém milhares de palavras com suas respectivas pontuações de sentimento.

  • Soma de Pontuações: Ao analisar um texto, o VADER realiza a soma das pontuações de sentimentos das palavras presentes. Cada palavra é ponderada pela sua intensidade e pelo contexto em que aparece. O algoritmo leva em consideração o uso de letras maiúsculas, a presença de intensificadores ou atenuadores, bem como pontuações de ênfase, como repetições de letras (ex: “looooove”).

VADER

  • Regras de Ponto de Corte: O VADER aplica regras de ponto de corte para determinar a polaridade geral do texto. Se a pontuação final for maior que zero, o texto é considerado positivo; se for menor que zero, é considerado negativo; e se for igual a zero, é considerado neutro.

  • Compensação de Valência: aplica uma técnica de compensação de valência para lidar com casos em que palavras positivas e negativas coexistem no mesmo texto.

VADER

  • Como o algoritmo foi construído para termos em inglês, uma abordagem é realizar a tradução dos tweets e, posteriormente, aplicar o algoritmo.
  • Para esta apresentação, sorteei 7000 tweets (cerca de 10% da base original de sintomas) para avaliarmos os sentimentos.

Exemplos de tweets com compound > 0.95:

  • “Ok 👍 no confinamento… dia 12 da quarentena. Mas na esperança 🙏 que tudo se resolva o mais rápido possível e a vida volte ao normal. Sem pânico e disciplina! DEUS nos abençoe e que… https://t.co/CFQlCcc44Z”
  • “E estamos todos com covid aqui em casa amigos, o primeiro teste deu negativo mas hj positivamos. Com sintomas leves, a maior preocupação é a vó que tá com uma tosse encatarrada. O pai que positivou primeiro já tá melhorando 🙌 orem, rezem, mandem muita energia positiva 🙏🙏🙏”

Exemplos de tweets com compound > 0.95:

  • “Não queria sair falando por aí, mas sinto que uma corrente de energia e pensamentos positivos seria boa. Minha mãe tem largo histórico de problemas respiratórios e tá com covid. está internada, sendo tratada. Peço aos amigos q mandem energias positivas, rezas e força. 🙏🏻❤️”
  • “Foi uma semana difícil, muitas dores, fraqueza, achei que não conseguiria em vários momentos.. Mas ele estava cmg em todos e acreditou em mim, na minha força como mãe e mulher… Eu venci o Covid ❤ Por ele, com ele, por nos! Obrigada por nos cuidar tão bem 👪 @joven_tralha157
  • “Bom dia !!!!! Fiz agora de manhã o teste Swab nasal do Covid-19 ! Mas estou ótima graças á Deus ! O teste é para um trabalho muito legal 😍 . Já já conto para vcs ! 🚀”

Exemplos de tweets com compound igual a zero:

  • @joicefran20 Kkkkkkkkkkk quarentena já tá me sufocando”

  • “Depois da Covid meu paladar e meu olfato nunca mais foram os mesmos… Às vezes ainda sinto cheiro e gosto metálicos… 😞”

  • “Fui fazer teste de covid e meu nariz começou a sangrar depois que a moça meteu nele o cotonete 👌🏻”

  • “Foi o reforço do covid, febre amarela, bezetacil, mds”

Exemplos de tweets com compound < -0.95:

  • “A verdade é que a quarentena tem que acabar. Mas eu acho bizarro um país que não respeitou a quarentena querer que tudo volte ao normal. É suicídio. E quem se # são as pessoas que em momentos assim, desenvolvem problemas psicológicos. Depressão e ansiedade n são brincadeira…”

  • “#! Consegui um assento no BRT, mas o cara que tá do meu lado tosse com certa frequência. #! #! Eu não tô podendo com o Covid-19. Tô rezando pra afastar o mal.”

Exemplos de tweets com compound < -0.95:

  • @marcelamcgowan fui na força do ódio. Lutei para o adiamento. Quando vi o tema eu surtei, achei que não iria conseguir escrever de tanto ódio. Pandemia, governo cagando, mortes por covid, caos na saúde, ansiedade, adoecimento em massa, imposição do enem meio ao caos. 0 saúde mental!”

  • “De todos esses dias difíceis de quarentena, hoje é o dia que eu tô me sentindo pior. Uma mistura de desespero, com querer explodir, com tacar o #, com vontade de correr pro colo do meu pai e chorar até dormir. Tô cansada, irritada, triste, desacreditada e não quero mais!”

  • “É # ter ansiedade e asma, quando vc ta mal e começa a chorar junta os dois ai vc fica com a dúvida é só mais uma crise ou Corona?”

Dificuldades e Questionamentos

  1. Como realizar a filtragem dos tweets que efetivamente contenham relatos de sintomas, tanto de indivíduos que se sentem dessa maneira quanto de pessoas conhecidas que tenham mencionado esses sintomas?
  • 👌 @angelanogueira2 Ainda mto mole e febril , mas pelo diário da COVID parece que e assim mesmo , 8° dia hoje . Agora só melhorar . Obrigada minha querida , esse carinho me cura 🙌🏻”

  • 🚫 “Foi o reforço do covid, febre amarela, bezetacil, mds”

Dificuldades e Questionamentos

  1. Como ter uma análise de sentimentos mais precisa?
  • ❓ Transformar emojis em sentimentos?
  • ❓ Criar um modelo de aprendizado de máquina?

📚 Referências

  • Hutto, C. J., & Gilbert, E. (2014). VADER: A parsimonious rule-based model for sentiment analysis of social media text. In Proceedings of the 8th International Conference on Weblogs and Social Media (ICWSM 2014) (pp. 216-225).
  • Qi, Y., Shabrina, Z. (2023). Sentiment analysis using Twitter data: a comparative application of lexicon- and machine-learning-based approach. Social Network Analysis and Mining, 13(31). Disponível em: https://doi.org/10.1007/s13278-023-01030-x
  • Wang, Y.; Guo, J.; Yuan, C.; Li, B. (2022) Sentiment Analysis of Twitter Data. Appl. Sci. 12, 11775. Disponível em: https://doi.org/10.3390/app122211775.