В этом блоге я расскажу о своем исследовании поведения покупателей на реальном наборе данных Instacart из 3 млн + записей. Я расскажу, как быстро выполнить анализ корзины покупателя с помощью алгоритма Apache Spark ML FP-growth
на Databricks.
Анализ рыночной корзины - это метод, используемый крупными розничными торговцами для выявления ассоциаций между своими товарами. Он работает путем поиска комбинаций предметов, которые часто покупаются вместе, и предоставляет информацию для понимания покупательского поведения. Майнинг ассоциативных правил - одна из очень важных концепций машинного обучения, используемых в анализе рыночной корзины. Давайте разберемся, что это такое.
Правило ассоциации Mining
Правила ассоциации можно рассматривать как отношения «если-то». Проще говоря, если у покупателя есть товар A в корзине, правила ассоциации помогают определить другой товар B, который покупатель, скорее всего, купит. Например, если покупатель покупает хлеб, вполне вероятно, что он купит и масло.
Супермаркеты с тысячами различных продуктов в своих магазинах могут увеличить свои доходы и прибыль, получив доступ к этим неиспользованным возможностям для определения взаимосвязи между приобретенными товарами. Они могут сделать это, разместив часто покупаемые вместе товары в одном проходе, оптимизируя дизайн своего каталога, предлагая перекрестные продажи товаров с коллективными скидками на своих веб-сайтах и анализируя анализ поведения покупателей и т. Д.
При определении правил связывания используются два важных показателя: Поддержка и Уверенность. Каждое правило ассоциации должно одновременно иметь минимум уверенности и минимум поддержки, и они обычно указываются пользователем.
Теперь давайте посмотрим, что такое показатели поддержки, уверенности и подъема с двумя пунктами (предположим) X и Y .
Поддержка: - Поддержка определяется как частота, с которой элементы X и Y покупаются вместе в течение общего количества транзакций. Этот показатель показывает, насколько часто набор элементов встречается во всех транзакциях.
Уверенность: - Уверенность - это частота, с которой X и Y покупаются вместе. с частотой, с которой X приобретается отдельно.
Подъем: - Подъем определяется как поддержка по сравнению с поддержкой для X, умноженная на поддержку для Y. Думайте о подъеме как о росте вероятности того, что в тележке окажется Y, если известно о наличии X. над вероятностью наличия Y в корзине без каких-либо сведений о наличии X.
Я буду использовать эти метрики позже при реализации алгоритма FP-growth
.
Набор данных
В этом блоге я использую настоящий набор данных Instacart, который был выпущен на Kaggle в 2017 году.
Это анонимный набор данных, содержащий выборку из более чем 3 миллионов заказов на продукты от более чем 200 000 пользователей Instacart. На каждого пользователя приходится от 4 до 100 заказов с указанием последовательности приобретенных продуктов в каждом заказе.
Набор данных можно скачать здесь.
Используемая платформа
Я бы использовал Apache Spark для реализации этого проекта и использую языки программирования PySpark, SparkSql и более поздние версии Scala для кодирования.
Обратите внимание, что вы можете бесплатно попробовать Apache Spark в облаке Databricks по этой ссылке.
Хорошо, хватит теории, перейдем к коду.
Импорт всех доступных файлов в Spark DataFrame и создание временных таблиц
В набор данных входит шесть разных файлов .csv, которые можно объединить для выполнения анализа. Для начала я импортировал все 6 файлов в среду Spark и создал временные таблицы для выполнения на них запросов Spark SQL.
Давайте посмотрим на 5 верхних строк каждого импортированного файла и их словарь данных:
orders
(3,4 млн строк, 206 тыс. пользователей):
order_id
: идентификатор заказаuser_id
: идентификатор клиентаeval_set
: к какому оценочному набору принадлежит этот заказorder_number
: порядковый номер заказа для этого пользователя (1 = первый, n = n-й)order_dow
: день недели, когда был размещен заказorder_hour_of_day
: час дня, когда был размещен заказdays_since_prior
: дней с момента последнего заказа, максимум 30 (с НП дляorder_number
= 1)
orders.show(n=5)
products
(50 тыс. строк):
product_id
: идентификатор продуктаproduct_name
: название продуктаaisle_id
: внешний ключdepartment_id
: внешний ключ
products.show(n=5)
aisles
(134 строки):
aisle_id
: идентификатор проходаaisle
: название прохода
aisles.show(n=5)
deptartments
(21 строка):
department_id
: идентификатор отделаdepartment
: название отдела
departments.show(n=5)
order_products_train
(131 тыс. + строк):
Данные обучения, предоставленные участникам Kaggle
order_products_train.show(n=5)
order_products_prior
(32 млн + строк):
Данные о заказах до последнего заказа этого пользователя
order_products_prior.show(n=5)
Теперь, когда мы создали DataFrames и взглянули на 5 верхних строк каждого файла, приступим к EDA с использованием Spark SQL, чтобы найти идеи и закономерности из набора данных Instacart.
Исследовательский анализ данных
В какое время дня покупают покупатели?
df = sqlContext.sql("select count(order_id) as total_orders, order_hour_of_day as hour from orders group by order_hour_of_day order by order_hour_of_day") df.show()
Примечание: с записными книжками Databricks мы можем использовать
%sql
для выполнения кода SQL в новой ячейке той же записной книжки Python. Например, эквивалентный код приведенного выше фрагмента кода будет таким, как показано ниже.
%sql select count(order_id) as total_orders, order_hour_of_day as hour from orders group by order_hour_of_day order by order_hour_of_day
Примечание. Databricks поддерживает различные типы DataFrame и визуализаций SQL в ячейках записной книжки. Вы можете узнать о них подробнее здесь.
▶ Над линейным графиком показано, что клиенты с большей вероятностью разместят заказ с 9:00 до 18:00.
Как часто клиенты размещают заказы?
%sql select days_since_prior_order,count(order_id) as total_orders from orders group by days_since_prior_order order by days_since_prior_order
▶ Похоже, что большинство клиентов заказывают один раз в неделю, поскольку большая часть записей сосредоточена от 0 до 7 дней.
▶ Кроме того, большое количество клиентов размещают заказ через 30 дней или позже, поскольку столбец days_since_prior ограничен 30
В какой день недели клиенты покупают больше всего?
%sql select count(order_id) as total_orders, (case when order_dow = '0' then 'Sunday' when order_dow = '1' then 'Monday' when order_dow = '2' then 'Tuesday' when order_dow = '3' then 'Wednesday' when order_dow = '4' then 'Thursday' when order_dow = '5' then 'Friday' when order_dow = '6' then 'Saturday' end) as day_of_week from orders group by order_dow order by total_orders desc
▶ В воскресенье и понедельник больше всего заказов, а в четверг меньше всего заказов за неделю.
Сколько товаров покупатели покупают в заказе?
Давайте создадим главный набор данных, объединив вместе продукты, отделы, наборы данных order_products_train и order_products_prior и запустим запрос поверх этого.
%sql create table master_table as (select op.*,p.product_name,p.aisle_id,p.department_id,d.department from (select * from order_products_train union select * from order_products_prior) as op inner join products as p on op.product_id = p.product_id inner join departments as d on p.department_id = d.department_id) %sql select order_id,count(product_id) as total_items from master_table group by order_id
▶ На гистограмме выше показано, что чаще всего покупатели заказывают 4 товара.
▶ Большинство клиентов предпочитают покупать от 1 до 15 товаров за заказ.
Из каких отделов верхнего уровня размещаются заказы?
%sql select department, count(*) as orders_count from master_table group by department order by orders_count desc limit 10
▶ Если мы посмотрим на 10 ведущих отделов, в которых закупается большинство товаров, мы сделаем вывод, что почти 50% покупаемых товаров принадлежат всего 2 отделам, которые 'производят 'и' молочные яйца '
Какие товары покупаются чаще всего?
%sql select product_name, count(*) as orders_count from master_table group by product_name order by orders_count desc limit 200
▶ Это 8 товаров, которые клиенты Instacart чаще всего покупают в своих заказах. Похоже, что в корзинах чаще всего покупают банан, за ним следуют клубника, молодой шпинат, авокадо и т. Д.
Давайте также составим облако слов из 200 самых популярных товаров, покупаемых клиентами Instacart.
# !pip install wordcloud from wordcloud import WordCloud import matplotlib.pyplot as plt df = sqlContext.sql("SELECT product_name FROM (select product_name, count(*) as orders_count from master_table group by product_name order by orders_count desc limit 200)") df2 = df.rdd.flatMap(lambda x: x).collect() fullStr = ' '.join(df2) wordcloud = WordCloud(background_color="white").generate(fullStr) # Display the generated image: plt.figure(figsize=(14, 10)) plt.imshow(wordcloud, interpolation='bilinear') plt.axis("off") plt.show() display()
Судя по облаку слов, американцы часто покупают экологически чистые продукты и овощи, используя такие слова, как Больше всего выделяются органические продукты, молоко, вода, яблоки, газированные напитки, яйца, зелень, сыр и т. Д.
Алгоритм FP-роста
Алгоритм FP-роста описан в статье Хан и др., Майнинг частых паттернов без генерации кандидатов, где FP означает частый паттерн. Учитывая набор данных транзакций, первым шагом роста FP является вычисление частотности элементов и выявление часто встречающихся элементов. В отличие от априорных алгоритмов, разработанных для той же цели, второй этап FP-роста использует структуру суффиксного дерева (FP-tree) для кодирования транзакций без явной генерации наборов кандидатов, создание которых обычно является дорогостоящим. После второго шага часто используемые наборы элементов можно извлечь из FP-дерева.
Вы можете узнать больше о этапах алгоритма FP-роста здесь.
Организация данных по корзине покупок
Для реализации FP-роста мы сначала создадим корзины каждого порядка в нашем наборе данных. Мы бы сделали это, создав фрейм данных корзины, содержащий 2 столбца: первый - order_id, а второй - список товаров, купленных в этом конкретном порядке.
Ниже приведены 5 верхних строк фрейма данных корзин, которые будут загружены в алгоритм увеличения FP.
Реализация алгоритма FP-роста на Scala
Здесь мы будем использовать для реализации пакет spark.ml
FP-growth.
Давайте начнем с того, что минимальное значение поддержки будет равно 0,001, а минимальное значение достоверности равно 0. Оба этих порога определяются пользователем. Минимальное значение поддержки выбирается таким образом, чтобы в наших наборах элементов был минимум 1 элемент, и это не занимало много времени для вычислений (более низкое минимальное значение поддержки приводит к большему времени вычислений).
Создание частых наборов товаров и создание правил связывания
А теперь давайте исследуем частые наборы предметов, которые мы сгенерировали выше.
%sql select items, freq from mostPopularItemInABasket where size(items) > 2 order by freq desc limit 20
Чаще всего в корзины входят органические авокадо, органические клубники и органические бананы вместе.
Хороший способ подумать о правилах ассоциации состоит в том, что модель определяет, что если вы что-то купили (т. Е. предшествующий), то вы купите и эту другую вещь (т. Е. консеквент) со следующей уверенностью.
%sql select antecedent as `antecedent (if)`, consequent as `consequent (then)`, confidence from ifThen order by confidence desc limit 20
Приведенные выше результаты показывают, что если в корзине покупателя есть органическая малина, органические авокадо и органическая клубника, то, возможно, имеет смысл порекомендовать и органические бананы. Удивительно, но 10 лучших рекомендаций по покупке либо органических бананов, либо бананов.
Показатель рост определяет, насколько независимы предшествующее и последующее в наборах элементов. Подъем ›› 1 означает, что элементы сильно зависят друг от друга, Подъем = 1 означает, что элементы не зависят друг от друга. other и l ift ‹< 1 означает, что элементы заменяют друг друга (это означает, что наличие одного элемента отрицательно влияет на наличие другого элемента и наоборот).
%sql select * from ifThen where lift > 1 order by lift desc
Как видно из результатов выше, для которых используются правила ассоциации по уменьшению значения поднятия значений, которые, если кто-то покупает йогурт с клубникой и ревенем тогда очень высока вероятность покупки черничного йогурта.
Реализация алгоритма FP-роста с использованием PySpark
Алгоритм FP-роста, который мы реализовали выше с помощью Scala, также можно реализовать с помощью PySpark с эквивалентным кодом, показанным ниже:
Резюме
В этом блоге мы проанализировали покупательское поведение клиентов и выполнили анализ рыночной корзины с помощью Apache Spark на огромном наборе данных. Если вы хотите реализовать анализ рыночной корзины в других средах, вы можете использовать библиотеку apyori в Python и библиотеку arules в R для алгоритма Apriori. .
Ну вот и все для этой статьи. Надеюсь, вам понравилось это читать, пожалуйста, поделитесь своими предложениями / взглядами / вопросами в разделе комментариев.
Спасибо за чтение !!!
Использованная литература: -
i) https://spark.apache.org/docs/latest/ml-frequent-pattern-mining.html
iii) https://towardsdatascience.com/association-rules-2-aa9a77241654