Resumo

A consulta pública sobre o Novo Ensino Médio está terminando. Aproveitando a ocasião, coletei todos os tweets de março sobre o assunto. Foi em março que o MEC anunciou a suspensão do cronograma e a abertura de consulta pública, então o assunto foi bastante comentado nas redes sociais.

Identifiquei o sentimento principal de cada tweet usando inteligência artificial (que tem limitações mas funciona para uma comparação geral). Foram 94% de tweets negativos. E quase todos os 6% positivos se referem à abertura da consulta pública do MEC ou aos atos contra o Novo Ensino Médio.

Fiz também uma nuvem de palavras, que mostra amplo apoio à revogação da reforma.

Para quem quiser ver os tweets, eu selecionei alguns e também deixei no final uma tabela com todos que viralizaram.

Análise de sentimento

clique para ver o código

library(tidyverse)
library(tm)
library(RWeka)
library(wordcloud)

# os dados foram obtidos via python, utilizando o pacote snscrape
# a análise de sentimento também foi feita via python, com o pacote transformers
df=read_csv('twits_NEM_2023-03_sentim.csv')

df=df[,-c(1,2)]
df$date=format(df$date, "%d")


# calcular impacto dos positivos e negativos
ss=df %>% 
  filter(sentim!='Neutral') %>% 
  group_by(sentim) %>% 
  summarise(n=length(likes),
            impacto=sum(likes)) # impacto = soma de likes

ss$sentim=c("Negativo", "Positivo")
ss$impacto_prop=round(100*prop.table(ss$impacto))
ss$impacto_prop=paste0(ss$impacto_prop,'%')

# plot
ss %>% 
  ggplot(aes(x=1, y=impacto, label=impacto_prop, fill=sentim))+
  geom_col()+
  labs(y=NULL, x=NULL, fill="Sentimento:", title="Impacto do Novo Ensino Médio no Twitter", caption = paste('Tweets de Março de 2023 com mais de 10 curtidas'))+
  scale_fill_manual(values=c('red','green'))+
  geom_text(position = position_stack(vjust = 0.5), size=4)+
  coord_polar(theta="y")+
  theme_bw()+
  theme(axis.text = element_blank(),
        axis.ticks = element_blank(),
        panel.grid = element_blank(),
        panel.border = element_blank(),
        legend.text = element_text(size=12),
        legend.position = 'top',
        plot.title = element_text(hjust = 0.5),
        plot.caption = element_text(hjust = 0.5))

Nuvem de palavras

Para ficar mais interessante, eu juntei as palavras em duplas. O “Novo Ensino Médio” está como uma palavra só: “NovoEM”.

Na nuvem abaixo estão as duplas de palavras mais citadas nos tweets de março.

tweets <- df %>% 
  # filter(sentim=='Negative') %>% 
  pull(content)

tweets <- gsub('novo ensino médio', 'NovoEM', tweets, ignore.case = TRUE)
tweets <- gsub('novo ensino medio', 'NovoEM', tweets, ignore.case = TRUE)

mycorpus <- Corpus(VectorSource(tweets))

# Text Cleaning
# Convert the text to lower case
mycorpus <- tm_map(mycorpus, content_transformer(tolower))
# Remove numbers
mycorpus <- tm_map(mycorpus, removeNumbers)
# Remove english common stopwords
mycorpus <- tm_map(mycorpus, removeWords, stopwords("portuguese"))
# Remove punctuations
mycorpus <- tm_map(mycorpus, removePunctuation)
# Eliminate extra white spaces
mycorpus <- tm_map(mycorpus, stripWhitespace)


token_delim <- " \\t\\r\\n.!?,;\"()"
bitoken <- NGramTokenizer(mycorpus, Weka_control(min=2, max=3, delimiters = token_delim))
two_word <- data.frame(table(bitoken))
two_word <- two_word[order(two_word$Freq,decreasing=TRUE),]

two_word$bitoken <- gsub('novoem', 'NovoEM', two_word$bitoken)

pal=brewer.pal(9,"Blues")
pal=pal[-(1:5)]

wordcloud(two_word$bitoken,
          two_word$Freq,
          random.order=FALSE,
          scale = c(2,.8),
          min.freq = 34,
          colors = pal,
          max.words=30)

Top Tweets

Veja abaixo alguns dos tweets com mais likes.


Todos os tweets que viralizaram

Na tabela abaixo estão todos os tweets de março/2023 com mais de 100 likes que mencionam o Novo Ensino Médio.

Você pode interagir com a tabela, por exemplo filtrando palavras de uma coluna.

df %>% 
  filter(likes>100) %>% 
  select(Autor=username, Tweet=content, Likes=likes, Sentimento=sentim, URL=url) %>%
  mutate(URL=paste0('<a href="', URL ,'" target="_blank"> Link </a>')) %>% 
  DT::datatable(., rownames = FALSE, 
                fillContainer = TRUE,
                # style = 'bootstrap4',
                escape = FALSE,
                filter = 'top',
                options = list(
                  language = list(url = 'http://cdn.datatables.net/plug-ins/1.10.11/i18n/Portuguese.json'),
                  dom = 'tp',
                  scrollX=FALSE,
                  scrollY=FALSE))