В моём телеграм канале я запустил новую рубрику — task. Суть рубрики — Я публикую задание каждый вторник с постановкой задачи и ссылкой на данные. Код с описанием хода решения задачи я размещаю в четверг. Задачи сделаны так, что бы на их решение нужно потратить не более пары часов. Подробный пост — https://t.me/renat_alimbekov/71
Постановка задачи
Первая задача — сделать RFM-анализ. Он делит пользователей на сегменты в зависимости от давности (Recency), частоты (Frequency) и общей суммы платежей (Monetary).
- Recency — разница между текущей датой и датой последнего платежа
- Frequency — количество транзакций
- Monetary — сумма покупок
Эти три показателя нужно рассчитать отдельно для каждого покупателя. После чего поставить оценки от 1-3 или 1-5. Чем шире диапазон, тем более узкие сегменты у нас получатся.
Баллы можно выставить с использованием квантилей. Сортируем данные по одному из критериев и делим на равныегруппы.
Для этой задачи используем публичный датасет: https://www.kaggle.com/olistbr/brazilian-ecommerce и файлы olist_orders_dataset.csv и olist_order_payments_dataset.csv. Соединить их можно по order_id
.
Реализация RFM на Python
import numpy as np
import pandas as pd
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
from datetime import date,timedelta
df_orders = pd.read_csv('data/olist_orders_dataset.csv')
df_payments = pd.read_csv('data/olist_order_payments_dataset.csv')
Импортируем все необходимые библиотеки и считаем файлы.
Мы будем опираться на дату доставки заказа первозчиком (order_delivered_carrier_date
), поэтому преобразуем её в datetime64. Создадим индекс order_id
и соединим наши датасеты по нему.
df_orders['order_delivered_carrier_date'] = pd.to_datetime(df_orders['order_delivered_carrier_date'])
df_payments = df_payments.set_index('order_id')
df_orders = df_orders.set_index('order_id')
order_payment = df_orders.join(df_payments)
Так как датасет не самый свежий, вместо текущей даты будем использовать max+1. Для создания recency, frequency и monetary мы сгруппируем наши записи по customer_id
.
last_date = order_payment['order_delivered_carrier_date'].max() + timedelta(days=1)
rfmTable = order_payment.reset_index().groupby('customer_id').agg({'order_delivered_carrier_date': lambda x: (last_date - x.max()).days,
'order_id': lambda x: len(x),
'payment_value': lambda x: x.sum()})
rfmTable.rename(columns={'order_delivered_carrier_date': 'recency',
'order_id': 'frequency',
'payment_value': 'monetary_value'}, inplace=True)
Теперь нам нужно выставить оценки. Мы будем разбивать на диапазон от 1 до 5. Чем шире диапазон, тем более точные наши группы, но в тоже время работать с большим количествов комбинаций сложнее.
quantiles = rfmTable.quantile(q=[0.20, 0.40, 0.60, 0.80])
quantiles = quantiles.to_dict()
segmented_rfm = rfmTable
def RScore(x,p,d):
if x <= d[p][0.20]:
return 1
elif x <= d[p][0.40]:
return 2
elif x <= d[p][0.60]:
return 3
elif x<=d[p][0.80]:
return 4
else:
return 5
segmented_rfm['r_quartile'] = segmented_rfm['recency'].apply(RScore, args=('recency',quantiles,))
segmented_rfm['f_quartile'] = segmented_rfm['frequency'].apply(RScore, args=('frequency',quantiles,))
segmented_rfm['m_quartile'] = segmented_rfm['monetary_value'].apply(RScore, args=('monetary_value',quantiles,))
segmented_rfm['RFMScore'] = segmented_rfm.r_quartile.map(str) + segmented_rfm.f_quartile.map(str) + segmented_rfm.m_quartile.map(str)
print(segmented_rfm.head())
Отдельно можем посмотреть среднее значение recency по всем RFMScore.
fig=plt.figure(figsize=(18, 16), dpi= 80, facecolor='w', edgecolor='k')
segmented_rfm.groupby('RFMScore').agg('recency').mean().plot(kind='bar', colormap='Blues_r')
plt.show()
Пока возможно это не очень информативно. Давайте попробуем понять как использовать результаты анализа.
Как использовать результаты RFM анализа
Цель RFM анализа сформировать сегменты и в зависимости от сегмента воздействовать на них определенным образом. Например: предложить бонус, льготу, отправить push или email уведомление. Важно делать это таргетировано.
Эффект от использования RFM анализа может быть следующим: удержание клиентов, повышение дохода, повышение лояльность клиентов.
Примеры интерпретации сегментов RFM анализа:
- R=5, F=5, M=5 — платят чаcто, много и недавно. Самые лояльным и активные пользователи.
- R=1, F=1, M=1 — платят мало, редко и давно. Скорее всего потерянные клиенты. Возможно не стоит предпринять действия по их возврату, если цена привлечения выше ожидаемой прибыли.
- R=1/2, F=4/5, M=4/5 — лояльные пользователи на грани ухода. Предлагаем им бонус, скидку и пытаемся их вернуть.
- R=4/5, F=1, M=1/2/3/4/5 — пользователи недавно совершили платеж. Пробуем их стимулировать покупать еще.
Заключение
Разобрали простой и эффективный способ сегментации пользователей/ клиентов. RFM анализ поможет вам выбрать таргетированное воздействие и таким образом повысить доход, или удержать пользователей.
Разговоры о Data Science – закрытый канал для общения на тему карьеры, развития профессиональных навыков и применения навыков на работе.