基于Apriori算法的杂货店推荐案例研究

xueyuediana 2019-01-16

基于Apriori算法的杂货店推荐案例研究

如今,产品推荐已成为每一个电子商务的核心。大多数实时推荐引擎使用复杂的概念,如协同过滤,基于内容的过滤或混合推荐系统。每种类型都有其优点和缺点,但是当涉及到产品匹配或找到一起购买的产品集时,Apriori算法就发挥了作用。

使用这种推荐引擎有很多好处。即使您没有客户的各种数据,您仍然可以使用Apriori算法构建仅使用订单事务数据的引擎。

Apriori算法理论

Apriori算法有三个主要组成部分:

  • 支持度
  • 置信度
  • 提升度

支持度

支持度基本上说明该项目的受欢迎程度。支持度是通过在总订单编号中包含物品B的交易来计算的。

Support(B) = (Transactions containing (B))/(Total Transactions)

置信度

置信度是指如果购买物品A,物品B也被购买的可能性。 可以通过查找A和B一起购买的交易数量除以购买A的交易总数来计算。在数学上,它可以表示为:

Confidence(A,B) = (Transactions containing both (A and B))/(Transactions containing A)

提升度

Lift(A,B)是指出售A时B的销售比率的增加。Lift(A,B)可以用Confidence(A,B)除以Support(B)来计算。。在数学上它可以表示为:

Lift(A→B) = (Confidence (A,B))/(Support (B))

您可以通过查看提升度得出一些结论。提升度1表示产品之间没有关联。提升度大于1意味着产品可能一起购买。假设两种产品A和B的提升度为5,这意味着产品A和B一起购买比单独购买产品B的可能性高5倍。提升度小于1表明产品不太可能一起购买。

Python的Apriori算法

我使用kaggle中提供的数据(https://www.kaggle.com/psparks/instacart-market-basket-analysis)实现该算法。数据来自一家杂货店。在本文中,我仅使用订单和产品数据来描述Apriori。订单日期包含大约13个缺失行。我对数据进行了一些过滤,以减少脚本所花费的时间。您可以在完整的机器学习数据集上运行。

导入必要的Python库

import pandas as pd
import numpy as np

读取数据

order_product_df = pd.read_csv(‘data/order_products__train.csv’)
product_df = pd.read_csv(‘data/products.csv’)

基于Apriori算法的杂货店推荐案例研究

检查两个data frame的形状

print(“shape of order data = “, order_product_df.shape)
print(“shape of product data = “, product_df.shape)

基于Apriori算法的杂货店推荐案例研究

shape of order data = (1384617, 4)

shape of product data = (49688, 4)

检查订单数据

order_product_df.head()

基于Apriori算法的杂货店推荐案例研究

在订单数据中,为简单起见,我只使用order_id和product_id。我只对重新排序的数据进行了分析。

过滤数据

#lets do analysis for only the order which is reordered..
reorder_product = order_product_df.loc[order_product_df.reordered == 1]
print(“reorder shape = “, reorder_product.shape)

基于Apriori算法的杂货店推荐案例研究

reorder shape = (555793, 4)

检查每个产品的订单数量

reorder_product_ids = pd.DataFrame({‘order_count’: reorder_product.groupby([‘product_id’])[‘order_id’].count()})
reorder_product_ids.reset_index(inplace = True)
reorder_product_ids_sort = reorder_product_ids.sort_values(by = ‘order_count’, ascending= False)
reorder_product_ids_sort['order_count'].describe()

基于Apriori算法的杂货店推荐案例研究

基于Apriori算法的杂货店推荐案例研究

我使用了根据订单数量排序的产品id列表中排名前1%的产品。order_count的截止值是370。

过滤产品

reorder_product_ids_sort.quantile(0.99)

基于Apriori算法的杂货店推荐案例研究

reorder_product_top99pct = reorder_product_ids_sort.loc[reorder_product_ids_sort.order_count > 370]
#print("product count for top 99% = ", reorder_product_top99pct.shape)
product_list_99pct = reorder_product_top99pct.product_id.unique()
reorder_product_99Pct = reorder_product.loc[reorder_product.product_id.isin(product_list_99pct)]

基于Apriori算法的杂货店推荐案例研究

此数据集reorder_product_90Pct基本上包含产品位于前1%的所有订单。

为了分析数据,我将订单和产品组合排成行

使数据排成一行以便更好地理解。Python代码如下:

def make_dataSet_rowWise(reorder_product):
 print(“unique Product in dataset = “, len(reorder_product.product_id.unique()))
 print(“unique order_id in dataset = “, len(reorder_product.order_id.unique()))
 product_id_list = reorder_product.product_id.unique().tolist()
 product_id_list.append(‘order_id’)
 product_id_dict = {}
 i = 0
 
 for prod_id in product_id_list:
 product_id_dict[prod_id] = i
 i = i+1 
 product_id_df = pd.DataFrame(columns = product_id_list)
 row_list_all = []
 order_id_list = reorder_product.order_id.unique()
 i = 1
 for id in order_id_list:
 #print(i)
 i = i+1
 np_zeros = np.zeros(shape = [len(product_id_list)-1])
 ordered_product_list = reorder_product.loc[reorder_product.order_id == id][‘product_id’].tolist()
 for order_prod in ordered_product_list:
 np_zeros[product_id_dict.get(order_prod)] = 1
 
 row_list = np_zeros.tolist()
 row_list.append(id)
 row_list_all.append(row_list)
 return (row_list_all, product_id_list)
df_row_wise = make_dataSet_rowWise(reorder_product_99Pct)
product_id_df = pd.DataFrame(df_row_wise[0], columns = df_row_wise[1])
product_id_df.head()

基于Apriori算法的杂货店推荐案例研究

基于Apriori算法的杂货店推荐案例研究

上图显示了数据集的格式。这里每行代表一个order_id,每列代表一个product_id。如果特定订单包含product_id,则该行中该列的相应值将填充为1,否则为零。

现在在上面提到的数据集之上。我计算上面提到的三个参数,即每对产品的置信度,支持度,提升度。

计算每对产品的提升度。

基于Apriori算法的杂货店推荐案例研究

上图基本上显示了产品数据之间的提升度数据。现在您可以看到产品24852和13176之间的提升度是0.007368。

将提升度数据与产品名称数据集合并。并按升序对数据进行排序。

product_A_name = lift_df.Product_A.apply(lambda x: product_df.loc[product_df.product_id == x].product_name.tolist()[0])
product_B_name = lift_df.Product_B.apply(lambda x: product_df.loc[product_df.product_id == x].product_name.tolist()[0])
lift_df[‘product_A_name’] = product_A_name
lift_df[‘product_B_name’] = product_B_name
lift_df_sorted = lift_df.sort_values(by = [‘Lift’], ascending= False)
lift_df_sorted[[‘Lift’, ‘product_A_name’, ‘product_B_name’]].head()

基于Apriori算法的杂货店推荐案例研究

在这里你可以看到Icelandic Style Skyr Blueberry Non-fat YogurtNon Fat Raspberry Yogurt,提升度值为69.09,非常高。这表明这两种产品之间的可能性非常高。

基于Apriori算法的杂货店推荐案例研究

我们如何使用这种分析的结果?

现在你有了所有显示产品之间可能性的数据。现在,如果您想搜索某个特定产品的前5个推荐产品,只需使用product_id或名称过滤掉数据即可。您将看到那些特定产品中最常购买的产品。

这是一个例子,我过滤了产品 Icelandic Style Skyr Blueberry Non-fat Yogurt的数据,该列表显示了当一个人购买第一个产品时可以推荐的前5个其他产品。

基于Apriori算法的杂货店推荐案例研究

相关推荐