1 Introdução

Esta análise é realizada sobre dos dados coletados pela pesquisa explicada em mais detalhes no seguinte artigo. Basicamente os grupos de usuários foram apresentados a um aplicativo de reprodução de músicas em várias etapas, de forma que em casa etapa houvesse uma nova funcionalidade no aplicativo. Começando o experimento com baseline que era a versão mais simples do aplicativo, e em seguida adicionando três funcionalidades de forma gradativa, sendo elas: like/dislike, up/downvoting e skip, respectivamente. Cada uma das funcionalidades foi testada primeiramente sozinha, ou seja, sem a presença das outras, e posteriormente, todas foram testadas juntas.

1.1 O que será analisado?

A análise busca entender como foi a evolução das avaliações do aplicativo ao longo do experimento, de acordo com a chegada de novas funcionalidades. O csv com os dados coletados se encontra no seguinte link. Vamos observar os atributos que vamos analisar a seguir.

glimpse(dados)
## Rows: 115
## Columns: 4
## $ user_id      <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 1…
## $ satisfaction <dbl> 2.0, 3.0, 1.5, 1.0, 2.0, 2.5, 2.0, 3.0, 2.0, 2.0, 2.0, 2…
## $ scenario     <chr> "baseline", "baseline", "baseline", "baseline", "baselin…
## $ group        <dbl> 3, 1, 2, 2, 1, 1, 3, 3, 2, 1, 3, 2, 3, 1, 3, 1, 1, 3, 3,…

Como pode ser observado acima, nossos dados possuem quatro atributos: user_id que identifica cada usuário, satisfaction que corresponde as notas que os usuários atribuiuram ao aplicativo, scenario que indica em que fase experimento se encontrava, ou seja, qual funcionalidade estava disponível no aplicativo e por fim group que indica a qual dos grupos de pessoas o usuário em questão pertence.

2 Início das análises

dados %>%
    ggplot(aes(x = satisfaction)) + 
    geom_histogram(binwidth = 1, boundary = 0, fill = "darkblue") + 
    facet_wrap(~ scenario) + 
    labs(title = "Funcionalidades da Jukebox",
         subtitle = "Dados das votações de cada funcionalidade", 
         y = "Quantidade de votos",
         x = "Satisfação")

No gráfico acima, já podemos ter uma ideia dos resultados obtidos com cada uma das funcionalidades da Jukebox. É possível observar por exemplo, que as avaliações mais baixas correspondem a baseline e a skip, enquanto que combined e up/downvoting parecem ter as maiores avaliações.

library(DT)
table = dados %>%
    group_by(scenario) %>%
    summarise(media_satisfacao = mean(satisfaction),
              mediana_satisfacao = median(satisfaction),
              desvio_padrao_satisfacao = sd(satisfaction))

datatable(head(table),
  options = list(pageLength = 5, dom = 'tip'), rownames = FALSE)

Na tabela acima, podemos analisar os resultados da média, mediana e desvio padrão da variável satisfaction, agrupados por scenario. Podemos ver que as médias e as medianas de cada um dos cenários é bem próxima, ou seja, não há muitos valores destoantes nos grupos. Podemos confirmar isso, observando que o desvio padrão dos dados é baixo.

3 Comparações entre as funcionalidades

Sabendo que as funcionalidades like/dislike, up/downvoting e skip foram apresentadas nessa ordem respectivamente. Pensei em analisar a evolução das avaliações gradativamente ao longo do experimento, começando com o baseline.

3.1 Diferença entre baseline e like/dislike

A funcionalidade like/dislike forneceu aos usuários da Jukebox a possibilidade de curtir ou descurtir determinada música. Sabendo que like/dislike foi apresentada após o uso da versão sem funcionalidades especiais (baseline), podemos concluir que fazendo a diferença entre as médias desses dois cenários, podemos descobrir o quanto as avaliações melhoraram ou pioraram em média. Vejamos abaixo o resultado dessa diferença.

diferenca_baseline_likedislike = function(d, i) {
    media_satisfacao = d %>%
        slice(i) %>%
        group_by(scenario) %>%
        summarise(satisfacao_media = mean(satisfaction))
    
    baseline = media_satisfacao %>% 
        filter(scenario == "baseline") %>%
        pull(satisfacao_media)
    
    like_dislike = media_satisfacao %>% 
        filter(scenario == "like/dislike") %>%
        pull(satisfacao_media)
    
    like_dislike - baseline
}

theta_dif_baseline_likedislike = diferenca_baseline_likedislike(dados, 1:NROW(dados))

theta_dif_baseline_likedislike
## [1] 1.521739

Acima podemos ver o resultado da diferença (média(like/dislike) - média(baseline)), com esse resultado podemos concluir que houve uma grande melhora com adição da funcionalidade like/dislike, uma melhora considerável, de 1.52 em média.

library(boot)
ic_dif_baseline_likedislike = dados %>% 
    boot(statistic = diferenca_baseline_likedislike, R = 4000) %>% 
    tidy(conf.level = 0.95, 
         conf.int = TRUE)

ic_dif_baseline_likedislike
## # A tibble: 1 x 5
##   statistic       bias std.error conf.low conf.high
##       <dbl>      <dbl>     <dbl>    <dbl>     <dbl>
## 1      1.52 -0.0000827     0.178     1.18      1.88

Acima podemos ver o intervalo onde temos 95% de confiança de que se encontra a diferença das médias dos cenários baseline e like/dislike.

ic_dif_baseline_likedislike %>%
    ggplot() +
    geom_pointrange(aes(
        x = "",
        y = statistic,
        ymin = conf.low,
        ymax = conf.high
    )) +
    ylim(0, 5) + 
    labs(title = "Intervalo de Confiança",
         subtitle = "Intervalo referente a diferença das médias de baseline e like/dislike",
         x = "",
         y = "Escala de Satisfação") +
    coord_flip()

No gráfico acima, podemos ver com mais clareza que realmente houve uma diferença considerável e positiva, mesmo que o valor esteja na margem inferior do intervalo de confiança mostrado, ela ainda é uma diferença considerável, pois ainda está acima de 1. Então podemos dizer que a funcionalidade like/dislike trouxe uma excelente evolução para o aplicativo.

3.2 Diferença entre like/dislike e up/downvoting

Após o período de uso da funcionalidade like/dislike, foi apresentada a funcionalidade up/downvoting que deu aos usuários a capacidade de definir a ordem em que as músicas são escutadas, modificando a fila de execução. Calculando a diferença entre a média dessa nova funcionalidade e a apresentada anteriormente (like/dislike), podemos ver o efeito dessa nova funcionalidade nas avaliações do aplicativo.

diferenca_likedislike_updown = function(d, i) {
    media_satisfacao = d %>%
        slice(i) %>%
        group_by(scenario) %>%
        summarise(satisfacao_media = mean(satisfaction))
    
    like_dislike = media_satisfacao %>% 
        filter(scenario == "like/dislike") %>%
        pull(satisfacao_media)
    
    updown = media_satisfacao %>% 
        filter(scenario == "up/downvoting") %>%
        pull(satisfacao_media)
    
     updown - like_dislike
}

theta_dif_likedislike_updown = diferenca_likedislike_updown(dados, 1:NROW(dados))

theta_dif_likedislike_updown
## [1] 0.7391304

Acima podemos ver o resultado da diferença (média(up/downvoting) - média(like/dislike)), com esse resultado podemos concluir que houve uma melhora com adição da funcionalidade up/downvoting, houve uma melhora de 0.73 em média nas avaliações, ou seja, essa funcionalidade subiu as avaliações de forma considerável.

library(boot)
ic_dif_likedislike_updown = dados %>% 
    boot(statistic = diferenca_likedislike_updown, R = 4000) %>% 
    tidy(conf.level = 0.95, 
         conf.int = TRUE)

ic_dif_likedislike_updown
## # A tibble: 1 x 5
##   statistic     bias std.error conf.low conf.high
##       <dbl>    <dbl>     <dbl>    <dbl>     <dbl>
## 1     0.739 -0.00412     0.151    0.435      1.03

Acima podemos ver o intervalo onde temos 95% de confiança de que se encontra a diferença das médias dos cenários like/dislike e up/downvoting.

ic_dif_likedislike_updown %>%
    ggplot() +
    geom_pointrange(aes(
        x = "",
        y = statistic,
        ymin = conf.low,
        ymax = conf.high
    )) +
    ylim(0, 5) + 
    labs(title = "Intervalo de Confiança",
         subtitle = "Intervalo referente a diferença das médias de like/dislike e up/downvoting",
         x = "",
         y = "Escala de Satisfação") +
    coord_flip()

No gráfico acima, podemos ver com mais clareza que realmente houve uma diferença positiva, mas que ela pode ser uma diferença considerável, chegando a ser maior que 1 ou pode ser mais próxima de 0, estando abaixo de 0.5. Então podemos dizer que a funcionalidade up/downvoting trouxe de fato uma evolução para o aplicativo, que pode ser considerável ou não.

3.3 Diferença entre up/downvoting e skip

Por fim, após o período de uso da funcionalidade up/downvoting, foi apresentada a ultima funcionalidade, skip que deu aos usuários a capacidade de pular as músicas. Calculando a diferença entre média dessa nova funcionalidade e a apresentada anteriormente (up/downvoting), podemos descobrir que efeito essa nova funcionalidade causou nas avaliações do aplicativo.

diferenca_updown_skip = function(d, i) {
    media_satisfacao = d %>%
        slice(i) %>%
        group_by(scenario) %>%
        summarise(satisfacao_media = mean(satisfaction))
    
    updown = media_satisfacao %>% 
        filter(scenario == "up/downvoting") %>%
        pull(satisfacao_media)
    
    skip = media_satisfacao %>% 
        filter(scenario == "skip") %>%
        pull(satisfacao_media)
    
     skip - updown
}

theta_dif_updown_skip = diferenca_updown_skip(dados, 1:NROW(dados))
theta_dif_updown_skip
## [1] -1.869565

Acima podemos ver o resultado da diferença (média(skip) - média(up/downvoting)), com esse resultado podemos concluir que houve uma piora considerável com adição da funcionalidade skip, houve uma piora de 1.86 em média nas avaliações, ou seja, essa funcionalidade fez com que as avaliações sofressem uma queda considerável.

library(boot)
ic_dif_updown_skip = dados %>% 
    boot(statistic = diferenca_updown_skip, R = 4000) %>% 
    tidy(conf.level = 0.95, 
         conf.int = TRUE)

ic_dif_updown_skip
## # A tibble: 1 x 5
##   statistic     bias std.error conf.low conf.high
##       <dbl>    <dbl>     <dbl>    <dbl>     <dbl>
## 1     -1.87 -0.00120     0.141    -2.16     -1.59

Acima podemos ver o intervalo onde temos 95% de confiança de que se encontra a diferença das médias dos cenários up/downvoting e skip.

ic_dif_updown_skip %>%
    ggplot() +
    geom_pointrange(aes(
        x = "",
        y = statistic,
        ymin = conf.low,
        ymax = conf.high
    )) +
    ylim(-5, 0) + 
    labs(title = "Intervalo de Confiança",
         subtitle = "Intervalo referente a diferença das médias de up/downvoting e skip",
         x = "",
         y = "Escala de Satisfação") +
    coord_flip()

No gráfico acima, podemos ver com mais clareza que realmente houve uma diferença considerável e negativa, mesmo que o valor esteja na margem superior do intervalo de confiança mostrado, ela ainda é uma diferença considerável, pois ainda está de -1.5 e pode ultrapassar a marca de -2. Então podemos dizer que a funcionalidade skip trouxe uma grande queda nas avaliações do aplicativa.

4 Conclusão

Com base na análise feita, foi possível concluir que a melhor funcionalidade apresentada foi up/downvoting, ela teve a maior média dentre todas as funcionalidades (4.39) e causou uma melhora considerável nas avaliações do aplicativo (0.73 em média) que já tinham melhorado bastante após o uso do like/dislike. Enquanto que a pior funcionalidade foi skip que causou uma grande queda nas avaliações (-1.86 em média), ela também foi a funcionalidade que teve o maior impacto, seguida por like/dislike que teve um impacto positivo de 1.52 em média nas avaliações.