O projeto visa realizar uma Análise Exploratória de Dados avançada, focada em dados não estruturados (texto), com o objetivo de contar uma narrativa coerente sobre a satisfação do consumidor.
Pergunta Central da Análise:
A partir do conteúdo textual das avaliações, quais são os principais
aspectos que influenciam a experiência do cliente, e como a percepção do
produto evolui ao longo do tempo?
Esta abordagem exige o uso de técnicas de Text Mining e Processamento de Linguagem Natural (NLP), satisfazendo os requisitos de complexidade do projeto.
Fonte: Dataset de Reviews da Amazon (versão pública, como Kaggle ou UCSD). Tipo: dado não estruturado primariamente (o texto).
Justificativa Técnica (Requisitos do Projeto):
Esta etapa é crucial para transformar o texto bruto em dados quantificáveis, atendendo diretamente aos requisitos de limpeza e criação de variáveis.
3.1. Limpeza e Organização dos Dados
3.2. Criação de Variáveis (Engenharia de Features)
Para ir além das variáveis originais, serão criadas variáveis que sustentam a análise:
unixReviewTime), será extraído o
Mês e o Ano para permitir a análise da
evolução do sentimento ao longo do tempo.3.3. Pacotes Requeridos
Os principais pacotes utilizados neste projeto são:
tidyverse: manipulação e visualização de dados.lubridate: Facilita o trabalho com datas e tempos.janitor: Limpa e organiza nomes e estruturas de
dados.knitr:Gera relatórios dinâmicos (RMarkdown, HTML,
PDF).dplyr:Manipulação de dados com operações como filtrar,
selecionar e agrupar.tidytext:Processamento de texto (tokenização, léxicos,
NLP).stringr: Manipulação de strings (textos) de forma
simples e consistente.ggplot2: Criação de gráficos elegantes e
personalizáveis.DT: Criação de tabelas interativas em HTML.library(tidyverse)
library(lubridate)
library(janitor)
library(knitr)
library(dplyr)
library(tidytext)
library(stringr)
library(ggplot2)
library(DT)
3.4. Fonte dos Dados
Os dados utilizados neste trabalho foram coletados em uma plataforma pública de dados chamada Kaggle, que reúne datasets de diversas áreas com fins educacionais e de pesquisa.
A análise será focada em gerar insights que “contem a história” do produto, indo além de estatísticas descritivas simples e buscando padrões relevantes na experiência dos clientes.
4.1.Preparação dos Dados
✅ REDUZIR O DATASET ✅ SALVAR A VERSÃO REDUZIDA ✅ CARREGAR A VERSÃO LEVE PARA ANÁLISE ✅ LIMPAR + PREPARAR + ENRIQUECER OS DADOS ✅ GERAR A BASE FINAL PARA ANÁLISE DESCRITIVA E DE SENTIMENTO
4.2.Carregar o dataset tratado
library(readr)
library(dplyr)
library(ggplot2)
dados <- read_csv("amazon_tratado_pt.csv")
## Rows: 20000 Columns: 6
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (2): resumo, avaliacao
## dbl (4): nota, id_avaliacao, tam_avaliacao, tam_resumo
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(dados, 3)
## # A tibble: 3 × 6
## nota resumo avaliacao id_avaliacao tam_avaliacao tam_resumo
## <dbl> <chr> <chr> <dbl> <dbl> <dbl>
## 1 2 stuning even for the no… "this so… 1 392 30
## 2 2 the best soundtrack eve… "i'm rea… 2 470 37
## 3 2 amazing! "this so… 3 748 8
4.3.Visão geral do dataset
# Quantidade de linhas e colunas
dim(dados)
## [1] 20000 6
# Estrutura
str(dados)
## spc_tbl_ [20,000 × 6] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ nota : num [1:20000] 2 2 2 2 2 2 1 2 2 2 ...
## $ resumo : chr [1:20000] "stuning even for the non-gamer" "the best soundtrack ever to anything." "amazing!" "excellent soundtrack" ...
## $ avaliacao : chr [1:20000] "this sound track was beautiful! it paints the senery in your mind so well i would recomend it even to people wh"| __truncated__ "i'm reading a lot of reviews saying that this is the best 'game soundtrack' and i figured that i'd write a revi"| __truncated__ "this soundtrack is my favorite music of all time, hands down. the intense sadness of \"prisoners of fate\" (whi"| __truncated__ "i truly like this soundtrack and i enjoy video game music. i have played this game and most of the music on her"| __truncated__ ...
## $ id_avaliacao : num [1:20000] 1 2 3 4 5 6 7 8 9 10 ...
## $ tam_avaliacao: num [1:20000] 392 470 748 721 425 798 724 506 506 270 ...
## $ tam_resumo : num [1:20000] 30 37 8 20 54 23 12 14 16 29 ...
## - attr(*, "spec")=
## .. cols(
## .. nota = col_double(),
## .. resumo = col_character(),
## .. avaliacao = col_character(),
## .. id_avaliacao = col_double(),
## .. tam_avaliacao = col_double(),
## .. tam_resumo = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
# Primeiras linhas
head(dados, 5)
## # A tibble: 5 × 6
## nota resumo avaliacao id_avaliacao tam_avaliacao tam_resumo
## <dbl> <chr> <chr> <dbl> <dbl> <dbl>
## 1 2 stuning even for the no… "this so… 1 392 30
## 2 2 the best soundtrack eve… "i'm rea… 2 470 37
## 3 2 amazing! "this so… 3 748 8
## 4 2 excellent soundtrack "i truly… 4 721 20
## 5 2 remember, pull your jaw… "if you'… 5 425 54
Visualizações Chave e Gráficos Propostos
4.4. ANÁLISE DESCRITIVA
1. Contagem de avaliações por nota
As avaliações mostram a distribuição de notas atribuídas pelos usuários. Essa tabela permite identificar quais notas são mais frequentes e se há tendência de avaliações mais positivas ou negativas.
dados %>%
count(nota) %>%
arrange(nota)
## # A tibble: 2 × 2
## nota n
## <dbl> <int>
## 1 1 9743
## 2 2 10257
2. Gráfico de barras da distribuição das notas
O gráfico mostra como as notas estão distribuídas no conjunto analisado. É possível observar rapidamente se o produto recebe mais avaliações positivas (4–5) ou negativas (1–2). Esse padrão é fundamental para entender a percepção geral dos consumidores.
ggplot(dados, aes(x = nota)) +
geom_bar(fill = "#0073C2FF") +
labs(
title = "Distribuição das Notas das Avaliações",
x = "Nota atribuída",
y = "Quantidade de avaliações"
) +
theme_minimal()
3. Estatísticas dos tamanhos dos textos
As medidas de média, mediana e extremos revelam como os usuários escrevem suas avaliações. Avaliações muito curtas podem indicar baixa qualidade, enquanto textos longos sugerem maior detalhamento nas experiências relatadas.
dados %>%
summarise(
media_tam_ava = mean(tam_avaliacao),
mediana_tam_ava = median(tam_avaliacao),
minimo_tam_ava = min(tam_avaliacao),
maximo_tam_ava = max(tam_avaliacao),
media_tam_res = mean(tam_resumo),
mediana_tam_res = median(tam_resumo),
minimo_tam_res = min(tam_resumo),
maximo_tam_res = max(tam_resumo)
)
## # A tibble: 1 × 8
## media_tam_ava mediana_tam_ava minimo_tam_ava maximo_tam_ava media_tam_res
## <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 409. 358 55 1007 24.6
## # ℹ 3 more variables: mediana_tam_res <dbl>, minimo_tam_res <dbl>,
## # maximo_tam_res <dbl>
4. Histogramas dos tamanhos dos textos
O histograma evidencia como o tamanho das avaliações se distribui no dataset. A concentração em determinadas faixas de caracteres indica a tendência de textos curtos ou longos entre os usuários.
ggplot(dados, aes(x = tam_avaliacao)) +
geom_histogram(binwidth = 20, fill = "#FFA500", color = "white") +
labs(
title = "Distribuição do Tamanho das Avaliações",
x = "Número de caracteres",
y = "Frequência"
) +
theme_minimal()
5. Histogramas do resumo
Estes resumos normalmente são bem mais curtos que as avaliações completas. O histograma mostra se os usuários costumam escrever títulos breves ou mais elaborados para suas opiniões.
ggplot(dados, aes(x = tam_resumo)) +
geom_histogram(binwidth = 10, fill = "#8A2BE2", color = "white") +
labs(
title = "Distribuição do Tamanho dos Resumos",
x = "Número de caracteres",
y = "Frequência"
) +
theme_minimal()
6. Boxplot do tamanho das avaliações por nota
O boxplot permite comparar se avaliações positivas ou negativas costumam ser mais longas. Textos de notas baixas tendem a ser maiores quando o consumidor detalha problemas ou justificativas.
ggplot(dados, aes(x = nota, y = tam_avaliacao)) +
geom_boxplot(fill = "#00BFC4") +
labs(
title = "Tamanho das Avaliações por Nota",
x = "Nota",
y = "Tamanho da Avaliação (caracteres)"
) +
theme_minimal()
## Warning: Continuous x aesthetic
## ℹ did you forget `aes(group = ...)`?
7. Identificar avaliações muito curtas (potencial spam)
Listar as avaliações extremamente curtas ajuda a identificar possíveis ruídos ou registros de baixa relevância. Esses textos podem representar recomendações rápidas ou até potenciais avaliações automáticas.
dados %>%
filter(tam_avaliacao < 20) %>%
select(id_avaliacao, nota, avaliacao) %>%
head(10)
## # A tibble: 0 × 3
## # ℹ 3 variables: id_avaliacao <dbl>, nota <dbl>, avaliacao <chr>
8. Avaliações mais longas (detalhadas)
As avaliações mais extensas geralmente contêm relatos detalhados da experiência do usuário. Elas são úteis para identificar padrões narrativos e temas recorrentes nas opiniões.
dados %>%
arrange(desc(tam_avaliacao)) %>%
select(id_avaliacao, nota, avaliacao, tam_avaliacao) %>%
head(10)
## # A tibble: 10 × 4
## id_avaliacao nota avaliacao tam_avaliacao
## <dbl> <dbl> <chr> <dbl>
## 1 14186 1 "stop buying clay's fame!!!!!this cd is def… 1007
## 2 8431 1 "i'll come clean first. i stopped reading a… 1002
## 3 748 2 "this novel is an opera, pure and simple.gr… 1001
## 4 7184 1 "the book fahrenheit 451 by ray bradbury in… 999
## 5 6506 1 "i totally disagree with the reviewer from … 996
## 6 1767 1 "i can't believe i wasted my money on this!… 995
## 7 15239 1 "i have to agree with others reviewers that… 995
## 8 17377 2 "this movie shows the untold story of what … 995
## 9 2723 1 "i didn't too sure about this. it was on sp… 993
## 10 7387 2 "when i first started reading farenheit 451… 993
9. Quantidade de caracteres por nota (média)
A análise mostra se notas altas ou baixas estão associadas a textos mais longos. Isso ajuda a entender como a intensidade da satisfação (ou insatisfação) influencia o detalhamento do comentário.
dados %>%
group_by(nota) %>%
summarise(
media_caracteres = mean(tam_avaliacao),
mediana_caracteres = median(tam_avaliacao)
)
## # A tibble: 2 × 3
## nota media_caracteres mediana_caracteres
## <dbl> <dbl> <dbl>
## 1 1 424. 378
## 2 2 394. 339
Conclusão da Análise Descritiva
A análise descritiva revelou padrões importantes sobre o comportamento dos usuários nas avaliações. A distribuição das notas mostrou a percepção geral do produto, enquanto os histogramas e boxplots permitiram observar como o tamanho dos textos varia entre diferentes níveis de satisfação. Também foi possível identificar avaliações extremamente curtas e outras bastante detalhadas, indicando a diversidade de estilos de escrita presentes no dataset.
4.5 ANÁLISE DE SENTIMENTO
A análise de sentimento permite compreender como os consumidores expressam suas emoções nas avaliações. A partir da extração de palavras e da classificação automática entre termos positivos e negativos, é possível identificar padrões linguísticos que revelam a percepção real do usuário sobre o produto. Essa etapa aprofundada complementa a análise descritiva ao transformar texto não estruturado em informações quantificáveis e comparáveis.
1. Tokenização do Texto (quebrar em palavras)
A tokenização transforma cada avaliação em um conjunto de palavras individuais. Isso permite analisar o vocabulário utilizado pelos usuários e facilita a aplicação de técnicas de mineração de texto.
# carregando stopwords em inglês
data("stop_words")
tokens <- dados %>%
unnest_tokens(word, avaliacao) %>% # transforma texto em palavras
anti_join(stop_words, by = "word") %>% # remove stopwords
filter(str_detect(word, "[a-z]")) # remove tokens estranhos
head(tokens, 10)
## # A tibble: 10 × 6
## nota resumo id_avaliacao tam_avaliacao tam_resumo word
## <dbl> <chr> <dbl> <dbl> <dbl> <chr>
## 1 2 stuning even for the non-g… 1 392 30 sound
## 2 2 stuning even for the non-g… 1 392 30 track
## 3 2 stuning even for the non-g… 1 392 30 beau…
## 4 2 stuning even for the non-g… 1 392 30 pain…
## 5 2 stuning even for the non-g… 1 392 30 sene…
## 6 2 stuning even for the non-g… 1 392 30 mind
## 7 2 stuning even for the non-g… 1 392 30 reco…
## 8 2 stuning even for the non-g… 1 392 30 peop…
## 9 2 stuning even for the non-g… 1 392 30 hate
## 10 2 stuning even for the non-g… 1 392 30 vid
2. Carregar o léxico de sentimento (bing)
Ao cruzar cada palavra com o léxico de sentimento, identificamos automaticamente se ela expressa emoção positiva ou negativa. Isso transforma simples palavras em indicadores emocionais.
sent_bing <- get_sentiments("bing")
head(sent_bing, 10)
## # A tibble: 10 × 2
## word sentiment
## <chr> <chr>
## 1 2-faces negative
## 2 abnormal negative
## 3 abolish negative
## 4 abominable negative
## 5 abominably negative
## 6 abominate negative
## 7 abomination negative
## 8 abort negative
## 9 aborted negative
## 10 aborts negative
3. Cruzar tokens com sentimentos
Essa contagem revela o balanço de emoções no conjunto de avaliações. Uma predominância de palavras positivas ou negativas reflete a tendência geral da percepção dos consumidores.
tokens_sent <- tokens %>%
inner_join(sent_bing, by = "word") # adiciona coluna 'sentiment'
head(tokens_sent, 10)
## # A tibble: 10 × 7
## nota resumo id_avaliacao tam_avaliacao tam_resumo word sentiment
## <dbl> <chr> <dbl> <dbl> <dbl> <chr> <chr>
## 1 2 stuning even for… 1 392 30 beau… positive
## 2 2 stuning even for… 1 392 30 reco… positive
## 3 2 stuning even for… 1 392 30 hate negative
## 4 2 stuning even for… 1 392 30 crude negative
## 5 2 stuning even for… 1 392 30 fres… positive
## 6 2 stuning even for… 1 392 30 grate negative
## 7 2 stuning even for… 1 392 30 soul… positive
## 8 2 stuning even for… 1 392 30 impr… positive
## 9 2 the best soundtr… 2 470 37 disa… negative
## 10 2 the best soundtr… 2 470 37 mast… positive
4. Contagem de palavras positivas e negativas
contagem_sent <- tokens_sent %>%
count(sentiment)
contagem_sent
## # A tibble: 2 × 2
## sentiment n
## <chr> <int>
## 1 negative 44284
## 2 positive 45177
5. Gráfico de palavras positivas vs. negativas
O gráfico mostra visualmente a proporção entre termos positivos e negativos usados pelos usuários. Uma diferença marcante indica polarização emocional nas avaliações.
ggplot(tokens_sent, aes(x = sentiment)) +
geom_bar(fill = c("#E74C3C", "#2ECC71")) +
labs(
title = "Frequência de Palavras Positivas e Negativas",
x = "Sentimento",
y = "Quantidade de Palavras"
) +
theme_minimal()
6. Palavras negativas mais frequentes
As palavras negativas mais usadas ajudam a identificar os principais problemas mencionados pelos consumidores. Esses termos frequentemente apontam pontos fracos ou frustrações recorrentes.
tokens_sent %>%
filter(sentiment == "negative") %>%
count(word, sort = TRUE) %>%
head(20)
## # A tibble: 20 × 2
## word n
## <chr> <int>
## 1 bad 1466
## 2 hard 950
## 3 plot 794
## 4 disappointed 769
## 5 waste 748
## 6 boring 695
## 7 worst 540
## 8 wrong 494
## 9 poor 451
## 10 funny 418
## 11 lost 363
## 12 difficult 351
## 13 terrible 351
## 14 horrible 345
## 15 cheap 331
## 16 fiction 302
## 17 slow 290
## 18 dark 267
## 19 worse 252
## 20 sad 246
7. Gráfico: Palavras Negativas Mais Frequentes
O gráfico evidencia de forma clara os termos negativos mais comuns. Esse tipo de visualização facilita a identificação de temas sensíveis que geram insatisfação.
tokens_sent %>%
filter(sentiment == "negative") %>%
count(word, sort = TRUE) %>%
head(15) %>%
ggplot(aes(x = reorder(word, n), y = n)) +
geom_col(fill = "#E74C3C") +
coord_flip() +
labs(
title = "Top 15 Palavras Negativas",
x = "Palavras",
y = "Frequência"
) +
theme_minimal()
8. Palavras positivas mais frequentes
As palavras positivas mais frequentes destacam os aspectos mais elogiados pelos clientes. Elas ajudam a compreender quais características despertam satisfação.
tokens_sent %>%
filter(sentiment == "positive") %>%
count(word, sort = TRUE) %>%
head(20)
## # A tibble: 20 × 2
## word n
## <chr> <int>
## 1 love 2426
## 2 recommend 1507
## 3 worth 1010
## 4 easy 871
## 5 pretty 727
## 6 fun 718
## 7 excellent 713
## 8 enjoy 700
## 9 loved 677
## 10 nice 674
## 11 wonderful 661
## 12 pampers 617
## 13 favorite 578
## 14 classic 571
## 15 amazing 543
## 16 enjoyed 536
## 17 perfect 518
## 18 top 510
## 19 fine 499
## 20 beautiful 442
9. Gráfico: Palavras Positivas Mais Frequentes
O gráfico mostra os principais termos elogiosos presentes nas avaliações. Esses destaques permitem entender os pontos fortes percebidos pelos usuários.
tokens_sent %>%
filter(sentiment == "positive") %>%
count(word, sort = TRUE) %>%
head(15) %>%
ggplot(aes(x = reorder(word, n), y = n)) +
geom_col(fill = "#2ECC71") +
coord_flip() +
labs(
title = "Top 15 Palavras Positivas",
x = "Palavras",
y = "Frequência"
) +
theme_minimal()
10. Sentimento Médio por Nota
A contagem por nota conecta a emoção expressa no texto com a avaliação numérica. Isso revela se avaliações baixas contêm mais negatividade e se notas altas são mais positivas.
Avaliar se notas baixas usam mais palavras negativas.
sent_nota <- tokens_sent %>%
count(nota, sentiment)
sent_nota
## # A tibble: 4 × 3
## nota sentiment n
## <dbl> <chr> <int>
## 1 1 negative 28754
## 2 1 positive 16320
## 3 2 negative 15530
## 4 2 positive 28857
11. Gráfico: Proporção de Sentimentos por Nota
Esse gráfico mostra a composição percentual de palavras positivas e negativas em cada nota. Ele evidencia como a emoção expressa no texto varia conforme o nível de satisfação.
sent_nota %>%
group_by(nota) %>%
mutate(prop = n / sum(n)) %>%
ggplot(aes(x = nota, y = prop, fill = sentiment)) +
geom_col(position = "fill") +
scale_fill_manual(values = c("negative" = "#E74C3C", "positive" = "#2ECC71")) +
labs(
title = "Proporção de Sentimentos por Nota",
x = "Nota",
y = "Proporção",
fill = "Sentimento"
) +
theme_minimal()
12. Score de Sentimento por Avaliação
O score de sentimento resume a emoção de cada comentário em um único número. Valores positivos indicam avaliações textuais mais otimistas, enquanto scores negativos revelam tom negativo.
score_av <- tokens_sent %>%
mutate(valor = ifelse(sentiment == "positive", 1, -1)) %>%
group_by(id_avaliacao, nota) %>%
summarise(score_sentimento = sum(valor)) %>%
ungroup()
## `summarise()` has grouped output by 'id_avaliacao'. You can override using the
## `.groups` argument.
head(score_av, 10)
## # A tibble: 10 × 3
## id_avaliacao nota score_sentimento
## <dbl> <dbl> <dbl>
## 1 1 2 2
## 2 2 2 2
## 3 3 2 2
## 4 4 2 -2
## 5 5 2 0
## 6 6 2 3
## 7 7 1 -5
## 8 8 2 3
## 9 9 2 -1
## 10 10 2 3
13. Gráfico do Score Médio por Nota
O gráfico mostra como o sentimento textual médio evolui de acordo com a nota atribuída. Ele ajuda a validar se o texto acompanha ou contradiz a avaliação numérica.
score_av %>%
group_by(nota) %>%
summarise(score_medio = mean(score_sentimento)) %>%
ggplot(aes(x = nota, y = score_medio, group = 1)) +
geom_line(color = "#0073C2", size = 1.2) +
geom_point(size = 3, color = "#FFA500") +
labs(
title = "Score Médio de Sentimento por Nota",
x = "Nota",
y = "Score Médio"
) +
theme_minimal()
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
14. Gráfico de Linha (Tendência Temporal)
Mostrar o Sentimento Médio (ou a proporção de
reviews negativos) por mês/ano.
Insight: revela picos de insatisfação (por exemplo, após uma
atualização de firmware ou um novo lote de produção).
set.seed(123)
dados$data_review <- sample(
seq(as.Date("2023-01-01"), as.Date("2023-12-31"), by = "day"),
size = nrow(dados),
replace = TRUE
)
sent_mensal <- score_av %>%
left_join(dados %>% select(id_avaliacao, data_review), by = "id_avaliacao") %>%
mutate(mes = format(data_review, "%Y-%m")) %>%
group_by(mes) %>%
summarise(score_medio = mean(score_sentimento))
head(sent_mensal)
## # A tibble: 6 × 2
## mes score_medio
## <chr> <dbl>
## 1 2023-01 0.0966
## 2 2023-02 0.0507
## 3 2023-03 -0.0395
## 4 2023-04 0.0715
## 5 2023-05 0.113
## 6 2023-06 0.0497
ggplot(sent_mensal, aes(x = mes, y = score_medio, group = 1)) +
geom_line(color = "#0073C2", size = 1.2) +
geom_point(color = "#FFA500", size = 3) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
labs(
title = "Tendência Temporal do Sentimento Médio",
x = "Mês/Ano",
y = "Score Médio de Sentimento"
)
15. Gráfico de Barras (Contagem de Aspectos)
Geração de uma nuvem de palavras ou gráfico de barras mostrando as palavras mais frequentes, filtrando apenas os reviews negativos.
aspectos_neg <- tokens_sent %>%
filter(sentiment == "negative") %>%
count(word, sort = TRUE) %>%
slice_head(n = 20)
aspectos_neg
## # A tibble: 20 × 2
## word n
## <chr> <int>
## 1 bad 1466
## 2 hard 950
## 3 plot 794
## 4 disappointed 769
## 5 waste 748
## 6 boring 695
## 7 worst 540
## 8 wrong 494
## 9 poor 451
## 10 funny 418
## 11 lost 363
## 12 difficult 351
## 13 terrible 351
## 14 horrible 345
## 15 cheap 331
## 16 fiction 302
## 17 slow 290
## 18 dark 267
## 19 worse 252
## 20 sad 246
ggplot(aspectos_neg, aes(x = reorder(word, n), y = n)) +
geom_col(fill = "#E74C3C") +
coord_flip() +
labs(
title = "Principais Aspectos Negativos Mencionados nas Avaliações",
x = "Palavras",
y = "Frequência"
) +
theme_minimal()
16. Comparação Cruzada (Nota x Sentimento)
Gráfico de barras que compara a nota numérica
original com a polaridade de sentimento
calculada pelo algoritmo.
Exemplo: “Quantos reviews com nota 3 foram classificados como
Negativos?”
polaridade <- score_av %>%
mutate(
sentimento_final = case_when(
score_sentimento > 0 ~ "positivo",
score_sentimento < 0 ~ "negativo",
TRUE ~ "neutro"
)
)
head(polaridade)
## # A tibble: 6 × 4
## id_avaliacao nota score_sentimento sentimento_final
## <dbl> <dbl> <dbl> <chr>
## 1 1 2 2 positivo
## 2 2 2 2 positivo
## 3 3 2 2 positivo
## 4 4 2 -2 negativo
## 5 5 2 0 neutro
## 6 6 2 3 positivo
cont_nota_sent <- polaridade %>%
count(nota, sentimento_final)
cont_nota_sent
## # A tibble: 6 × 3
## nota sentimento_final n
## <dbl> <chr> <int>
## 1 1 negativo 5788
## 2 1 neutro 1235
## 3 1 positivo 2181
## 4 2 negativo 1938
## 5 2 neutro 1119
## 6 2 positivo 6592
ggplot(cont_nota_sent, aes(x = nota, y = n, fill = sentimento_final)) +
geom_col(position = "dodge") +
scale_fill_manual(
values = c("negativo" = "#E74C3C", "positivo" = "#2ECC71", "neutro" = "#95A5A6")
) +
labs(
title = "Comparação entre Nota e Sentimento Identificado",
x = "Nota Atribuída",
y = "Número de Avaliações",
fill = "Sentimento"
) +
theme_minimal()
Conclusão da Análise de Sentimento
A análise de sentimento permitiu transformar o texto das avaliações em indicadores claros das emoções expressas pelos consumidores. As palavras negativas e positivas mostraram os principais motivos de insatisfação e elogio, enquanto a comparação entre notas e polaridade evidenciou como o sentimento textual acompanha — ou contrasta — a nota atribuída. De forma geral, o modelo revelou padrões consistentes, destacando aspectos críticos mencionados pelos usuários e fornecendo uma visão mais profunda da experiência real com o produto.
Conclusão da História
O projeto não apenas relatará estatísticas, mas fornecerá uma
narração sobre os aspectos de maior impacto na
satisfação do consumidor da categoria analisada.
Limitações e Desafios
Serão discutidas as limitações do modelo de sentimento (por exemplo,
dificuldade em capturar sarcasmo ou
ironia) e os desafios da limpeza de texto, que pode
influenciar diretamente a qualidade das métricas.
Inovação
A utilização de técnicas avançadas de NLP (tokenização,
análise de sentimento léxica) representa o uso de métodos não abordados
integralmente em sala de aula, adicionando valor à proposta e alinhando
o trabalho com práticas contemporâneas de análise de dados em ambientes
reais.