Добро пожаловать в мой проект по сегментации розничных клиентов! Мы собираемся проанализировать данные розничной компании и попытаться понять поведение их клиентов. Надеюсь, мы найдем много полезной информации, которая поможет компании в планировании своих следующих кампаний, на кого будет нацелен новый продукт, каковы наиболее ценные клиенты и т. д.

Исходный набор данных, который можно найти в этом наборе данных kaggle. Он содержит информацию о 2240 клиентах, такую ​​как их возраст, семейное положение, количество детей, образование, доход, количество покупок на канал, общая сумма, потраченная на товар, сколько покупок было со скидкой, приняли ли они свои предложения кампании и т. д. Мы имеют 29 атрибутов, которые имеют полное описание в первоисточнике.

Код можно найти в моем github-репозитории. Обратите внимание, что большая часть кода в этой статье была опущена.

Очистка данных + разработка функций

В этом сеансе мы собираемся удалить нулевые значения, создать новые функции в наборе данных, удалить выбросы и внести некоторые другие корректировки.

Удаление пустых значений

Во-первых, мы собираемся сделать старую и добрую проверку нулевых значений:

## Check the number of null values
display(df.isnull().sum())
## fill the values with the mean
df = df.fillna(df['income'].mean())
## make sure we got rid of all the null values
assert (df.isnull().sum().sum() == 0)

У нас было 24 нулевых значения в функции «доход». Это очень низкое значение и хороший признак того, что наш набор данных очень последователен. Мы наполним их средним значением.

Создание новых функций

Теперь мы собираемся создать несколько новых функций, которые помогут нам.

# Feature engineering: Creating new, useful features
... 
# Create a feature with the percentage of purchases made with a discount
df['pct_purchases_with_discount'] = df['num_deals_purchases'] / df['num_purchases']
df['pct_purchases_with_discount'].fillna(0, inplace=True)
# Create a feature with the % of money spent on essential item (food-related) 
df['pct_essentials'] = (df['mnt_fruits'] + df['mnt_meat'] + df['mnt_fish'] + df['mtn_sweet'])/df['total_spent']

Двумя наиболее важными являются:

  • Процент покупок со скидкой.
  • Процент стоимости, потраченной на предметы первой необходимости (фрукты + мясо + рыба + сладости)

Удаление выбросов

Мы собираемся удалить некоторых клиентов, которые имеют экстремальные значения и не идут в ногу с другими.

## Removing outliers
df = df[(df[‘age’] < 90) & (df[‘income’] < 200000)].reset_index(drop = True)
print(“The new dataset have {} rows.”.format(df.shape[0]))

Итак, в новом наборе данных 2236 строк. В этом процессе было удалено только 4 клиента.

Перегруппировка категориальных значений

Вот наша проблема: функция, содержащая статус отношений и образование, имеет много категорий, и некоторые из них очень похожи друг на друга. Имеет смысл их перегруппировать, чтобы упростить анализ:

  • В функции отношений у нас будет 2 группы: люди, у которых есть партнер, и люди, у которых его нет.
  • В функции образования у нас будет 3 группы: бакалавриат, выпускники и аспиранты.
# Group some categories that have a similar meaning 
df[‘relationship’] = df[‘marital_status’].replace({‘Married’:1,’Together’:1,
 ‘Single’:0, ‘Divorced’:0, ‘Widow’:0, ‘Alone’:0, ‘Absurd’:0,’YOLO’:0})
df[“education”] = df[“education”].replace({‘Basic’:’Undergraduate’, ‘2n Cycle’:’Undergraduate’, 
 ‘Graduation’:’Graduated’, ‘Master’:’Postgraduate’, ‘PhD’:’Postgraduate’})

Замечательно! Прежде чем мы двинемся дальше, давайте посмотрим, имеет ли смысл разделение в образовательной группе: насколько различаются покупательские привычки между группами?

Кажется, что клиенты в категориях «Выпускник» и «Последипломное образование» имеют очень похожее поведение. Поэтому мы присоединимся к ним в одной группе.

Изучение функций «accepted_cpm_N»

В исходном наборе данных у нас есть 5 функций, которые указывают, принял ли клиент соответствующее предложение: AcceptedCmp1, AcceptedCmp2, AcceptedCmp3, AcceptedCmp4, AcceptedCmp5.

Из первоисточника:

«AcceptedCmp1: 1, если клиент принял предложение в 1-й кампании, 0 в противном случае»

Функции звучат великолепно, но у меня есть несколько вопросов:

  • Что произойдет, если клиент не был в компании достаточно долго, чтобы получить все предложения?
  • Как мы можем гарантировать, что он видел эти предложения?
  • Что делать, если он получил более 5 предложений?

Давайте посмотрим, как эти функции связаны с «pct_purchases_with_discount». Я ожидаю, что у них будет сильная корреляция.

Это не то, что мы ожидали! Похоже, у них обратная корреляция: чем больше предложений принимает покупатель, тем меньше у него процент покупок со скидкой. Это не имеет никакого смысла. Из-за этого несоответствия и вопросов, оставшихся без ответа выше, я не буду использовать этот набор функций: вместо этого, чтобы проверить, насколько разумно покупатели реагируют на скидки, я буду использовать «pct_purchases_with_discount», который является более простым.

Исследовательский анализ данных

Теперь мы более подробно рассмотрим наши функции, их распределение и то, как они соотносятся друг с другом. Мы рассмотрим только самые актуальные графики. Чтобы увидеть полное исследование, ознакомьтесь с проектом на github.

Небольшое напоминание: чтобы увеличить изображение, нажмите на него!

Категорические признаки

Мы видим, что большинство наших клиентов:

  • В отношениях
  • Иметь высшее образование (законченное или более)
  • Иметь 1 детей
  • В возрасте от 30 до 60 лет

Непрерывные функции

Мы видим, что большинство наших непрерывных переменных довольно хорошо распределены: у нас нет определенного диапазона для подавляющего большинства данных. Единственным исключением является pct_purchases_with_discount, где 75% наших клиентов совершают менее 18,2% покупок со скидкой.

Связь между переменными

Во-первых, давайте посмотрим, как функции соотносятся друг с другом.

Некоторые из этих отношений выделяются: Давайте нарисуем их.

Из этого первого набора графиков мы можем увидеть некоторые интересные отношения:

  • Чем выше доход, тем больше покупок совершается и больше денег тратится.
  • Покупатели с более высоким доходом менее склонны ждать скидок, чтобы купить товары. Это очень полезная информация! Зная это, команда маркетинга может разработать индивидуальную стратегию предоставления скидок разным клиентам.

Теперь к следующему набору графиков:

Чем больше детей у них дома:

  • тем больше денег они тратят
  • тем больше они склонны покупать товары со скидкой.
  • чем больше предметов первой необходимости они покупают

Это полезно знать: мы видим, что люди без детей тратят больше денег и покупают много товаров по полной цене! Эти клиенты являются самыми ценными для компании!

Кластеризация

Теперь мы собираемся начать с нашей кластеризации! Мы собираемся использовать K-Means для сегментации наших кластеров. Есть несколько шагов, которые мы собираемся предпринять в первую очередь: 1) масштабирование наших данных и выполнение метода уменьшения размерности.

Масштабирование данных

Теперь нам нужно масштабировать наши данные. Алгоритмы PCA и K-Means требуют, чтобы функции были в одном и том же измерении, поскольку их работа включает расчет расстояний между клиентами: если бы одна функция имела более широкий диапазон, чем другие, это оказало бы большее влияние на решение алгоритма. , а мы этого не хотим.

К счастью, метод Standard Scaler от sklearn упрощает это преобразование! Все исходные значения будут иметь аналогичный диапазон (в основном от -2 до 2). Новый набор данных (транспонированный) выглядит так:

Анализ основных компонентов (PCA)

В нашем наборе данных у нас есть большое количество функций, и многие из них имеют определенный уровень корреляции друг с другом и несколько избыточны. Выполнение метода уменьшения размерности является хорошим вариантом для уменьшения количества признаков, снижения стоимости вычислений алгоритма при сохранении большого количества информации из исходного набора данных.

Этот шаг не является обязательным, и не совсем ясно, всегда ли использование PCA перед кластеризацией дает нам лучшие результаты. В нашем случае конечные кластеры с PCA и без него были очень похожи. Мы все равно это делаем, просто в «академических» целях. Если бы я делал этот проект, работая на реальную компанию, я бы пропустил этот шаг.

Теперь, выполняя PCA, нам нужно определить, сколько основных компонентов нам потребуется, чтобы поддерживать около 70–80% дисперсии исходных данных.

Давайте посмотрим на диаграмму с сохраненной дисперсией по количеству основных компонентов.

С 4 основными компонентами мы объяснили почти 70% дисперсии. Это хороший результат, и это то, что мы собираемся использовать!

K-средние

Мы собираемся использовать алгоритм k-средних для создания наших кластеров. Во-первых, нам нужно определить идеальное количество кластеров. Мы собираемся сделать это, сравнив два метода: метод локтя и оценку силуэта.

Метод локтя

В методе локтя мы строим график зависимости WCSS от количества кластеров. WCSS представляет собой сумму квадратов расстояний между каждой точкой и центроидом в кластере. Естественно, по мере увеличения количества кластеров это значение всегда будет уменьшаться.

То, что мы ищем, — это значение N, при котором с этого момента уменьшение WCSS не будет очень значительным.

Глядя на кривую, не совсем понятно, каково идеальное количество кластеров. Давайте дважды проверим это с помощью показателей силуэта. Из википедии:

«Значение силуэта — это мера того, насколько объект похож на свой собственный кластер (сплоченность) по сравнению с другими кластерами (разделение)».

Оценка силуэта

Это решает: мы собираемся использовать K-Means с 3 кластерами.

Анализ результатов

После выполнения описанных выше шагов мы собираемся проанализировать результаты. Давайте сделаем несколько сюжетов!

Количество клиентов на кластер

Насколько различаются переменные в кластерах?

Из диаграммы и графиков выше мы можем получить хорошее представление о различиях между кластерами.

Кластеры 1 и 2 содержат большую часть наших данных, а кластер 3 значительно меньше, но по-прежнему содержит соответствующий процент наших клиентов.

На первый взгляд видно, что доход очень важен для разделения пользователей: в кластере 1 у нас много клиентов с высоким доходом, в кластере 2 у нас есть люди с низким доходом, а в кластере 3 — люди со средним доходом.

Прежде чем изложить наши выводы, давайте более наглядно посмотрим, насколько различаются переменные в кластерах.

Распределение переменных

Связь между переменными

Выводы

Благодаря этим кластерам мы на шаг ближе к пониманию поведения наших клиентов.

Наиболее важные выводы:

  • Люди из кластера 1 покупают товары по полной цене и тратят много денег. Следовательно, они являются нашими самыми ценными клиентами. Компания должна приложить дополнительные усилия, чтобы они остались довольны.
  • Люди из кластера 3 покупают много второстепенных товаров и очень чувствительны к скидкам. С другой стороны, люди из кластера 1 не очень хорошо реагируют на скидки. Поэтому может быть хорошей идеей сосредоточить усилия на рассылке специальных предложений людям из кластера 3 (и не отправлять так много в кластер 1).

Спасибо, что прочитали!