Использование ассоциативного интеллектуального анализа данных и априорного алгоритма

Введение

В последнее время все мы стали больше делать покупки на сайтах электронной коммерции, вероятно, из-за ограничений, введенных в большинстве стран мира. Вы, должно быть, заметили функцию дополнительных продаж под названием «часто покупают вместе» на большинстве этих сайтов, например на Amazon, где она предсказывает, какие товары будут уместны вместе с товар, который вы только что добавили в корзину. Клиентам предоставляется выбор: добавить в корзину все товары, показанные в рамках этой функции, или выбрать необходимые. Amazon делает это через то, что они называют «совместной фильтрацией товаров», когда запускает алгоритмы рекомендаций, основанные на истории поиска товаров покупателем, чтобы улучшить впечатления от покупок. В случае офлайн-розничных продавцов это работает примерно так же. Давайте рассмотрим основной пример «Хлеб и джем». Если розничный торговец обнаруживает рост продаж хлеба, он может дополнительно повысить продажи, предоставив скидку на варенье, так что больше покупателей обязательно будут покупать их вместе.

Весь этот процесс анализа покупательских тенденций клиентов называется «Анализ рыночной корзины». Это метод анализа, основанный на идее, что если мы покупаем товар, мы обязаны покупать или не покупать группу (или отдельные) товары. Например, если покупатель покупает хлеб, шансы, что он купит варенье, выше. Это представлено следующим уравнением:

Это уравнение называется правилом ассоциативного майнинга. Это можно рассматривать как отношение ЕСЛИ-ТО. Если товар A покупает покупатель, то выясняется вероятность того, что товар B будет куплен тем же пользователем в рамках той же транзакции. Здесь A называется антецедентом, а B - консеквентом. Антецеденты - это первичные элементы, которые находятся в корзине, а консеквенты - это элементы, обнаруженные с антецедентами / группой антецедентов. Метрики для измерения ассоциации:

Поддержка: он сообщает нам о комбинации товаров, которые часто покупаются вместе. Он дает часть транзакций, которые содержат как A, так и B.

Мы можем отфильтровать менее часто встречающиеся наборы элементов с помощью поддержки.

Уверенность: он говорит нам, как часто товары A и B покупаются вместе, или нет. раз покупается А.

Повышение: указывает силу правила над случайностью покупок A и B вместе. Он в основном измеряет силу любого правила ассоциации (о правилах ассоциации мы поговорим ниже).

Чем больше подъем, тем сильнее правило. Если лифт равен 3 для A - ›B, это означает, что если мы купим A, шансы купить B увеличиваются в 3 раза.

Таким образом, процесс состоит в том, чтобы создать правила для каждого набора элементов, чтобы выяснить метрики его связи, чтобы решить, включать его в анализ или нет. Но рассмотрим большой набор данных, содержащий миллионы пользователей и транзакций, тем самым создавая большое количество наборов элементов. Так что создать правила для всего этого было бы огромной задачей. Здесь на сцену выходит алгоритм Априори.

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

Чтобы продемонстрировать работу этого алгоритма, рассмотрим следующие транзакции:

Всего существует 5 предметов A, B, C, D и E, которые покупаются вместе в разных комбинациях в каждой транзакции. Давайте зафиксируем минимальное пороговое значение поддержки сформированных наборов элементов равным 2.

Итерация-1: Формируются наборы предметов, состоящие из 1 предмета, и рассчитывается их поддержка.

Как видно из значений поддержки каждого набора элементов, D имеет поддержку 1, что меньше порогового значения. Так что мы опустим этот набор элементов.

Итерация-2: Затем мы создаем все возможные наборы элементов, в которых есть 2 элемента. При этом используются все элементы таблицы F1.

Наборы предметов, поддерживающие менее 2, снова опускаются, {A, B} в этой итерации.

Итерация-3: перечислены все возможные наборы элементов, в которых есть 3 элемента. Затем мы собираемся разделить эти наборы элементов на их подмножества и опустить те, у которых значение поддержки меньше порогового, то есть 2. Этот процесс называется Сокращение.

Мы опускаем {A, B, C} и {A, B, E}, поскольку они оба содержат {A, B}, что было опущено в итерации-2. Эта секция обрезки является ключевой частью алгоритма априори.

Итерация-4: с помощью F3 мы создадим наборы из 4 элементов.

Как мы видим, поддержка единственного набора элементов, имеющего 4 элемента, меньше 2. Таким образом, мы останавливаем итерации здесь, и последний набор элементов - это F3.

Если I = {A, C, E}, то подмножествами являются {A, C}, {A, E}, {C, E}, {A}, {C}, {E}.

Если I = {B, C, E}, подмножества - это {B, C}, {B, E}, {C, E}, {B}, {C}, {E}.

Правила: для фильтрации соответствующих наборов элементов мы создадим определенные правила и применим их к подмножествам. Примите минимальное значение достоверности 60%.

Для каждого подмножества S из I мы составляем правило

S → (I-S) (что означает, что если S, то I минус S), если

поддержка (I) / поддержка (S) ≥ минимальное значение достоверности, т. е. 60%.

Рассмотрим {A, C, E}

Правило 1: {A, C} → ({A, C, E} - {A, C}), то есть {A, C} → {E}

Уверенность = поддержка {A, C, E} / поддержка {A, C} = 2/3 = 66,6% ›60%

Итак, выбрано правило 1, т.е. {A, C} → {E}.

Правило 2: {A, E} → ({A, C, E} - {A, E}), то есть {A, E} → {C}

Уверенность = поддержка {A, C, E} / поддержка {A, E} = 2/2 = 100% ›60%

Итак, выбрано правило 2, т.е. {A, E} → {C}.

Правило 3: {C, E} → ({A, C, E} - {C, E}), то есть {C, E} → {A}

Уверенность = поддержка {A, C, E} / поддержка {C, E} = 2/3 = 66,6% ›60%

Итак, выбрано правило 3, т.е. {C, E} → {A}.

Правило 4: {A} → ({A, C, E} - {A}), то есть {A} → {C, E}

Уверенность = поддержка {A, C, E} / поддержка {A} = 2/3 = 66,6% ›60%

Итак, выбрано правило 4, т.е. {A} → {C, E}.

Правило 5: {C} → ({A, C, E} - {C}), то есть {C} → {A, E}

Уверенность = поддержка {A, C, E} / поддержка {C} = 2/4 = 50% ‹60%

Итак, правило 5, т. Е. {C} → {A, E}, отклоняется.

Правило 6: {E} → ({A, C, E} - {E}), то есть {E} → {A, C}

Уверенность = поддержка {A, C, E} / поддержка {E} = 2/4 = 50% ‹60%

Итак, правило 6, т. Е. {E} → {A, C}, отклоняется.

Те же шаги можно проделать с {B, C, E}. Лифт не используется, поскольку размер набора входных данных невелик и нет необходимости в дальнейшей фильтрации. Но в случае большего набора данных дальнейшая фильтрация выполняется путем установления минимального значения подъемной силы для правил. Значения всех трех показателей ассоциации могут быть изменены в соответствии с требованиями.

Давайте рассмотрим фактический набор данных и посмотрим, как проводится анализ.

Ссылка на используемый набор данных приведена ниже.



Мы собираемся подать в суд на питона и панд. Мы также собираемся использовать Mlxtend lib, поскольку он содержит встроенные функции для алгоритма Apriori и правил ассоциации.

Загрузите необходимые библиотеки:

import pandas as pd
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
import matplotlib.pyplot as plt
from matplotlib import style
import numpy as np

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

read_df = pd.read_csv(‘transaction_data.csv’)
df = read_df.copy()
df.info()

Дальнейшее описание функций выглядит следующим образом:

UserId - Уникальный идентификатор пользователя.

TransactionId - уникальный идентификатор транзакции. Если один и тот же TransactionId присутствует в нескольких строках, то все эти продукты покупаются вместе в одной транзакции.

TransactionTime - время выполнения транзакции

ItemCode - уникальный идентификатор купленного товара.

ItemDescription - Простое описание приобретенного продукта.

NumberOfItemsPurchased - количество продукта, приобретенного в транзакции.

CostPerItem - Цена за каждую единицу товара.

Страна - страна, в которой совершена покупка.

EDA и очистка данных выполняется следующим образом:

df = df[df.UserId>0] # usedid <=0 : 25%
df = df[df.ItemCode>0]
df = df[df.NumberOfItemsPurchased>0]
df = df[df.CostPerItem>0]
df = df[df.ItemDescription.notna()]
df = df[df.TransactionTime.str[-4:] != ‘2028’]

Получается следующий фрейм данных:

EDA:

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

df.TransactionTime = pd.to_datetime(df.TransactionTime)
df[‘month_year’]= pd.to_datetime(df.TransactionTime).dt.to_period(‘M’)
df.sort_values(by = [‘month_year’], inplace = True)
Ser = df.groupby(‘month_year’).TransactionId.nunique()
x = np.arange(0,len(Ser),1)
style.use(‘ggplot’)
fig = plt.figure(figsize = (10,10))
ax1 = fig.add_subplot(111)
ax1.plot(x, Ser, color = ‘k’)
ax1.fill_between(x, Ser, color = ‘r’, alpha = 0.5)
ax1.set_xticks(x)
ax1.set_xticklabels(Ser.index)
plt.xlabel(‘Time period’)
plt.ylabel(‘No. of transactions’)

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

Как мы видим, с течением времени интернет-магазин получает все больше и больше покупок, максимум которых пришелся на 19 января.

Давайте исследуем нет. товаров, купленных в каждой транзакции.

Ser = df.groupby(‘TransactionId’).ItemDescription.nunique()
Ser.describe()

Как мы видим, мин. элементов равно 1, а максимальное - 540. Итак, нам нужно построить нашу гистограмму, как показано ниже:

bins = [0,50,100,150,200,250,300,350,400,450,500,550]
fig = plt.figure(figsize = (10,10))
plt.hist(Ser, bins, histtype = 'bar', rwidth = 0.5)
plt.xlabel('No. of items')
plt.ylabel('No. of transactions')
plt.show()

Ой! Мы видим, что большинство транзакций включает элементы от 0 до 100, а некоторые от 100 до 200. Показанное выше максимальное количество транзакций, вероятно, является выбросом или является покупателем, совершающим крупные покупки. Итак, нам нужно изменить масштаб нашей гистограммы.

bins = [0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200]
fig = plt.figure(figsize = (10,10))
ax1 = fig.add_subplot(111)
ax1.hist(Ser, bins, histtype = 'bar', rwidth = 0.5)
ax1.set_xticks(bins)
plt.xlabel('No. of items')
plt.ylabel('No. of transactions')
plt.show()

Как мы видим, в большинстве транзакций было менее 10 элементов.

Давайте узнаем самый продаваемый товар на рынке. Это можно интерпретировать по-разному, например, предмет, приносящий максимальный доход, предметы, которые были обнаружены в максимальном количестве. сделок и т. д. Будем рассматривать те позиции, которые приносят максимальную прибыль.

df[‘total_cost_item’] = df.NumberOfItemsPurchased*df.CostPerItem
Ser = df.groupby(‘ItemDescription’).total_cost_item.sum()
Ser.sort_values(ascending = False, inplace = True)
Ser = Ser[:10]
fig = plt.figure(figsize = (10,10))
ax = fig.add_subplot(111)
ax.barh(Ser.index, Ser, height = 0.5)

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

Нет. из уникальных TransactionId оказывается 18334, а номер уникальных ItemDescription’s оказалось 3871.

Теперь, когда у нас есть данные после всей предварительной обработки, давайте упорядочим их с помощью TransactionId в качестве индекса и ItemDescriptions в качестве столбцов с общим номером. элементов, купленных в каждой транзакции каждого элемента в качестве точки данных.

df_set = df.groupby(['TransactionId', 'ItemDescription']).NumberOfItemsPurchased.sum().unstack().reset_index().fillna(0).set_index('TransactionId')

Получается следующий фрейм данных:

Нам нужно убедиться, что любые положительные значения закодированы в одно, а все отрицательные значения (если есть) в ноль.

def encode(x):
 if x <= 0:
 return 0
 else:
 return 1
df_set = df_set.applymap(encode)
df_set

Когда фрейм данных готов, мы можем применить алгоритм Apriori для получения часто покупаемых наборов товаров.

frequent_itemsets = apriori(df_set, min_support = 0.015, use_colnames = True)

Здесь минимальное значение пороговой поддержки установлено на уровне 1,5%. Получаем следующие комплекты предметов.

Затем мы располагаем наборы элементов в порядке убывания их значений поддержки, что дает нам

frequent_itemsets = apriori(df_set, min_support = 0.015, use_colnames = True)
top_items = frequent_itemsets.sort_values('support', ascending = False)[:20]
for i in range(len(top_items.itemsets)):
    top_items.itemsets.iloc[i] = str(list(top_items.itemsets.iloc[i]))
fig = plt.figure(figsize = (10,10))
ax = fig.add_subplot(111)
ax.bar(top_items.itemsets, top_items.support)
for label in ax.xaxis.get_ticklabels():
    label.set_rotation(90)
plt.xlabel('Item')
plt.ylabel('Support')

Затем мы применяем правила ассоциации к этим наборам элементов, сформированным алгоритмом Apriori.

rules = association_rules(frequent_itemsets, metric = 'confidence', min_threshold = 0.2)

Здесь используется показатель достоверности, а его минимальное пороговое значение установлено равным 0,2.

Получен следующий фрейм данных

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

Сводка фреймов данных правил дает нам следующую информацию:

  1. Всего существует 187 правил.
  2. Сводка различных показателей.

Давайте возьмем главные правила с максимальной уверенностью

top_rules = rules.sort_values(‘confidence’, ascending = False)[:10]

fig = plt.figure(figsize = (10,10))
ax = fig.add_subplot(111)
ax.scatter(top_rules.support, top_rules.confidence, top_rules.lift)

Нанесение правил на график:

import networkx as nx
G1 = nx.DiGraph()
color_map = []
N = 50
colors = np.random.rand(N)
strs = ['r0', 'r1', 'r2', 'r3', 'r4', 'r5', 'r6', 'r7', 'r8', 'r9']
for i in range(10):
    G1.add_nodes_from('r'+str(i))
    for a in top_rules.iloc[i]['antecedents']:
        G1.add_nodes_from([a])
        G1.add_edge(a, 'r'+str(i), color = colors[i], weight = 2)
    for c in top_rules.iloc[i]['consequents']:
        G1.add_nodes_from([c])
        G1.add_edge('r'+str(i), c, color = colors[i], weight = 2)
for node in G1:
    found_a_string = False
    for item in strs:
        if node == item:
            found_a_string = True
    if found_a_string:
        color_map.append('red')
    else:
        color_map.append('black')
edges = G1.edges()
colors = [G1[u][v]['color'] for u,v in edges]
weights = [G1[u][v]['weight'] for u,v in edges]
pos = nx.spring_layout(G1, k = 16, scale = 1)
fig = plt.figure(figsize = (20,20))
nx.draw(G1, pos, edges = edges, node_color = color_map, edge_color = colors, width = weights, font_size = 16, with_labels = False)
for p in pos:
    pos[p][1] += 0.07
nx.draw_networkx_labels(G1, pos)

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

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

Здесь среднее значение подъема и уверенности составило 9,388 и 0,429 соответственно.

rules[(rules.lift >= 9.388) & (rules.confidence >= 0.429)]

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

Таким образом можно найти все необходимые наборы предметов. Дальнейшая точная настройка наборов элементов для поиска наиболее вероятных может быть выполнена путем увеличения пороговых значений поддержки и подъемной силы. Мы можем сохранить найденные наборы предметов в файле csv для дальнейшего использования.

Резюме:

Мы рассмотрели базовое правило Association Mining Rule и его приложения. Затем мы решили задачу создания часто покупаемых наборов товаров с помощью алгоритма Apriori. Был рассмотрен процесс применения правил ассоциации к этому сгенерированному набору элементов. Мы также узнали, как выполнить весь этот процесс на Python, используя Pandas и Mlxtend на сравнительно крупномасштабном наборе данных.

Ссылки: