Olist
Código em linguagem R para a Análise de Sentimentos
Código em linguagem R para a Análise de Sentimentos
Configuração de diretório de arquivos e carregar bibliotecas
### Preparando o ambiente de trabalho ------------------------------------------
# Diretório de Trabalho
setwd("/home/formiga/Desktop/Projetos/Olist")
getwd()
# Pacotes
library(data.table)
library(tm) # Processamento de lingagem natural
library(topicmodels) # Modelagem de tópicos
library(textdata) # Tratamento de dados em forma de texto
library(rvest) # Web Scraping
library(tidyverse) # Pacote para manipulação de dados
library(tidytext) # Pacote para manipulação de dados
library(dplyr) # Pacote para manipulação de dados
library(tidyr) # Pacote para manipulação de dados
library(reshape2) # Mudar shape dos dados
library(forcats) # Mudar shape dos dados
library(scales) # Mudar escalo de gráficos
library(stringr) # Manipular strings
library(ggplot2) # Construção de gráficos
library(wordcloud) # Construção de gráficos
library(igraph) # Construção de gráficos
library(ggraph) # Construção de gráficos
Preparação do dataset para facilitar o código posteriormente
# Carregamento do dataset e ocultar colunas não necessárias
reviews <- fread('olist_order_reviews_dataset.csv')
reviews
df_reviews <- data.frame(line = 1, text = reviews, stringsAsFactors = FALSE)
class(df_reviews)
View(df_reviews)
df_reviews<-df_reviews[,-c(1,2,3,7,8)]
df_score<-df_reviews[,c(1)]
df_title<-df_reviews[,c(2)]
df_message<-df_reviews[,c(3)]
# Separação em sub datasets
df_score <- data.frame(line = 1, score = df_score, stringsAsFactors = FALSE)
class(df_score)
View(df_score)
df_title <- data.frame(line = 1, title = df_title, stringsAsFactors = FALSE)
class(df_title)
View(df_title)
df_message <- data.frame(line = 1, message = df_message, stringsAsFactors = FALSE)
class(df_message)
View(df_message)
Tokenização
### Processamento de Linguagem Natural ###
# Tokenização
tokens_title <- df_title %>%
unnest_tokens(word, title) %>%
anti_join(get_stopwords(language = "pt")) %>%
count(word, sort = TRUE)
View(tokens_title)
?stop_words
tokens_message <- df_message %>%
unnest_tokens(word, message) %>%
anti_join(get_stopwords(language = "pt")) %>%
count(word, sort = TRUE)
View(tokens_message)
title_clean <- df_title %>%
unnest_tokens(word, title) %>%
anti_join(get_stopwords(language = "pt"))
message_clean <- df_message %>%
unnest_tokens(word, message) %>%
anti_join(get_stopwords(language = "pt"))
# Combinando os Dataframes e Calculando a frequência
frequencia <- bind_rows(mutate(title_clean, text_box = "title"),
mutate(message_clean, text_box = "message")) %>%
mutate(word = str_extract(word, "[a-z']+")) %>%
count(text_box, word) %>%
group_by(text_box) %>%
mutate(proportion = n/sum(n))%>%
select(-n) %>%
spread(text_box, proportion) %>%
gather(text_box, proportion, `message`)
print(frequencia)
# A tibble: 14,224 × 4
word title text_box proportion
<chr> <dbl> <chr> <dbl>
1 a NA message 0.000291
2 aa NA message 0.00000669
3 aaa 5.60e-5 message 0.0000134
4 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa… NA message 0.00000334
5 aaguardando NA message 0.00000334
6 aainda NA message 0.00000669
7 aancheira NA message 0.00000334
8 aaprelho NA message 0.00000334
9 ab NA message 0.00000669
10 aba NA message 0.00000669
# ℹ 14,214 more rows
# ℹ Use `print(n = ...)` to see more rows
# Correlação entre as colunas título e mensagem
cor.test(data = frequencia[frequencia$text_box == "message",], ~proportion + `title`)
Pearson's product-moment correlation
data: proportion and title
t = 31.703, df = 1430, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.6109831 0.6718922
sample estimates:
cor
0.6424512
### Análise de Sentimentos ###
# Léxicos de sentimentos
afinn <- get_sentiments("afinn")
nrc <- get_sentiments("nrc")
bing <- get_sentiments("bing")
# Método AFINN
title_clean %>%
inner_join(get_sentiments("afinn")) %>%
summarise(sentiment = sum(value)) %>%
mutate(method = "AFINN")
# Método Bing
title_clean %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = T)
# Método NRC
sentimentos_title <- title_clean %>%
inner_join(get_sentiments("nrc"), multiple = "all") %>%
count(word, sentiment, sort = T) %>%
ungroup()
📊
# Plot de todos os sentimentos
sentimentos_title %>%
group_by(sentiment) %>%
top_n(5) %>%
ungroup() %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n, fill = sentiment)) +
geom_col(show.legend = FALSE) +
facet_wrap(~sentiment, scales = "free_y") +
ggtitle("Sentimentos dos Títulos") +
theme(plot.title = element_text(color = "grey", face = "bold", hjust = 0, vjust = 0)) +
labs(y = "", x = NULL) +
coord_flip() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "grey"))
# Método AFINN
message_clean %>%
inner_join(get_sentiments("afinn")) %>%
summarise(sentiment = sum(value)) %>%
mutate(method = "AFINN")
# Método Bing
message_clean %>%
inner_join(get_sentiments("bing")) %>%
count(word, sentiment, sort = T)
# Método NRC
sentimentos_message <- message_clean %>%
inner_join(get_sentiments("nrc"), multiple = "all") %>%
count(word, sentiment, sort = T) %>%
ungroup()
📊
# Plot de todos os sentimentos
sentimentos_message %>%
group_by(sentiment) %>%
top_n(10) %>%
ungroup() %>%
mutate(word = reorder(word, n)) %>%
ggplot(aes(word, n, fill = sentiment)) +
geom_col(show.legend = FALSE) +
facet_wrap(~sentiment, scales = "free_y") +
ggtitle("Sentimentos das Mensagens") +
theme(plot.title = element_text(color = "grey", face = "bold", hjust = 0, vjust = 0)) +
labs(y = "", x = NULL) +
coord_flip() + theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "grey"))
# Encontrando as Palavras Mais Comuns nos Textos Usando TF-IDF (term frequency-inverse document frequency)
# Combinando os textos
df_combinado <- bind_rows(mutate(df_title, text_box = "title"),
mutate(df_message, text_box = "message"))
df_combinado$title <- ifelse(is.na(df_combinado$title), df_combinado$message, df_combinado$title)
# Deletando última coluna
df_combinado<-df_combinado[,-c(4)]
#Renomeando as colunas
colnames(df_combinado)[2] ="text"
colnames(df_combinado)[3] ="category"
# Remoção de stop words e tokenização
df_combinado_limpo <- df_combinado %>%
unnest_tokens(word, text) %>%
anti_join(get_stopwords(language = "pt")) %>%
count(category, word, sort = TRUE) %>%
ungroup()
# Total de palavras
total_palavras <- df_combinado_limpo %>%
group_by(category) %>%
summarize(total = sum(n))
# Left join
df_combinado_limpo <- left_join(df_combinado_limpo, total_palavras)
# TF-IDF
?bind_tf_idf
df_tf_idf <- df_combinado_limpo %>%
bind_tf_idf(word, category, n)
📊
# Plot das palavras mais frequentes usando TF-IDF (term frequency-inverse document frequency)
df_tf_idf %>%
arrange(desc(tf_idf)) %>%
mutate(word = factor(word, levels = rev(unique(word)))) %>%
group_by(category) %>%
top_n(5) %>%
ungroup() %>%
ggplot(aes(tf_idf, fct_reorder(word, tf_idf), fill = category)) +
geom_col(show.legend = FALSE) +
facet_wrap(~category, ncol = 2, scales = "free") +
labs(x = NULL, y = "") +
scale_x_continuous(label = scales::percent) +
ggtitle("Palavras Mais Frequentes") +
theme(plot.title = element_text(color = "grey", face = "bold", hjust = 0, vjust = 0)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "grey"))
# Criando a Document Term Matrix para todas as caixas de mensagens
doc_term_matrix <- df_combinado %>%
unnest_tokens(word, text) %>%
count(category, word) %>%
cast_dtm(category, word, n)
print(doc_term_matrix)
dtm_artigos <- df_combinado_limpo %>%
cast_dtm(category, word, n)
# Utilizei 2 clusters dado que temos bem definido os clusters de título e mensagem
?LDA
modelo_lda <- LDA(dtm_artigos, k = 2, control = list(seed = 123))
modelo_lda
# Dataframe de tópicos (beta é um indice criado pelo algoritmo pra identificar em qual cluster a palavra é mais adequada)
df_topics <- tidy(modelo_lda, matrix = "beta")
📊
# Top termos
top_termos <- df_topics %>%
group_by(topic) %>%
top_n(5, beta) %>%
ungroup() %>%
arrange(topic, -beta)
# Tópicos - Top Termos
top_termos %>%
mutate(term = reorder(term, beta)) %>%
ggplot(aes(term, beta, fill = factor(topic))) +
geom_col(show.legend = FALSE) +
facet_wrap(~ topic, scales = "free") +
coord_flip() +
labs(x = NULL, y = "") +
ggtitle("Beta") +
theme(plot.title = element_text(color = "grey", face = "bold", hjust = 0, vjust = 0)) +
theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank(),
panel.background = element_blank(), axis.line = element_line(colour = "grey"))
# Conclusão: O top_termos demonstra reação positiva dos consumidores com relação aos reviews
# analisados, comprovando a nota de avaliação acima de 4 (de 5 estrelas). O objetivo principal
# dos comentários parece estar em prover informação, em sua maioria, positiva.