Обзор
Когда дело доходит до определения ваших лучших клиентов, лучше всего подходит старый принцип матрицы RFM. RFM расшифровывается как "Время с недавнего времени", "Частота" и "Деньги". Это метод сегментации клиентов, который использует прошлое покупательское поведение для разделения клиентов на группы.
Расчет рейтинга RFM
НЕДАВНИЕ (R): количество дней с момента последней покупки
ЧАСТОТА (F): Общее количество покупок
ДЕНЕЖНАЯ СТОИМОСТЬ (M): Общая сумма денег, потраченных этим клиентом
Шаг 1. Рассчитайте показатели RFM для каждого клиента.
Шаг 2: Добавьте номера сегментов в таблицу RFM.
Шаг 3. Отсортируйте в соответствии с оценками RFM лучших клиентов (111 баллов).
Поскольку RFM основан на данных об активности пользователей, первое, что нам нужно, это данные.
Данные
Набор данных, который мы будем использовать, тот же, что и при Анализе рыночной корзины - Набор данных розничной онлайн-торговли, который можно загрузить из Репозитория машинного обучения UCI.
import pandas as pd import warnings warnings.filterwarnings('ignore') df = pd.read_excel("Online_Retail.xlsx") df.head() df1 = df
Набор данных содержит все транзакции, произошедшие с 01/12/2010 по 09/12/2011 для зарегистрированного онлайн-продавца из Великобритании.
Загрузка данных заняла несколько минут, поэтому я сохранил копию в качестве резервной.
Изучите данные - проверка и новые переменные
- Отсутствуют значения в важных столбцах;
- Распределение клиентов в каждой стране;
- Цена за единицу и количество должны ›0;
- Дата выставления счета должна ‹сегодня.
df1.Country.nunique()
38
Всего было 38 уникальных стран:
df1.Country.unique()
array (['Соединенное Королевство', 'Франция', 'Австралия', 'Нидерланды', 'Германия',
'Норвегия', 'EIRE', 'Швейцария', 'Испания', "Польша", "Португалия",
"Италия", "Бельгия", "Литва", "Япония", "Исландия",
"Нормандские острова", "Дания", "Кипр", " Швеция, Австрия,
Израиль, Финляндия, Бахрейн, Греция, Гонконг, Сингапур,
Ливан, Объединенные Арабские Эмираты, "Саудовская Аравия", "Чешская Республика",
"Канада", "Не указано", "Бразилия", "США", "Европейское сообщество",
"Мальта", "RSA"], dtype = объект
customer_country=df1[['Country','CustomerID']].drop_duplicates() customer_country.groupby(['Country'])['CustomerID'].aggregate('count').reset_index().sort_values('CustomerID', ascending=False)
Более 90% клиентов в данных из Соединенного Королевства. Некоторые исследования показывают, что кластеры клиентов различаются в зависимости от географического положения, поэтому здесь я ограничусь данными только по Соединенному Королевству.
df1 = df1.loc[df1['Country'] == 'United Kingdom']
Проверьте, есть ли пропущенные значения в каждом столбце.
В столбце CustomerID 133600 пропущенных значений, и, поскольку наш анализ основан на клиентах, мы удалим эти пропущенные значения.
df1 = df1[pd.notnull(df1['CustomerID'])]
Проверьте минимальные значения в столбцах UnitPrice и Quantity.
df1 = df1[pd.notnull(df1['CustomerID'])]
0.0
df1.Quantity.min()
-80995
Удалите отрицательные значения в столбце "Количество".
df1 = df1[(df1['Quantity']>0)] df1.shape df1.info()
(354345, 8)
После очистки данных мы имеем дело с 354 345 строками и 8 столбцами.
Проверьте уникальное значение для каждого столбца.
def unique_counts(df1): for i in df1.columns: count = df1[i].nunique() print(i, ": ", count) unique_counts(df1)
InvoiceNo: 16649
StockCode: 3645
Описание: 3844
Количество: 294
InvoiceDate: 15615
UnitPrice: 403
CustomerID: 3921
Страна: 1
Добавьте столбец для общей цены.
df1['TotalPrice'] = df1['Quantity'] * df1['UnitPrice']
Узнайте дату первого и последнего заказа в данных.
df1['InvoiceDate'].min()
Отметка времени («2010–12–01 08:26:00»)
df1['InvoiceDate'].max()
Отметка времени («2011–12–09 12:49:00»)
Поскольку новизна рассчитывается для определенного момента времени, а дата последнего счета - 2011–12–09, мы будем использовать 2011–12–10 для расчета давности.
import datetime as dt NOW = dt.datetime(2011,12,10) df1['InvoiceDate'] = pd.to_datetime(df1['InvoiceDate'])
RFM сегментация клиентов
Отсюда начинается RFM-сегментация.
Создайте таблицу RFM
rfmTable = df1.groupby('CustomerID').agg({'InvoiceDate': lambda x: (NOW - x.max()).days, 'InvoiceNo': lambda x: len(x), 'TotalPrice': lambda x: x.sum()}) rfmTable['InvoiceDate'] = rfmTable['InvoiceDate'].astype(int) rfmTable.rename(columns={'InvoiceDate': 'recency', 'InvoiceNo': 'frequency', 'TotalPrice': 'monetary_value'}, inplace=True)
Рассчитайте показатели RFM для каждого клиента
Интерпретация:
- CustomerID 12346 имеет частоту: 1, денежное выражение: 77 183,60 долларов США и новизну: 325 дней.
- CustomerID 12747 имеет частоту: 103, денежное выражение: 4 196,01 доллара США и новизну: 2 дня.
Давайте проверим данные первого покупателя.
Первый покупатель совершил покупку только один раз, купил один товар в большом количестве (74 215). Цена за единицу очень низкая; возможно распродажа.
Разделите показатели
Самый простой способ разбить показатели на сегменты - использовать квартили.
- Это дает нам отправную точку для подробного анализа.
- 4 сегмента легко понять и объяснить.
quantiles = rfmTable.quantile(q=[0.25,0.5,0.75]) quantiles = quantiles.to_dict()
Создайте сегментированную таблицу RFM
segmented_rfm = rfmTable
Самая низкая давность, самая высокая частота и денежные суммы - наши лучшие клиенты.
def RScore(x,p,d): if x <= d[p][0.25]: return 1 elif x <= d[p][0.50]: return 2 elif x <= d[p][0.75]: return 3 else: return 4 def FMScore(x,p,d): if x <= d[p][0.25]: return 4 elif x <= d[p][0.50]: return 3 elif x <= d[p][0.75]: return 2 else: return 1
Добавьте номера сегментов во вновь созданную сегментированную таблицу RFM
segmented_rfm['r_quartile'] = segmented_rfm['recency'].apply(RScore, args=('recency',quantiles,)) segmented_rfm['f_quartile'] = segmented_rfm['frequency'].apply(FMScore, args=('frequency',quantiles,)) segmented_rfm['m_quartile'] = segmented_rfm['monetary_value'].apply(FMScore, args=('monetary_value',quantiles,)) segmented_rfm.head()
Сегменты RFM разбивают клиентскую базу на воображаемый трехмерный куб, который трудно визуализировать. Однако мы можем разобраться.
Добавьте новый столбец, чтобы объединить оценку RFM: 111 - это наивысшая оценка, как мы определили ранее.
segmented_rfm['RFMScore'] = segmented_rfm.r_quartile.map(str) + segmented_rfm.f_quartile.map(str) + segmented_rfm.m_quartile.map(str) segmented_rfm.head()
Очевидно, что первый покупатель - это вовсе не наш лучший покупатель.
Кто входит в десятку наших лучших клиентов?
segmented_rfm[segmented_rfm['RFMScore']=='111'].sort_values('monetary_value', ascending=False).head(10)
Учить больше
Интересно узнать больше?
- Kimberly Coffey имеет отличный учебник по тому же набору данных с использованием R.
- Пакет R Дэниела Маккарти и Эдварда Уодсворта - Buy’ Til You Die - A Walkthrough .
- Сегментация клиентов продавца вина из блога yhat.
Исходный код, создавший этот пост, можно найти здесь. Я был бы рад получить отзывы или вопросы по любому из вышеперечисленного.
ссылка: Blast Analytics and Marketing