1. Introdução

1.1 Problema analisado

O crescimento do comércio eletrônico transformou a forma como consumidores pesquisam e escolhem produtos. Atualmente, avaliações publicadas por outros usuários exercem grande influência no processo de decisão de compra, funcionando como uma importante fonte de informação sobre qualidade, desempenho e satisfação com determinado produto.

No entanto, nem todas as avaliações possuem o mesmo valor para os consumidores. Algumas recebem diversos votos indicando que foram úteis, enquanto outras praticamente não recebem atenção. Dessa forma, surge a seguinte questão: quais características tornam uma avaliação mais útil para outros usuários?

Responder essa pergunta é relevante tanto para consumidores, que podem identificar comentários mais informativos, quanto para empresas e plataformas de comércio eletrônico, que podem aprimorar sistemas de recomendação e destaque de avaliações.

1.2 Objetivo do projeto

O objetivo deste projeto é analisar o conjunto de dados Amazon Fine Food Reviews Dataset para investigar possíveis fatores relacionados à utilidade das avaliações publicadas pelos usuários.

A análise busca identificar padrões envolvendo características como:

  • nota atribuída ao produto;
  • tamanho da avaliação;
  • quantidade de votos recebidos;
  • evolução temporal das avaliações;
  • relação entre avaliações úteis e não úteis.

1.3 Dataset utilizado

O conjunto de dados utilizado foi o Amazon Fine Food Reviews Dataset, disponibilizado publicamente no Kaggle.

Fonte: https://www.kaggle.com/datasets/snap/amazon-fine-food-reviews

O dataset contém avaliações de produtos alimentícios comercializados na Amazon entre os anos de 1999 e 2012, reunindo informações sobre usuários, produtos, notas atribuídas, votos de utilidade, resumos e textos completos das avaliações.

Ao todo, o conjunto de dados possui 568.454 avaliações distribuídas em 10 variáveis originais, permitindo análises exploratórias bastante abrangentes.

1.4 Metodologia adotada

A metodologia utilizada neste trabalho foi dividida em quatro etapas principais:

  1. importação e compreensão inicial do conjunto de dados;
  2. verificação da estrutura das variáveis;
  3. limpeza e transformação das informações;
  4. criação de variáveis derivadas e análises exploratórias iniciais.

Essa abordagem permitiu preparar o conjunto de dados para a realização das análises exploratórias e estatísticas apresentadas neste trabalho.

1.5 Estratégia de análise

Para investigar quais características podem tornar uma avaliação mais útil, serão utilizadas técnicas de análise exploratória de dados. Inicialmente será realizada a preparação do conjunto de dados, incluindo limpeza, transformação e criação de variáveis derivadas.

Em seguida, serão construídos gráficos, tabelas e estatísticas descritivas com o objetivo de identificar possíveis relações entre a utilidade das avaliações e características como nota atribuída, tamanho do texto, quantidade de votos recebidos e comportamento temporal das reviews.

A partir dos resultados obtidos, será possível comparar diferentes grupos de avaliações e levantar hipóteses sobre quais fatores contribuem para que uma avaliação seja considerada útil pelos usuários da plataforma.

2. Pacotes utilizados

Para realizar a análise foram utilizados pacotes do ecossistema R voltados para manipulação, visualização e apresentação de dados.

O pacote tidyverse foi utilizado para limpeza, transformação e manipulação dos dados. O pacote lubridate auxiliou no tratamento das datas extraídas dos registros originais. O pacote readr foi utilizado para importação eficiente do arquivo CSV contendo mais de meio milhão de registros.

Além disso, foram utilizados os pacotes knitr para geração de tabelas no relatório, DT para construção de tabelas interativas e plotly para criação de visualizações interativas.

pacotes <- tibble(
  Pacote = c("tidyverse", "lubridate", "readr", "knitr", "DT", "plotly"),
  Finalidade = c(
    "Manipulação, limpeza e visualização dos dados",
    "Tratamento e extração de informações de datas",
    "Importação eficiente de arquivos CSV",
    "Criação de tabelas no relatório",
    "Criação de tabelas interativas",
    "Criação de gráficos interativos"
  )
)

kable(pacotes, caption = "Pacotes utilizados no projeto")
Pacotes utilizados no projeto
Pacote Finalidade
tidyverse Manipulação, limpeza e visualização dos dados
lubridate Tratamento e extração de informações de datas
readr Importação eficiente de arquivos CSV
knitr Criação de tabelas no relatório
DT Criação de tabelas interativas
plotly Criação de gráficos interativos

3. Preparação dos dados

3.1 Importação dos dados

reviews_original <- read_csv(
  "Reviews.csv",
  show_col_types = FALSE
)

dim(reviews_original)
## [1] 568454     10

O resultado acima confirma que o dataset foi importado corretamente, contendo 568.454 registros e 10 variáveis.

3.2 Estrutura original dos dados

glimpse(reviews_original)
## Rows: 568,454
## Columns: 10
## $ Id                     <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, …
## $ ProductId              <chr> "B001E4KFG0", "B00813GRG4", "B000LQOCH0", "B000…
## $ UserId                 <chr> "A3SGXH7AUHU8GW", "A1D87F6ZCVE5NK", "ABXLMWJIXX…
## $ ProfileName            <chr> "delmartian", "dll pa", "Natalia Corres \"Natal…
## $ HelpfulnessNumerator   <dbl> 1, 0, 1, 3, 0, 0, 0, 0, 1, 0, 1, 4, 1, 2, 4, 4,…
## $ HelpfulnessDenominator <dbl> 1, 0, 1, 3, 0, 0, 0, 0, 1, 0, 1, 4, 1, 2, 5, 5,…
## $ Score                  <dbl> 5, 1, 4, 2, 5, 4, 5, 5, 5, 5, 5, 5, 1, 4, 5, 5,…
## $ Time                   <dbl> 1303862400, 1346976000, 1219017600, 1307923200,…
## $ Summary                <chr> "Good Quality Dog Food", "Not as Advertised", "…
## $ Text                   <chr> "I have bought several of the Vitality canned d…
variaveis_originais <- tibble(
  Variavel = c(
    "Id",
    "ProductId",
    "UserId",
    "ProfileName",
    "HelpfulnessNumerator",
    "HelpfulnessDenominator",
    "Score",
    "Time",
    "Summary",
    "Text"
  ),
  Descricao = c(
    "Identificador único da avaliação",
    "Identificador do produto avaliado",
    "Identificador do usuário",
    "Nome do perfil do usuário",
    "Quantidade de votos indicando que a avaliação foi útil",
    "Quantidade total de votos recebidos pela avaliação",
    "Nota atribuída ao produto, variando de 1 a 5",
    "Data da avaliação em formato Unix timestamp",
    "Resumo curto da avaliação",
    "Texto completo da avaliação"
  )
)

kable(variaveis_originais, caption = "Descrição das variáveis originais")
Descrição das variáveis originais
Variavel Descricao
Id Identificador único da avaliação
ProductId Identificador do produto avaliado
UserId Identificador do usuário
ProfileName Nome do perfil do usuário
HelpfulnessNumerator Quantidade de votos indicando que a avaliação foi útil
HelpfulnessDenominator Quantidade total de votos recebidos pela avaliação
Score Nota atribuída ao produto, variando de 1 a 5
Time Data da avaliação em formato Unix timestamp
Summary Resumo curto da avaliação
Text Texto completo da avaliação

A presença simultânea de dados numéricos, textuais e temporais torna esse conjunto de dados interessante para análises exploratórias.

3.3 Verificação de valores ausentes

valores_ausentes <- reviews_original %>%
  summarise(across(everything(), ~ sum(is.na(.)))) %>%
  pivot_longer(
    cols = everything(),
    names_to = "Variavel",
    values_to = "Quantidade_NA"
  )

kable(valores_ausentes, caption = "Quantidade de valores ausentes por variável")
Quantidade de valores ausentes por variável
Variavel Quantidade_NA
Id 0
ProductId 0
UserId 0
ProfileName 4
HelpfulnessNumerator 0
HelpfulnessDenominator 0
Score 0
Time 0
Summary 0
Text 0

A verificação de valores ausentes é importante para identificar possíveis problemas antes das análises. Valores ausentes podem afetar cálculos de médias, contagens, gráficos e interpretações.

3.4 Remoção de duplicatas

reviews <- reviews_original %>%
  distinct()

linhas_removidas <- nrow(reviews_original) - nrow(reviews)

linhas_removidas
## [1] 0

A remoção de duplicatas foi realizada para evitar que registros repetidos influenciassem os resultados da análise.

3.5 Conversão da variável de tempo

A variável Time estava originalmente em formato Unix timestamp. Para facilitar a análise temporal, essa variável foi convertida para data, e também foram criadas as variáveis Ano e Mes.

reviews <- reviews %>%
  mutate(
    Data = as.Date(as.POSIXct(Time, origin = "1970-01-01")),
    Ano = year(Data),
    Mes = month(Data)
  )

3.6 Criação de novas variáveis

Foram criadas novas variáveis para enriquecer a análise e permitir observar características que não estavam diretamente disponíveis no dataset original.

reviews <- reviews %>%
  mutate(
    tamanho_review = nchar(Text),
    tamanho_resumo = nchar(Summary),
    helpful_rate = ifelse(
      HelpfulnessDenominator == 0,
      0,
      HelpfulnessNumerator / HelpfulnessDenominator
    ),
    classificacao_nota = case_when(
      Score >= 4 ~ "Positiva",
      Score == 3 ~ "Neutra",
      Score <= 2 ~ "Negativa"
    ),
    review_util = ifelse(helpful_rate >= 0.5, "Útil", "Não útil")
  )
novas_variaveis <- tibble(
  Variavel = c(
    "Data",
    "Ano",
    "Mes",
    "tamanho_review",
    "tamanho_resumo",
    "helpful_rate",
    "classificacao_nota",
    "review_util"
  ),
  Descricao = c(
    "Data da avaliação convertida a partir do timestamp original",
    "Ano em que a avaliação foi publicada",
    "Mês em que a avaliação foi publicada",
    "Quantidade de caracteres no texto completo da avaliação",
    "Quantidade de caracteres no resumo da avaliação",
    "Proporção de votos úteis em relação ao total de votos recebidos",
    "Classificação da nota como positiva, neutra ou negativa",
    "Classificação da avaliação como útil ou não útil"
  )
)

kable(novas_variaveis, caption = "Variáveis criadas durante o pré-processamento")
Variáveis criadas durante o pré-processamento
Variavel Descricao
Data Data da avaliação convertida a partir do timestamp original
Ano Ano em que a avaliação foi publicada
Mes Mês em que a avaliação foi publicada
tamanho_review Quantidade de caracteres no texto completo da avaliação
tamanho_resumo Quantidade de caracteres no resumo da avaliação
helpful_rate Proporção de votos úteis em relação ao total de votos recebidos
classificacao_nota Classificação da nota como positiva, neutra ou negativa
review_util Classificação da avaliação como útil ou não útil

3.7 Seleção das variáveis principais

reviews_limpo <- reviews %>%
  select(
    Id,
    ProductId,
    UserId,
    ProfileName,
    Score,
    HelpfulnessNumerator,
    HelpfulnessDenominator,
    helpful_rate,
    review_util,
    classificacao_nota,
    Summary,
    Text,
    tamanho_review,
    tamanho_resumo,
    Data,
    Ano,
    Mes
  )

3.8 Amostra do conjunto final

Para evitar imprimir uma tabela muito grande, abaixo é apresentada apenas uma amostra de 10 registros do conjunto de dados após o pré-processamento.

set.seed(123)

reviews_limpo %>%
  sample_n(10) %>%
  select(
    Score,
    helpful_rate,
    review_util,
    classificacao_nota,
    tamanho_review,
    Data,
    Summary
  ) %>%
  kable(caption = "Amostra do conjunto de dados após o pré-processamento")
Amostra do conjunto de dados após o pré-processamento
Score helpful_rate review_util classificacao_nota tamanho_review Data Summary
1 0.4583333 Não útil Negativa 340 2010-08-18 Beware: 8 oz only!!!
5 0.8333333 Útil Positiva 264 2009-06-18 Gluten free and Great tasting
5 1.0000000 Útil Positiva 213 2010-10-03 Bev
5 0.0000000 Não útil Positiva 117 2012-04-20 good
2 0.0000000 Não útil Negativa 196 2012-03-13 Salty and with bones
5 0.0000000 Não útil Positiva 528 2012-01-29 Tasty, crunchy and healthy
5 1.0000000 Útil Positiva 328 2009-04-03 Great healthy treats for the kids
1 0.6666667 Útil Negativa 1960 2010-09-19 Changed the ingredients to now include meat products! ZERO STARS
5 0.0000000 Não útil Positiva 199 2011-05-17 Surprisingly good
4 0.0000000 Não útil Positiva 888 2012-01-29 Spicy, limey, popchips.

3.9 Resumo das variáveis de interesse

resumo_geral <- reviews_limpo %>%
  summarise(
    total_reviews = n(),
    nota_media = mean(Score, na.rm = TRUE),
    tamanho_medio_review = mean(tamanho_review, na.rm = TRUE),
    tamanho_mediano_review = median(tamanho_review, na.rm = TRUE),
    taxa_media_utilidade = mean(helpful_rate, na.rm = TRUE),
    ano_inicial = min(Ano, na.rm = TRUE),
    ano_final = max(Ano, na.rm = TRUE)
  )

kable(resumo_geral, caption = "Resumo geral do dataset após o pré-processamento")
Resumo geral do dataset após o pré-processamento
total_reviews nota_media tamanho_medio_review tamanho_mediano_review taxa_media_utilidade ano_inicial ano_final
568454 4.183199 436.2221 302 0.4078619 1999 2012

Após o processo de preparação, o conjunto de dados passou a conter informações adicionais que facilitam a identificação de padrões relacionados à utilidade das avaliações. As variáveis derivadas possibilitam comparar grupos de avaliações, observar tendências temporais e analisar o comportamento dos usuários de maneira mais detalhada.

4. Análise exploratória dos dados

4.1 Distribuição das notas

grafico_notas <- reviews_limpo %>%
  count(Score) %>%
  ggplot(aes(x = factor(Score), y = n)) +
  geom_col() +
  labs(
    title = "Distribuição das notas das avaliações",
    x = "Nota",
    y = "Quantidade de avaliações"
  )

grafico_notas

A primeira análise realizada buscou compreender como as notas estão distribuídas dentro do conjunto de dados. Observa-se uma forte concentração de avaliações com nota máxima, indicando que a maior parte dos consumidores avaliou os produtos de forma positiva.

Essa característica sugere um viés positivo nas avaliações presentes na base de dados.

4.2 Classificação geral das avaliações

reviews_limpo %>%
  count(classificacao_nota) %>%
  ggplot(aes(x = classificacao_nota, y = n)) +
  geom_col() +
  labs(
    title = "Classificação das avaliações",
    x = "Classificação",
    y = "Quantidade de avaliações"
  )

A maior parte das avaliações é classificada como positiva. Isso reforça a ideia observada no gráfico anterior: no dataset analisado, os consumidores tendem a atribuir notas altas aos produtos avaliados.

4.3 Evolução das avaliações ao longo do tempo

reviews_limpo %>%
  count(Ano) %>%
  ggplot(aes(x = Ano, y = n)) +
  geom_line() +
  geom_point() +
  labs(
    title = "Quantidade de avaliações por ano",
    x = "Ano",
    y = "Quantidade de avaliações"
  )

Ao analisar a quantidade de avaliações por ano, observa-se um crescimento expressivo da participação dos usuários ao longo do período analisado.

A partir de 2007 ocorre um aumento acelerado no número de avaliações registradas, alcançando os maiores valores próximos ao final do conjunto de dados. Esse comportamento acompanha o crescimento do comércio eletrônico e da popularização das plataformas de avaliação online.

4.4 Relação entre tamanho da review e utilidade

set.seed(123)

amostra_grafico <- reviews_limpo %>%
  sample_n(5000)

ggplot(
  amostra_grafico,
  aes(x = tamanho_review, y = helpful_rate)
) +
  geom_point(alpha = 0.3) +
  labs(
    title = "Relação entre tamanho da review e taxa de utilidade",
    x = "Tamanho da review em caracteres",
    y = "Taxa de utilidade"
  )

Uma das hipóteses deste projeto é que avaliações mais detalhadas tendem a ser consideradas mais úteis pelos usuários.

Embora existam avaliações curtas consideradas úteis, os resultados indicam que comentários mais completos podem fornecer informações mais relevantes para outros consumidores. Essa hipótese é reforçada pelas análises estatísticas apresentadas nas seções seguintes.

4.5 Tamanho médio das reviews úteis e não úteis

reviews_limpo %>%
  group_by(review_util) %>%
  summarise(
    tamanho_medio = mean(tamanho_review),
    quantidade = n()
  ) %>%
  kable(
    caption = "Comparação entre reviews úteis e não úteis"
  )
Comparação entre reviews úteis e não úteis
review_util tamanho_medio quantidade
Não útil 386.2940 320165
Útil 500.6036 248289

Os resultados mostram que reviews classificadas como úteis apresentam, em média, aproximadamente 501 caracteres, enquanto reviews classificadas como não úteis apresentam cerca de 386 caracteres.

Essa diferença sugere que avaliações mais detalhadas tendem a fornecer mais informações aos consumidores e, consequentemente, recebem mais votos de utilidade.

correlacao <- cor(
  reviews_limpo$tamanho_review,
  reviews_limpo$helpful_rate,
  use = "complete.obs"
)

correlacao
## [1] 0.1233427

A correlação calculada entre o tamanho da review e a taxa de utilidade foi de aproximadamente 0,12.

Embora esse valor represente uma correlação positiva fraca, ele indica que existe uma tendência de avaliações mais longas receberem mais votos de utilidade. Esse resultado está alinhado com a comparação das médias apresentada anteriormente, reforçando a hipótese de que comentários mais detalhados tendem a ser considerados mais úteis pelos usuários.

4.6 Nota média das reviews úteis e não úteis

reviews_limpo %>%
  group_by(review_util) %>%
  summarise(
    nota_media = mean(Score, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  ggplot(aes(x = review_util, y = nota_media)) +
  geom_col() +
  labs(
    title = "Nota média das reviews úteis e não úteis",
    x = "Classificação da review",
    y = "Nota média"
  )

Observa-se que a nota média das reviews classificadas como úteis e não úteis é bastante semelhante. Esse resultado sugere que a utilidade de uma avaliação não está diretamente relacionada à nota atribuída ao produto.

Dessa forma, avaliações consideradas úteis podem estar presentes tanto em reviews positivas quanto negativas, desde que forneçam informações relevantes para outros consumidores.

4.7 Taxa média de utilidade por nota

reviews_limpo %>%
  group_by(Score) %>%
  summarise(
    media_utilidade = mean(helpful_rate, na.rm = TRUE),
    .groups = "drop"
  ) %>%
  ggplot(aes(x = factor(Score), y = media_utilidade)) +
  geom_col() +
  labs(
    title = "Taxa média de utilidade por nota",
    x = "Nota",
    y = "Taxa média de utilidade"
  )

Essa análise mostra como a utilidade média varia de acordo com a nota atribuída. O objetivo é observar, de forma preliminar, se avaliações muito positivas, neutras ou negativas recebem maior reconhecimento de utilidade por outros usuários.

4.8 Tabela interativa das avaliações

set.seed(123)

reviews_limpo %>%
  select(
    Score,
    helpful_rate,
    review_util,
    classificacao_nota,
    tamanho_review,
    Data,
    Summary
  ) %>%
  sample_n(100) %>%
  datatable(
    caption = "Amostra interativa das avaliações pré-processadas",
    options = list(pageLength = 10)
  )

A tabela interativa permite explorar uma amostra das avaliações de maneira mais dinâmica, observando simultaneamente nota, taxa de utilidade, tamanho da review, data e resumo.

4.9 Gráfico interativo: avaliações por ano

dados_ano <- reviews_limpo %>%
  count(Ano)

grafico_interativo_ano <- ggplot(
  dados_ano,
  aes(x = Ano, y = n)
) +
  geom_line() +
  geom_point() +
  labs(
    title = "Quantidade de avaliações por ano",
    x = "Ano",
    y = "Quantidade"
  )

ggplotly(grafico_interativo_ano)

O gráfico interativo facilita a exploração do crescimento das avaliações ao longo dos anos, permitindo visualizar os valores de cada ponto com mais facilidade.

5. Conclusão

O objetivo deste trabalho foi investigar quais características podem estar relacionadas à utilidade das avaliações presentes no conjunto Amazon Fine Food Reviews Dataset.

Por meio da importação, limpeza, transformação e análise exploratória dos dados, foi possível identificar padrões relevantes no comportamento das avaliações dos usuários. Os resultados mostraram que a maioria das reviews possui caráter positivo, com predominância de notas altas ao longo de todo o período analisado.

Também foi observado um crescimento expressivo no volume de avaliações ao longo dos anos, refletindo a expansão do comércio eletrônico e da participação dos consumidores em plataformas digitais.

Em relação ao problema central do trabalho, os resultados indicam que avaliações mais detalhadas tendem a apresentar maiores níveis de utilidade. Tanto os gráficos quanto as estatísticas descritivas sugerem que comentários mais extensos fornecem informações mais relevantes para outros consumidores, aumentando a probabilidade de receber votos positivos de utilidade.

Além disso, verificou-se que a utilidade de uma avaliação não depende exclusivamente da nota atribuída ao produto. Avaliações positivas, neutras ou negativas podem ser consideradas úteis desde que apresentem informações claras, detalhadas e relevantes para outros usuários.

Dessa forma, conclui-se que a qualidade e o nível de detalhamento do conteúdo textual são fatores importantes para a percepção de utilidade das avaliações em plataformas de comércio eletrônico.