Анализ рыночной корзины с помощью априорного алгоритма с использованием Python

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

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

df_mining = pd.DataFrame(
    [
        ["onion", "potato", "burguer", "false", "false"],
        ["false", "potato", "burguer", "milk", "false"],
        ["false", "false", "false", "milk", "beer"],
        ["onion", "potato", "false", "milk", "false"],
        ["onion", "potato", "burguer", "false", "beer"],
        ["onion", "potato", "burguer", "milk", "beer"],
    ]
)

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

minimum_support = 0.5
df_values = df_mining.values.astype(str)
n_trans = len(df_mining)
n_minimum_support = minimum_support * n_trans

index, counts = np.unique(df_values, return_counts=True)
df_item = pd.DataFrame(zip(index, counts), columns=["product", "frequency"])
df_item.sort_values(by="frequency", ascending=False, inplace=True)
df_item.reset_index(drop=True, inplace=True)
df_item = df_item.query("product != 'false'")
df_item

Поддерживать

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

Если предполагается, что минимальная поддержка равна 0,5, набор элементов отображается только в том случае, если он присутствует не менее чем в 50% транзакций.

n_minimum_support = minimum_support * n_trans
df_item_frequent = df_item[df_item["frequency"] > n_minimum_support]
df_item_frequent["supp"] = df_item_frequent["frequency"] / n_trans
df_item_frequent

Теперь нам нужно рассчитать поддержку для всех комбинаций элементов.

itemset_frequency = []
for i in tqdm(np.arange(len(df_item_frequent), 0, -1)):
    comb = list(combinations(df_item_frequent["product"].values, i))
    for w in comb:
        count = 0
        for instancia in df_values:
            if all(elem in instancia for elem in w):
                count = count + 1
        if count >= n_minimum_support:
            itemset_frequency.append({"itemset": w, "frequency": count})
df_itemset_frequency = pd.DataFrame(itemset_frequency)
df_itemset_frequency.sort_values(by="frequency", inplace=True, ascending=False)
df_item_frequent.set_index("product", inplace=True)
df_itemset_frequency["supp"] = df_itemset_frequency["frequency"] / n_trans
df_itemset_frequency

Обратите внимание, что мы исключили все нечастые наборы элементов.

Теперь мы можем создать правила ассоциации. Например, когда покупается бургер, покупается ли и лук? Давай выясним!!

Уверенность

Достоверность правила — это вероятность покупки товара B при покупке товара A. Другими словами, это условная вероятность найти элемент B в транзакциях при условии, что транзакции уже содержат A.

Пример: уверенность в покупке гамбургера при условии, что была куплена картошка.

То есть 80% людей, которые покупают картошку, покупают и бургеры.

Поднимать

Эта мера также вычисляет вероятность покупки предмета относительно другого предмета. Однако эта мера учитывает популярность обоих.

Пример: рост покупки гамбургера при условии, что была куплена картошка:

По этому значению проверяем:

  • Если Lift(X=›Y) › 1, набор Y, скорее всего, будет куплен, когда будет куплен X.
  • Если Lift(X=›Y) ≤1, набор Y вряд ли будет куплен, если X будет куплен.
prob = []
for item, supp in tqdm(df_itemset_frequency[["itemset", "supp"]].values):
    s = round(supp * 100, 2)
    for conjunto, supp_c in df_itemset_frequency[["itemset", "supp"]].values:

        conf = round((supp_c / supp) * 100, 2)
        lift = round(
            supp_c / np.prod([df_item_frequent.loc[i]["supp"] for i in conjunto]), 2
        )
        conj = set(conjunto) - set(item)
        if set(item).intersection(set(conjunto)) == set(item):
            if len(conj) > 0 and conf > 0:
                prob.append([conj, item, conf, lift])
df = pd.DataFrame(prob, columns=["B", "A", "confidence", "lift"])
df

Правила ассоциации

  • Каждый раз, когда кто-то покупал гамбургеры или лук вместе или по отдельности, он брал и картошку.
  • Если кто-то покупает картошку, менеджер должен порекомендовать лук или котлеты.

Скачать код здесь.

Это все люди!!

P.S. Если вам нравится читать подобные материалы на Medium, подумайте о том, чтобы поддержать меня и тысячи других писателей, подписавшись на членство. Или вместо этого вы можете купить мне кофе здесь. Хорошего дня :)