Собесов

Кейс — анализ датасета интернет-компании на Python

Кейсы и метрикиEDA и аналитикаСредняяMiddle

Условие

Дан датасет интернет-компании. Загрузить в Python/R, ознакомиться, ответить:

  • a. Какой рекламный канал принёс больше всего дохода за всё время?
  • b. Как изменился средний чек транзакции после введения коронавирусных ограничений? Как он изменился для пользователей с промокодом и без (promo_activated)?
  • c. Можно ли с уверенностью 95% сказать, что CR (конверсия в транзакцию) в выходные дни отличается от CR в будни?
  • d. Спрогнозировать выручку с пользователей, приведённых контекстной рекламой (medium=cpc) на полгода вперёд. Описать подход и какие ещё данные понадобятся.
  • e. Если что-то ещё интересного в данных — рассказать.

Решение

a. Лучший рекламный канал

import pandas as pd
 
df = pd.read_csv("realweb_dataset.csv", parse_dates=["date"])
revenue_by_channel = (df[df["transaction_id"].notna()]
                      .groupby("source_medium")["revenue"]
                      .sum()
                      .sort_values(ascending=False))
print(revenue_by_channel.head(10))

Что важно проверить:

  • Различать доход (выручка) и транзакции (число заказов).
  • Один пользователь = один канал? Или у пользователя может быть несколько касаний? Нужна атрибуция (last-click обычно по умолчанию).
  • Учитывать только успешные транзакции (если есть статус).
  • Если в датасете несколько источников per session — фильтровать дубликаты.

Ответ — название канала с максимальным sum(revenue) и его доля в общем revenue.

b. Средний чек до/после COVID

«Введение коронавирусных ограничений в России» — обычно 2020-03-30. Уточнить дату по контексту датасета.

covid_start = "2020-03-30"
 
trx = df[df["transaction_id"].notna()].copy()
trx["period"] = (trx["date"] >= covid_start).map({True: "after", False: "before"})
 
aov_overall = trx.groupby("period")["revenue"].mean()
aov_by_promo = trx.groupby(["period","promo_activated"])["revenue"].mean().unstack()
print(aov_overall, aov_by_promo, sep="\n")

Дополнительно:

  • Тест статистической значимости разницы: t-test (Welch) или bootstrap для разности средних.
  • График: AOV по неделям (resample('W').mean()) с маркером даты ограничений.
  • Для аккуратности — учесть выбросы (clip 99-й перцентили) или использовать медиану вместо среднего.

c. CR в будни vs выходные

CR обычно = transactions / sessions (или users). Нужны не только транзакции, но и сессии без транзакций — то есть знаменатель.

df["dow"] = df["date"].dt.dayofweek         # 0=Пн ... 6=Вс
df["is_weekend"] = df["dow"].isin([5, 6])
 
agg = df.groupby("is_weekend").agg(
    sessions=("session_id","nunique"),
    transactions=("transaction_id", lambda s: s.notna().sum())
)
agg["cr"] = agg["transactions"] / agg["sessions"]
print(agg)

Тест: z-test для двух пропорций (или хи-квадрат).

from statsmodels.stats.proportion import proportions_ztest
 
count = agg["transactions"].values
nobs  = agg["sessions"].values
stat, pval = proportions_ztest(count, nobs)
print(f"z={stat:.3f}, p={pval:.4f}")

Если p < 0.05 — отвергаем H0 (CR одинаков). С 95%-уверенностью различие значимо.

Подвох: независимость наблюдений. Если один пользователь делает много сессий и в будни, и в выходные — это нарушает условия теста. Лучше делать тест на уникальных пользователях или использовать кластерный bootstrap.

d. Прогноз выручки с CPC на полгода

Формальный подход:

  1. Декомпозируем будущую выручку: Revenue = Users(cpc) × CR × AOV × repeat_factor.
  2. Прогноз каждого фактора:
    • Users(cpc) — динамика приведённых cpc-пользователей: ARIMA / Prophet / экспоненциальное сглаживание + сезонность по неделям.
    • CR(cpc) — тренд за последние месяцы, экстраполяция (если стабильно).
    • AOV(cpc) — аналогично.
    • Repeat factor — доля выручки от повторных покупок (если в датасете есть user_id и история).
  3. Итог = произведение прогнозов с интервалами (через bootstrap или MC).

Какие ещё данные нужны

  • Маркетинговый бюджет на cpc (план на 6 месяцев) — без него прогноз делается «при текущем темпе расходов».
  • CPC и CPI — чтобы понимать, останется ли стоимость пользователя стабильной.
  • Промо-календарь — крупные распродажи смещают AOV и CR.
  • Сезонность — нужен исторический ряд хотя бы 18–24 месяца (для годовой сезонности).
  • Cohort retention — повторные покупки сильно влияют на 6-месячный horizon.
  • Внешние факторы — конкуренция (CPM-индексы), макроэкономика.

Альтернативы

  • Time-series модель напрямую на revenue(cpc) — Prophet с сезонностью и changepoints. Проще, но не позволяет анализировать «почему».
  • Marketing Mix Model (MMM) — если есть бюджет, делает прогноз revenue от расходов с учётом adstock + saturation.

e. Что ещё интересного

Что часто всплывает в подобных датасетах:

  • Распределение AOV — heavy tail, нужны медиана / P95.
  • Cannibalization промокодов: пользователи с промо имеют выше частоту, но ниже маржу.
  • Day of week × Hour heatmap для трафика и конверсий.
  • Воронка mediums — organic приносит много сессий, cpc — много транзакций.
  • Когортное удержание по acquisition channel — некоторые каналы дают «одноразовых».

Подводные камни

  1. Атрибуция. «Доход с канала» меняется в 2–3 раза в зависимости от модели атрибуции (last-click vs first-click vs data-driven). Уточнить у заказчика.
  2. Дата COVID. Без явной даты исследование «до/после» бессмысленно. В разных странах введения было в разные дни.
  3. AOV среднее vs медиана. Heavy tail искажает среднее.
  4. CR = трансакции / сессии, не «трансакции / пользователи». Нужно понимать, что есть в данных.
  5. Тест значимости с зависимостями. Один пользователь имеет много сессий, нарушение iid. Лучше cluster-bootstrap.
  6. Прогноз на полгода. Линейная экстраполяция тренда — наивная база. Лучше Prophet/ARIMA с сезонностью + предупредить, что 6 мес — длинный horizon, доверие низкое.
  7. CPC ≠ paid social ≠ display. В колонке medium могут быть и cpc, и cpa, и cpm. Уточнить, что именно фильтровать.

Эталонный ответ

  • a. Канал с максимальным sum(revenue) среди транзакционных строк, с поправкой на single-attribution.
  • b. Сравнение AOV до/после 2020-03-30 overall и по promo_activated. Статтест на разности средних. Также — взгляд на медиану.
  • c. Z-тест для двух пропорций по CR(weekend) vs CR(weekday). Если p < 0.05 — различие значимо. Учесть зависимость наблюдений (cluster-bootstrap).
  • d. Прогноз раскладывается как Users × CR × AOV × repeat, каждый компонент моделируется (Prophet/ARIMA), CI через MC. Дополнительно нужны: маркетинг-бюджет, промо-календарь, история ≥ 1.5 года, retention-данные.
  • e. Распределения AOV (медиана), пересечение каналов и промо, weekday × hour heatmap, когорты по каналу.

Хочешь увидеть разбор?

Зарегистрируйся бесплатно — откроется развёрнутое решение этой задачи и ещё 4 на выбор.

Зарегистрироваться и увидеть разбор
Уже есть аккаунт? Войти