Python Apriori算法
本教程将讨论Python中Apriori算法的实现。
Apriori算法的解释
Apriori算法被广泛用于市场篮子分析,即分析哪些商品被售出,哪些其他商品被售出。对于那些想通过将售出的商品放在一起相互靠近或提供折扣来增加销售额的店主来说,这是一个有用的算法。
这个算法指出,如果一个物品集是频繁的,所有非空的子集也必须是频繁的。让我们看一个小例子来帮助说明这个概念。
比方说,在我们的商店里,牛奶、黄油和面包经常一起出售。这意味着牛奶、黄油和牛奶、面包、黄油、面包也经常一起出售。
Apriori算法还指出,一个项目集的频率不能超过其非空子集的频率。我们可以通过对我们之前的例子做一些扩展来进一步说明这一点。
在我们的商店里,牛奶、黄油和面包一起卖了3次。这意味着它的所有非空子集,如牛奶、黄油和牛奶、面包,以及黄油、面包,至少有3次以上一起出售。
Python中的Apriori算法
在实现这个算法之前,我们需要了解Apriori算法的工作原理。
在算法的开始,我们指定支持度阈值。支持率阈值只是在交易中出现一个项目的概率。
$$
支持率(A) =(包含项目A的交易数量) / (交易总数)
$$
除了支持度之外,还有其他的衡量标准,如置信度和提升度,但在本教程中我们不需要担心这些问题。
我们需要遵循的实现apriori算法的步骤如下。
- 我们的算法只从一个
1-itemset
。这里,1指的是我们的项目集中的项目数。 - 从我们的数据中删除所有不符合最小支持度要求的项目。
- 现在,我们的算法增加我们的项集中的项目数(
k
),并重复步骤1和2,直到达到指定的k
,或者没有符合最小支持度要求的项集。
在Python中实现拓扑排序算法
为了实现Apriori算法,我们将使用Python的apyori
模块。它是一个外部模块,因此我们需要单独安装它。
安装apyori
模块的pip
命令如下。
pip install apyori
我们将使用Kaggle的Market Basket Optimization数据集。
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from apyori import apriori
在上面的代码中,我们已经导入了所有操作所需的库。现在,我们需要使用pandas
读取数据集。
这已经在下面的代码段中实现了。
market_data = pd.read_csv('Market_Basket_Optimisation.csv', header = None)
现在,让我们检查一下我们的数据集中的交易总数。
len(market_data)
输出:
7501
输出显示,我们的数据集中有7501条记录。这个数据只有两个小问题;这些交易的长度是可变的。
考虑到现实世界中的场景,这是很有意义的。
为了执行apriori算法,我们需要将这些任意的交易转换为等长的交易。这已经在下面的代码片段中实现了。
transacts = []
for i in range(0, len(market_data)):
transacts.append([str(market_data.values[i,j]) for j in range(0, 20)])
在上面的代码中,我们初始化了列表transacts
,并将我们长度为20的事务存储在其中。这里的问题是,我们在少于20条的事务中插入空值。
但我们不必担心,因为apriori
模块会自动处理空值。
我们现在用apriori
类的构造函数从我们的数据中生成关联规则。这在下面的代码块中演示。
rules = apriori(transactions = transacts, min_support = 0.003, min_confidence = 0.2, min_lift = 3, min_length = 2, max_length = 2)
我们为构造函数的最小支持度、置信度和提升阈值指定了我们的阈值。我们还指定物品集的最小和最大数量为2,也就是说,我们希望生成经常一起出售的物品对。
apriori算法的关联规则被存储在rules
生成器对象内。我们现在需要一种机制,将这个rules
转化为一个pandas
数据框架。
下面的代码片段显示了一个函数inspect()
,它接收由我们的apriori()
构造函数返回的生成器对象rules
,并将其转换为一个pandas
数据框架。
def inspect(output):
Left_Hand_Side = [tuple(result[2][0][0])[0] for result in output]
support = [result[1] for result in output]
confidence = [result[2][0][2] for result in output]
lift = [result[2][0][3] for result in output]
Right_Hand_Side = [tuple(result[2][0][1])[0] for result in output]
return list(zip(Left_Hand_Side, support, confidence, lift, Right_Hand_Side))
output = list(rules)
output_data = pd.DataFrame(inspect(output), columns = ['Left_Hand_Side', 'Support', 'Confidence', 'Lift', 'Right_Hand_Side'])
print(output_data)
输出:
Left_Hand_Side Support Confidence Lift Right_Hand_Side
0 light cream 0.004533 0.290598 4.843951 chicken
1 mushroom cream sauce 0.005733 0.300699 3.790833 escalope
2 pasta 0.005866 0.372881 4.700812 escalope
3 fromage blanc 0.003333 0.245098 5.164271 honey
4 herb & pepper 0.015998 0.323450 3.291994 ground beef
5 tomato sauce 0.005333 0.377358 3.840659 ground beef
6 light cream 0.003200 0.205128 3.114710 olive oil
7 whole wheat pasta 0.007999 0.271493 4.122410 olive oil
8 pasta 0.005066 0.322034 4.506672 shrimp
我们现在可以通过支持度对这个数据框架进行排序,并通过以下代码显示我们数据集中的前5条记录。
print(output_data.nlargest(n = 5, columns = 'Lift'))
输出:
Left_Hand_Side Support Confidence Lift Right_Hand_Side
3 fromage blanc 0.003333 0.245098 5.164271 honey
0 light cream 0.004533 0.290598 4.843951 chicken
2 pasta 0.005866 0.372881 4.700812 escalope
8 pasta 0.005066 0.322034 4.506672 shrimp
7 whole wheat pasta 0.007999 0.271493 4.122410 olive oil
Apriori是一个非常基本和简单的市场篮子分析的算法。它可以为增加市场或商店中的商品销售提供有用的内幕信息。
这个算法的唯一缺点是,它对大型数据集需要大量的内存。这是因为它创建了大量的频繁项目的组合。
我们也经历了这个限制,因为这个教程是要与UCI在线零售数据集一起工作的,但由于内存的限制,我们不得不将数据集改为市场篮子优化。