L2P2 - Antonio Esteves

Explorando e Inferindo dados das Sessões, Buscas e Navegações da Wikimedia

Neste relatório, usa-se a exploração de dados da Wikimedia Foundation, apresentando conclusões de inferências estatísticas sobre o dataset disponibilizado por eles e seguindo instruções da tarefa original, respondendo as quatro perguntas elencadas na mesma.

  1. Qual é a nossa taxa de cliques geral diária? Como isso varia entre os grupos?

  2. Quais resultados as pessoas tendem a tentar primeiro? Como isso muda no dia-a-dia?

  3. Qual é a nossa taxa de resultados zero no geral? Como isso varia entre os grupos?

  4. A duração da sessão é aproximadamente o tempo entre o primeiro e o último evento de uma sessão. Escolha uma variável do conjunto de dados e descreva sua relação com o tamanho da sessão. Visualize o relacionamento.

  5. Resuma suas descobertas em um resumo executivo.

Nas seções um e dois estão as bibliotecas utilizadas e o os dados utilizados na análise. Na seção 3 estão as respostas para as perguntas elencadas no relatório e na última seção estão as conclusões obtidas das análises sobre os dados.

1. Importando as bibliotecas utilizadas.

library(tidyverse)
## Registered S3 methods overwritten by 'ggplot2':
##   method         from 
##   [.quosures     rlang
##   c.quosures     rlang
##   print.quosures rlang
## Registered S3 method overwritten by 'rvest':
##   method            from
##   read_xml.response xml2
## ── Attaching packages ──────────────────────────────────────────────────────────────────────────────── tidyverse 1.2.1 ──
## ✔ ggplot2 3.1.1       ✔ purrr   0.3.2  
## ✔ tibble  2.1.1       ✔ dplyr   0.8.0.1
## ✔ tidyr   0.8.3       ✔ stringr 1.4.0  
## ✔ readr   1.3.1       ✔ forcats 0.4.0
## ── Conflicts ─────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following object is masked from 'package:base':
## 
##     date
library(here)
## here() starts at /Users/toni/Git/l1p2-toniesteves
## 
## Attaching package: 'here'
## The following object is masked from 'package:lubridate':
## 
##     here
library(ggbeeswarm)
library(gridExtra)
## 
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
## 
##     combine

2. Lendo dataset de buscas para análise.

buscas = read_csv("../data/search_data.csv")
## Parsed with column specification:
## cols(
##   session_id = col_character(),
##   search_index = col_double(),
##   session_length = col_double(),
##   session_start_timestamp = col_double(),
##   session_start_date = col_datetime(format = ""),
##   group = col_character(),
##   results = col_double(),
##   num_clicks = col_double(),
##   first_click = col_double()
## )

2.1 Tratamento dos dados

glimpse(buscas)
## Observations: 136,234
## Variables: 9
## $ session_id              <chr> "0000cbcb67c19c45", "0001382e027b2ea4", …
## $ search_index            <dbl> 1, 1, 1, 1, 2, 3, 4, 5, 6, 1, 1, 2, 1, 1…
## $ session_length          <dbl> 0, 303, 435, 58, 58, 58, 58, 58, 58, 0, …
## $ session_start_timestamp <dbl> 2.016030e+13, 2.016031e+13, 2.016031e+13…
## $ session_start_date      <dttm> 2016-03-03 15:20:45, 2016-03-07 08:49:5…
## $ group                   <chr> "b", "b", "b", "a", "a", "a", "a", "a", …
## $ results                 <dbl> 20, 18, 20, 20, 20, 20, 20, 20, 20, 1, 0…
## $ num_clicks              <dbl> 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0…
## $ first_click             <dbl> NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA…

Para uma análise melhor, foram realizados alguns tratamento nos dados. Inicialmente separamos os dados de forma a compilar apenas as datas que foram efetuadas buscas. Tratamentos específicos são realizados para cada sessão.

search_dates <- buscas %>% 
  mutate(search_date = format(session_start_date, "%d-%m-%Y"))

glimpse(search_dates)
## Observations: 136,234
## Variables: 10
## $ session_id              <chr> "0000cbcb67c19c45", "0001382e027b2ea4", …
## $ search_index            <dbl> 1, 1, 1, 1, 2, 3, 4, 5, 6, 1, 1, 2, 1, 1…
## $ session_length          <dbl> 0, 303, 435, 58, 58, 58, 58, 58, 58, 0, …
## $ session_start_timestamp <dbl> 2.016030e+13, 2.016031e+13, 2.016031e+13…
## $ session_start_date      <dttm> 2016-03-03 15:20:45, 2016-03-07 08:49:5…
## $ group                   <chr> "b", "b", "b", "a", "a", "a", "a", "a", …
## $ results                 <dbl> 20, 18, 20, 20, 20, 20, 20, 20, 20, 1, 0…
## $ num_clicks              <dbl> 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0…
## $ first_click             <dbl> NA, 1, 1, NA, NA, NA, NA, NA, NA, NA, NA…
## $ search_date             <chr> "03-03-2016", "07-03-2016", "05-03-2016"…

2.2 Variáveis Utilizadas nas análises

As variáveis utilizadas podem serem vistas abaixo:

group : Um marcador (“a” ou “b”);

results : Número de ocorrências retornadas para o usuário;

num_clicks: Número de ocorrências clicadas pelo usuário;

first_click: Posição da ocorrência que o usuário clicou primeiro;

session_start_date: Data do início da pesquisa;

session_length: Duração da sessão.

search_index : Um contador de buscas em uma mesma sessão ordenado cronologicamente

3. Respostas e Análise exploratória de dados.

3.1 Qual é a taxa de cliques geral diária? Como isso varia entre os grupos?

Para responder a essa pergunta, foi efetuado um tratamento nos dados de forma a remover incialmente resultados nulos e resultados onde o primeiro clique, por motivos desconhecidos são maiores que a quantidade de resultados retornardos na busca. Outro ponto a que merece destaque, é que o dia 08/03 apenas possui registros até as 20h. Desta forma optou-se por remover esses dias do cálculo da taxa geral de cliques de forma a obter um resultado mais coeso.

A taxa de cliques geral é bem baixa, mais ainda no dia 05 de Março.

clicked = search_dates %>%
  filter((num_clicks > 0) & (first_click <= results) & (results > 0) & (search_date != "08-03-2016")) %>%
  group_by(search_date)

per_date = clicked %>% 
  summarize(total_clicks = n(), clickthrough_rate = (total_clicks/nrow(search_dates)))

per_date %>%
  ggplot(aes(x=search_date,y=clickthrough_rate)) + 
  geom_point(
    color="#44cde8",
    size=3
  ) + 
  geom_line(aes(group=1),linetype='dotted') +
  labs(
      title = "Figura 1 - Taxa de Cliques Geral Diária", 
      x = "Data de Acesso.", 
      y = "Taxa Geral de Cliques",
      subtitle = "Taxa de cliques para datas em que ocorreram buscas."
      )

O detalhamento da taxa de cliques geral comparado por grupos também é bem baixa. No entanto o grupo que utilizou o algoritmo de busca B, ainda que com uma taxa menor, apresenta uma taxa mais constante que o grupo que utilizou o algoritmo de busca A. Diferentemente do algoritmo de busca A o algoritmo B não apresenta uma redução de taxa significativa para o dia 05 de Março. Talvez um problema bastante especifico do algoritmo ou do grupo em questão.

clicked = search_dates %>%
  filter((num_clicks > 0) & (first_click <= results) & (results > 0) & (search_date != "08-03-2016")) %>%
  group_by(search_date, group)

per_date = clicked %>% 
  summarize(total_clicks = n(), clickthrough_rate = (total_clicks/nrow(search_dates)))

per_date %>%
  group_by(group) %>% 
  ggplot(aes(x=search_date,y=clickthrough_rate)) + 
  geom_point(
    aes(color=group),
    size=3
  ) + 
  scale_color_manual(values=c("#6ab3a2", "brown")) +
  geom_line(aes(group=group),linetype='dotted') +
  labs(
      title = "Figura 2 - Variação da Taxa de Cliques Geral Diária Entre Grupos", 
      x = "Data de Acesso.", 
      y = "Taxa Geral de Cliques",
      subtitle = "Taxa de cliques para datas para datas em que ocorreram buscas.",
      color = "Grupo")

3.2 Quais resultados as pessoas tendem a tentar primeiro? Como isso muda no dia-a-dia?

Para identificar a preferência dos usuários dentre os resultados retornardos na busca, inicialmente foram removidos registros de cliques nulos e invalidos bem como o dia 08 de Março.

search_dates %>% 
  filter((!is.na(first_click)) & (first_click != 0) & (search_date != "08-03-2016")) %>%
  ggplot(aes(x=first_click)) + 
  geom_bar(color = "black") + 
  scale_x_log10() +
  labs(
      title = "Figura 3 - Preferência do Primeiro Acesso Entre os Resultados",
      x = "Resultados Acessados", 
      y = "Quantidade de Acessos", 
      subtitle = "Distribuição para datas para datas em que ocorreram buscas."
      )

A distribuição mostra-se assimétrica uma grande cauda a direita, além disso aparentemente o comportamento mais comum dos usuários é acessar o primeiro link.

Abaixo uma distribuição mais granularizada é possível observar o a quantidade de acessos para o primeiro clique nas datas em que ocorreram buscas.

search_dates %>%
  arrange(search_date)%>%
    ggplot(aes(x = first_click, fill = search_date)) +
    geom_histogram(binwidth = 2, na.rm = TRUE) +
    scale_x_continuous(limits=c(0, 30)) +
    scale_y_continuous(limits=c(0, 1000)) +
    facet_wrap(~ search_date, nrow=2) +
    labs(
      title = "Figura 4 - Link do Primeiro Acesso Entre os Resultados", 
      x = "Resultado Acessado.", 
      y = "Quantidade de Acesso",
      subtitle = "Resultados primeiramente acessados para datas que ocorreram buscas.",
      fill = "Data da busca")

O dia 07 de Março a incidencia de primeiros cliques aparentemene mostrou-se maior. É constante o fato do usuário clicar no primeiro link na maioria dos dias ou emalgum link que pertence aos 10 primeiros resultados.

3. Qual é a nossa taxa de resultados zero no geral? Como isso varia entre os grupos?

Para responder esse questionamento, foram considerados apenas valores iguais a 0. Com isso, na Figura 5 exibe a distribuição de zeros nos resultados por data de ocorrência. Baseado nas questões já respondidas é possível notar também que a taxa da ocorrência de buscas sem resultado consegue ser maior que a taxa geral de cliques.

no_results = search_dates %>%
  filter((results > 0)) %>%
  group_by(search_date)

no_results_per_date = no_results %>%
  summarize(total_no_results = n(), no_results_rate = (total_no_results/nrow(search_dates)))

no_results_per_date %>%
  ggplot(aes(x=search_date,y=no_results_rate)) +
  geom_point(
    color="#44cde8",
    size=3
  ) +
  geom_line(aes(group=1),linetype='dotted') +
  labs(
      title = "Figura 5 - Taxa Geral Diária de Buscas sem Resultados ",
      x = "Data de Acesso.",
      y = "Taxa Geral de Cliques",
      subtitle = "Taxa de cliques para datas em que ocorreram buscas."
      )

A variação da taxa de buscas sem resultado para cada grupo é demonstrada abaixo. Novamente é possível observar a amplitude dos dados no dia 05 de Março para o grupo que utilizou o algoritmo de busca A.

no_results = search_dates %>%
  filter((results > 0)) %>%
  group_by(search_date, group)

no_results_per_date = no_results %>%
  summarize(total_no_results = n(), no_results_rate = (total_no_results/nrow(search_dates)))

no_results_per_date %>%
  group_by(group) %>% 
  ggplot(aes(x=search_date,y=no_results_rate)) + 
  geom_point(
    aes(color=group),
    size=3
  ) + 
  scale_color_manual(values=c("orange", "navy blue")) +
  geom_line(aes(group=group),linetype='dotted') +
  labs(
      title = "Figura 6 - Variação da Taxa Geral Diária de Buscas sem Resultados Entre Grupos", 
      x = "Data de Acesso.", 
      y = "Taxa Geral de Cliques",
      subtitle = "Taxa de cliques para datas para datas em que ocorreram buscas.",
      color = "Grupo")

4. A duração da sessão é aproximadamente o tempo entre o primeiro e o último evento de uma sessão. Escolha uma variável do conjunto de dados e descreva sua relação com o tamanho da sessão. Visualize o relacionamento.

Optou-se por comparar o tempo de sessão com a quantidade de buscas em uma mesma sessão. Interessante notar que a quantidade de buscas efetuadas para aqueles que utilizaram o algoritmo de busca A é muito maior que os que utilizaram o algortimo B. Talvez esse efeito se deve a algum fator ineficiente do algorítmo (delay, resultados errados, etc)

search_by_min = buscas %>% 
  mutate(session_length_min = session_length/60)

search_by_min %>%
  ggplot(mapping = aes(x = session_length_min, y = search_index, color=group)) +
  scale_color_manual(values=c("orange", "#68B3A2")) +
  geom_point(alpha = 0.3, na.rm = TRUE) + 
  scale_x_continuous(limits=c(0,1000)) +
  facet_wrap(~group)+
  labs(
      title = "Figura 7 - Índice do click em relação a Duração da seção", 
      x = "Duração da seção (Min)",
      y = "Buscas Efetuadas em uma Mesma Sessão",
      subtitle = "Taxa de cliques para datas para datas em que ocorreram buscas.",
      color = "Grupo"
      )

4. Resultados e Conclusões

Sabe-se que a média geral de clicks é maior para o grupo A. Assim, como o número de ocorrências é maior para esse grupo (Figura 2), visto isso, aparentemente o algoritmo do grupo A foi utilizado com muito mais intensidade ou é mais eficiente de fato.

Em relação em qual link o usuário clica primeiro, verificamos (Figura 3 e Figura 4) que os mesmos clicam pela primeira vez, na maioria das vezes, entre os primeiros 10 links retornados. Em relação aos grupos, praticamente, o A e o B têm taxas bem diferentes (Figura 4). É possível observar ainda que o algorítmo A apresenta uma queda acentuada no dia 05 de Março que também é replicada na taxa geral de cliques (Figura 1)

Por fim, relacionamos a variável duração da sessão com a quantidade de buscas efetuadas na sessão e observamos que, para o grupo B a sequencia de buscas por sessão é bem menor do que para o grupo A, além de sessões com pouca duração (Figura 7).