Показаны сообщения с ярлыком lifetime. Показать все сообщения
Показаны сообщения с ярлыком lifetime. Показать все сообщения

воскресенье, 21 апреля 2024 г.

Vanity metrics: DAU, WAU, MAU

DAU, WAU и MAU малочувствительны к изменениям в продукте

dau_total = (
    sessions.groupby('session_date').agg({'client_id': 'nunique'}).mean()
)

wau_total = (
    sessions.groupby(['session_year', 'session_week'])
    .agg({'client_id': 'nunique'})
    .mean()
)

  • Sticky factor - DAU/WAU, DAU/MAU отражает регулярность использования сервиса или приложения 
  • Среднее количество сессий на пользователя за период (обычно берут в расчет месяц)
  • Средняя продолжительность сессии, average session length

sessions['session_duration_sec'] = (
    sessions['session_end_ts'] - sessions['session_start_ts']
).dt.seconds

print(sessions['session_duration_sec'].median()) #mean будет сильно сдвигаться за счет экстремально-длинных сессий
#желательно чтобы медиана была выше некоторого минимального значения (отказ пользователя)

# и распределение
sessions['session_duration_sec'].hist(bins=50)
plt.show() 

пятница, 19 апреля 2024 г.

LTV, CAC, ROI

  • Retention (Churn), Conversion - база для расчета
  • LTV, или Lifetime Value, — это «пожизненная ценность» клиента, то есть общая сумма денег, которую один клиент в среднем приносит компании со всех своих покупок. "В среднем" потому что вычисление происходит для когорты, вся выручка с когорты делится на размер когорты. В теории эта метрика включает все прошлые, нынешние и будущие покупки пользователя. На практике чаще анализируют LTV за определённый срок — первые 1, 3, 7 и 14 дней после регистрации. 
  • CAC, или Customer Acquisition Cost, — стоимость привлечения одного клиента. Сумма денег, в которую компании обходится каждый новый клиент. В сущности, CAC — это инвестиции в маркетинг. 
  • ROI, или Return On Investment, — окупаемость инвестиций. В экономике одного покупателя эта метрика показывает, на сколько процентов LTV превысил CAC. Ещё говорят: на сколько процентов «окупились» клиенты. (=LTV/CAC)
Иногда вместо LTV используют показатели ARPU или ARPPU
  • ARPU, или Average Revenue Per User, — это полный аналог LTV. Рассчитывается делением выручки с накоплением на размер когорты. 
  • ARPPU, или Average Revenue Per Paying User, — тот же LTV, но рассчитанный с учётом только платящих пользователей когорты. Выручку с накоплением делят на число пользователей, совершивших хотя бы одну покупку. За счёт исключения неплатящих пользователей ARPPU часто более показателен, чем ARPU, но считать его труднее: во-первых, число платящих в когорте со временем растёт, а во-вторых, для расчёта требуется больше данных о привлечённых пользователях.
Как проверить вычисления?
  • сумма размеров когорт равна числу новых пользователей за изучаемый период
  • сумма размеров платящих когорт равна числу покупателей за изучаемый период
  • retention rate убывает по экспоненциальному закону e^(-x/a), a - задает кривизну
  • retention rate неплатящих убывает быстрее, чем убывание платащих
  • retention rate не может быть отрицательным
  • conversion rate в когортном анализе никогда не снижается (плавно растущая функция) и не может превышать 100%; 1-e^-(x/a+b), a - кривизна, b - конверсия первого дня
  • количество новых покупателей равно числу новых клиентов умноженному на общую конверсию
  • CAC когорты постоянная величина для всех лайфтаймов
  • CAC умноженный на размер когорты должен быть равен рекламным затратам на изучаемом периоде
  • LTV никогда не снижаются (плавно растущая функция) 
  • LTV теоретически не ограничена сверху
  • Общая стоимость покупок клиентов когорты равна количеству этих клиентов умноженному на максимальных LTV
  • Если LTV и CAC рассчитаны верно это исключает ошибки в исходных данных и ROI скорее всего тоже рассчитан верно
  • Реалистичный ROI лежит в диапазоне от 0 до 3 (если ROI больше 300% это либо чудо либо ошибка)















понедельник, 18 марта 2024 г.

Lifetime

Время от момента регистрации пользователя продукта до момента наступления какого-то важного с точки зрения бизнеса события.
Lifetime = T - T0




# загружаем данные
data = pd.read_csv('flowers.csv')

# приводим столбцы к типу datetime (дата и время)
for c in ['install_dt', 'event_dt']: 
    data[c] = pd.to_datetime(data[c])

data['lifetime'] = data['event_dt'] - data['install_dt']

data['lifetime_sec'] = (data['event_dt'] - data['install_dt']).dt.total_seconds()
data['lifetime_days'] = (data['event_dt'] - data['install_dt']).dt.days
# недели
data['lifetime_weeks'] = (data['event_dt'] - data['install_dt']) / np.timedelta64(1, 'W')
# месяцы
data['lifetime_months'] = (data['event_dt'] - data['install_dt']) / np.timedelta64(1, 'M')
# года
data['lifetime_years'] = (data['event_dt'] - data['install_dt']) / np.timedelta64(1, 'Y')



Используется для:
  • сегментации пользователей "по возрасту" (масштаб дни... месяцы...)
  • first user experience (масштаб секунды... минуты...)
  • когортный анализ (первые и повторные покупки)
выбор шкалы времени зависит от специфики продукта, например для интернет магазинов это м.б. месяцы; для онлайн образования масштаб шкалы примерно соответствует длине спринта, около 1-2 недель; для мобильных игр и приложений это могут быть дни и недели;

Классы задач (примеры):
  • доля старых пользователей во всех пользователях (соотношение старый и новый, при этом старый/новый могут определяться по разному)
  • различия в монетизации для старых/новых пользователей, например средний чек
  • отвал пользователей в приложении или онлайн игре, можно локализовать время максимального оттока пользователей
  • изучение пользователей возобновляющих подписку к каждом периоде с момента регистрации




воскресенье, 17 марта 2024 г.

Что необходимо для выделения когорты

  • изначально объединяющее событие (первое посещение сайта, регистрация или скачивание мобильного приложения. Так в анализ попадает только определённая категория людей — впервые посетившие сайт, зарегистрированные в программе лояльности, пользователи приложения.)
  • время
  • дополнительный признак (может отсутствовать)

Обычно BI системы ведут два основных журнала:
  • журнал посещений
    • uid
    • дата начала сессии
    • длительность (или дата окончания)
    • другие параметры (устройство, география, источник и т.п.)
  • журнал покупок
    • uid
    • дата покупки
    • сумма
    • м.б. состав покупки

Ниже на основании журналов подготовим профили пользователей для когортного анализа. 

import pandas as pd

sessions = pd.read_csv('sessions.csv')  #https://drive.google.com/file/d/1mM4m4W_jWH8KqicHjJguw70ViO5_ldgK/view?usp=share_link
sessions['session_start'] = pd.to_datetime(sessions['session_start'])

orders = pd.read_csv('book_orders.csv')  #https://drive.google.com/file/d/1BRxsxvtYXrADqD6fXd_YqXgo4xiXeCRb/view?usp=share_link
orders['event_dt'] = pd.to_datetime(orders['event_dt'])

# добавили второй аргумент
def get_profiles(sessions, orders=None):

    profiles = (
        sessions.sort_values(by=['user_id', 'session_start'])
        .groupby('user_id')
        .agg(
            {
                'session_start': 'first',
                'channel': 'first',
                'device': 'first',
                'region': 'first',
                # другие параметры
            }
        )
        .rename(columns={'session_start': 'first_ts'})
        .reset_index()
    )

    profiles['dt'] = profiles['first_ts'].dt.date
    profiles['month'] = profiles['first_ts'].to_numpy().astype('datetime64[M]')
    
    # проверьте, есть ли ID пользователей из profiles в orders
    if orders is not None:
        payers = set(orders.user_id.unique())
        profiles['payer'] = profiles['user_id'].map(lambda x: True if x in payers else False)

    return profiles

# строим профили по двум наборам данных
profiles = get_profiles(sessions, orders)

print(profiles)

Простая продуктовая воронка

В данных должны содержаться три обязательных поля:
  • дата и время - event_time
  • идентификатор пользователя uid
  • имя события event_name

events_count = events.groupby('event_name').agg({'uid': 'count'})
в первом приближении так, то пользователи могут вызывать одно и тоже событие по нескольку раз, например, открывать окно чата с сервисом, поэтому правильнее будет использовать количество уникальных пользователей на каждом этапе воронки.
users_count = events.groupby('event_name').agg({'uid': 'nunique'}).sort_values(by='uid', ascending=False)