[R, Визуализация данных, Аналитика мобильных приложений, Управление продажами] R в руках маркетолога. Делаем когортный анализ своими руками

Автор Сообщение
news_bot ®

Стаж: 6 лет 9 месяцев
Сообщений: 27286

Создавать темы news_bot ® написал(а)
02-Май-2021 13:33

В маркетинге очень популярен когортный анализ. Его популярность вызвана, скорее всего, легкостью алгоритма и вычислений. Никаких серьезных математических концепций в основе нет, элементарная математика, выполняемая в excel. С точки зрения получения инсайтов гораздо интереснее анализ дожития.
Тем не менее, считаем, что есть такая задача и ее надо решить. Искать какие-либо пакеты и готовые функции неинтересно — математика проста, параметров настройки масса. Ниже возможный пример реализации (без особой фиксации на скорость исполнения), всего кода на пару десятков строк.
Является продолжением серии предыдущих публикаций.
Немного кода
При создании тестового набора мы можем особо не акцентироваться на временнЫх зонах, все равно данные случайные.

Создание тестового набора

SPL
# генерируем данные на 15 недель
set.seed(42)
events_dt <- tibble(user_id = 1000:9000) %>%
  mutate(birthday = Sys.Date() + as.integer(rexp(n(), 1/10))) %>%
  rowwise() %>%
  mutate(timestamp = list(as_datetime(birthday) + 24*60*60 * (
     rexp(10^3, rate = 1/runif(1, 2, 25))))) %>%
  ungroup() %>%
  unnest(timestamp) %>%
  # режем длинные хвосты в прошлом и в будущем
  filter(timestamp >= quantile(timestamp, probs = 0.1),
         timestamp <= quantile(timestamp, probs = 0.95)) %>%
  mutate(date = as_date(timestamp)) %>%
  select(user_id, date) %>%
  setDT(key = c("user_id", "date")) %>%
  # оставим только уникальные по датам события
  unique()

Посмотрим на получившееся интегральное распределение
ggplot(events_dt, aes(date)) +
  geom_histogram()


Шаг 1. Формируем справочник пользователей
В настоящем примере справочник будет тривильным и содержит только "дату рождения", т.е. дату, когда мы первый раз встретились с ним. Установка ключей для data.table объекта приводит к физической сортировке этих данных в порядке появления ключей.

Формируем справочник пользователей

SPL
users_dict <- events_dt[, .(birthday = head(date, 1)), by = user_id] %>%
  # для последующей сортировки оставим дату начала недели
  .[, week_start := floor_date(.BY[[1]], unit = "week"), by = birthday] %>%
    # переведем даты рождения в номера когорт
  .[, cohort := stri_c(
        lubridate::isoyear(.BY[[1]]),
        sprintf("%02d", lubridate::isoweek(.BY[[1]])),
        sep = "/"), by = week_start]
# посмотрим на распределение дат, нам нужен разброс для красивой картинки
as_tibble(janitor::tabyl(users_dict, birthday))


Шаг 2. Подготовим разметку в терминах когортного анализа
Совсем за скоростью пока не гонимся.
Составим справочник когорт. Для сокращения преобразований и обеспечения последующей сортировки.

Строим когортное представление в data.frame

SPL
cohort_dict <- unique(users_dict[, .(cohort, week_start)])
cohort_tbl <- users_dict[events_dt, on = "user_id"] %>%
  # посчитаем удаленность событий от даты рождения в терминах недель
  .[, rel_week := floor(as.numeric(difftime(date, birthday, units = "week")))] %>%
  # оставим только 10 недель
  .[rel_week <= 9] %>%
  # редуцируем до уникальных пользователей
  unique(by = c("user_id", "cohort", "rel_week")) %>%
  # считаем агрегаты в терминах когорт и недель
  .[, .N, by = .(cohort, rel_week)] %>%
  .[, rate := N/max(N), by = cohort]

Шаг 3. Визуализируем
Вариант 1. ggplot

Визуализация ggplot

SPL
# вариант ggplot
data_tbl <- cohort_tbl %>%
  # вернем числовые показатели когорт для сортировки
  left_join(cohort_dict)
data_tbl %>%
  mutate(cohort_group = forcats::fct_reorder(cohort, week_start, .desc = TRUE)) %>%
  ggplot(mapping = aes(x = rel_week, y = cohort_group, fill = rate)) +
  geom_tile()  +
  geom_text(aes(label = N), colour = "darkgray") +
  labs(x = "Недели существования когорты",
       y = "Неделя появления когорты",
       fill = "Количество\nпользователей",
       title = "graph_title") +
  scale_fill_viridis_c(option = "inferno") +
  scale_x_continuous(breaks = scales::breaks_width(1)) +
  theme_minimal() +
  theme(panel.grid = element_blank())


Вариант 2. gt
Для оформления используем тот факт, что у нас всегда по две строки на когорту и они отсортированы в нужном порядке.

Визуализация gt

SPL
# подготовим табличку-подложку
data_tbl <- cohort_tbl %>%
  pivot_longer(cols = c(N, rate)) %>%
  pivot_wider(names_from = rel_week, values_from = value) %>%
  # вернем числовые показатели когорт для сортировки
  left_join(cohort_dict) %>%
  arrange(week_start, desc(name))
odd_rows <- seq(1, to = nrow(data_tbl), by = 2)
even_rows <- seq(2, to = nrow(data_tbl), by = 2)
tab <- data_tbl %>%
  mutate(cohort = if_else(rep(c(TRUE, FALSE), length.out = nrow(.)),
                          cohort, "")) %>%
  select(-name, -week_start) %>%
  gt(rowname_col = "cohort") %>%
  fmt_percent(columns = matches("[0-9]+"),
              rows = odd_rows,
              decimals = 0, pattern = "<big>{x}</big>") %>%
  fmt_missing(columns = everything(),
              missing_text = "---") %>%
  tab_stubhead(label = "Неделя появления когорты") %>%
  tab_spanner(label = "Неделя существования когорты",
              columns = everything()) %>%
  tab_header(title = "Развертка") %>%
  data_color(columns = everything(),
             colors = scales::col_numeric(palette = "inferno",
                                          domain = c(0, 1),
                                          alpha = 0.6,
                                          na.color = "lightgray")) %>%
  tab_options(
    table.font.size = "smaller",
    data_row.padding = px(1),
    table.width = pct(75)
  ) %>%
  tab_style(
    style = list(
      cell_fill(color = "white"),
      cell_text(style = "italic"),
      cell_borders(sides = "bottom")
    ),
    locations = cells_body(
      columns = everything(),
      rows = even_rows)
  ) %>%
  tab_style(
    style = list(
      cell_borders(sides = "top")
    ),
    locations = cells_body(
      columns = everything(),
      rows = odd_rows)
  )
tab


Каркас приведен, прочее каждый может модифицировать под себя.
Предыдущая публикация — «R и работа со временем. Что за кулисами?».
===========
Источник:
habr.com
===========

Похожие новости: Теги для поиска: #_r, #_vizualizatsija_dannyh (Визуализация данных), #_analitika_mobilnyh_prilozhenij (Аналитика мобильных приложений), #_upravlenie_prodazhami (Управление продажами), #_marketing (маркетинг), #_data_science, #_kogortnyj_analiz (когортный анализ), #_vizualizatsija_dannyh (визуализация данных), #_r, #_vizualizatsija_dannyh (
Визуализация данных
)
, #_analitika_mobilnyh_prilozhenij (
Аналитика мобильных приложений
)
, #_upravlenie_prodazhami (
Управление продажами
)
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 22-Ноя 16:09
Часовой пояс: UTC + 5