apriori: 通过 Apriori 算法获取频繁项集
Apriori 函数用于提取用于关联规则挖掘的频繁项集
from mlxtend.frequent_patterns import apriori
概述
Apriori [1] 是一种流行的算法,用于提取频繁项集,应用于关联规则学习。Apriori 算法旨在处理包含交易的数据库,例如商店顾客的购买记录。如果一个项集满足用户指定的最小支持度阈值,则被认为是“频繁的”。例如,如果支持度阈值设置为 0.5 (50%),频繁项集则定义为在数据库中至少 50% 的交易中一起出现的项目集合。
参考文献
[1] Agrawal, Rakesh, and Ramakrishnan Srikant. "快速关联规则挖掘算法." Proc. 20th int. conf. very large data bases, VLDB. Vol. 1215. 1994.
相关内容
示例 1 -- 生成频繁项集
apriori
函数需要独热编码的 pandas DataFrame 格式的数据。假设我们有以下交易数据
dataset = [['Milk', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Dill', 'Onion', 'Nutmeg', 'Kidney Beans', 'Eggs', 'Yogurt'],
['Milk', 'Apple', 'Kidney Beans', 'Eggs'],
['Milk', 'Unicorn', 'Corn', 'Kidney Beans', 'Yogurt'],
['Corn', 'Onion', 'Onion', 'Kidney Beans', 'Ice cream', 'Eggs']]
我们可以通过 TransactionEncoder
将其转换为正确的格式,如下所示
import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
te = TransactionEncoder()
te_ary = te.fit(dataset).transform(dataset)
df = pd.DataFrame(te_ary, columns=te.columns_)
df
苹果 | 玉米 | 莳萝 | 鸡蛋 | 冰淇淋 | 芸豆 | 牛奶 | 肉豆蔻 | 洋葱 | 独角兽 | 酸奶 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | False | False | False | True | False | True | True | True | True | False | True |
1 | False | False | True | True | False | True | False | True | True | False | True |
2 | True | False | False | True | False | True | True | False | False | False | False |
3 | False | True | False | False | False | True | True | False | False | True | True |
4 | False | True | False | True | True | True | False | False | True | False | False |
现在,让我们返回支持度至少为 60% 的项和项集
from mlxtend.frequent_patterns import apriori
apriori(df, min_support=0.6)
支持度 | 项集 | |
---|---|---|
0 | 0.8 | (3) |
1 | 1.0 | (5) |
2 | 0.6 | (6) |
3 | 0.6 | (8) |
4 | 0.6 | (10) |
5 | 0.8 | (3, 5) |
6 | 0.6 | (8, 3) |
7 | 0.6 | (5, 6) |
8 | 0.6 | (8, 5) |
9 | 0.6 | (10, 5) |
10 | 0.6 | (8, 3, 5) |
默认情况下,apriori
返回项目的列索引,这在下游操作(例如关联规则挖掘)中可能很有用。为了更好的可读性,我们可以设置 use_colnames=True
将这些整数值转换为相应的项目名称
apriori(df, min_support=0.6, use_colnames=True)
支持度 | 项集 | |
---|---|---|
0 | 0.8 | (鸡蛋) |
1 | 1.0 | (芸豆) |
2 | 0.6 | (牛奶) |
3 | 0.6 | (洋葱) |
4 | 0.6 | (酸奶) |
5 | 0.8 | (鸡蛋, 芸豆) |
6 | 0.6 | (鸡蛋, 洋葱) |
7 | 0.6 | (芸豆, 牛奶) |
8 | 0.6 | (芸豆, 洋葱) |
9 | 0.6 | (酸奶, 芸豆) |
10 | 0.6 | (芸豆, 鸡蛋, 洋葱) |
示例 2 -- 选择和过滤结果
使用 pandas DataFrames
的优势在于我们可以利用其便捷的功能来过滤结果。例如,假设我们只对长度为 2 且支持度至少为 80% 的项集感兴趣。首先,我们通过 apriori
创建频繁项集,并添加一个新列来存储每个项集的长度
frequent_itemsets = apriori(df, min_support=0.6, use_colnames=True)
frequent_itemsets['length'] = frequent_itemsets['itemsets'].apply(lambda x: len(x))
frequent_itemsets
支持度 | 项集 | 长度 | |
---|---|---|---|
0 | 0.8 | (鸡蛋) | 1 |
1 | 1.0 | (芸豆) | 1 |
2 | 0.6 | (牛奶) | 1 |
3 | 0.6 | (洋葱) | 1 |
4 | 0.6 | (酸奶) | 1 |
5 | 0.8 | (鸡蛋, 芸豆) | 2 |
6 | 0.6 | (鸡蛋, 洋葱) | 2 |
7 | 0.6 | (芸豆, 牛奶) | 2 |
8 | 0.6 | (芸豆, 洋葱) | 2 |
9 | 0.6 | (酸奶, 芸豆) | 2 |
10 | 0.6 | (芸豆, 鸡蛋, 洋葱) | 3 |
然后,我们可以按如下方式选择满足我们期望标准的结果
frequent_itemsets[ (frequent_itemsets['length'] == 2) &
(frequent_itemsets['support'] >= 0.8) ]
支持度 | 项集 | 长度 | |
---|---|---|---|
5 | 0.8 | (鸡蛋, 芸豆) | 2 |
类似地,使用 Pandas API,我们可以根据“itemsets”列选择条目
frequent_itemsets[ frequent_itemsets['itemsets'] == {'Onion', 'Eggs'} ]
支持度 | 项集 | 长度 | |
---|---|---|---|
6 | 0.6 | (鸡蛋, 洋葱) | 2 |
不可变集合 (Frozensets)
请注意,“itemsets”列中的条目是 frozenset
类型,这是 Python 内置类型,类似于 Python 的 set
,但它是不可变的,这使得它在某些查询或比较操作中效率更高 (https://docs.pythonlang.cn/3.6/library/stdtypes.html#frozenset)。由于 frozenset
是集合,项目的顺序无关紧要。也就是说,查询
frequent_itemsets[ frequent_itemsets['itemsets'] == {'Onion', 'Eggs'} ]
等价于以下三个查询中的任何一个
frequent_itemsets[ frequent_itemsets['itemsets'] == {'Eggs', 'Onion'} ]
frequent_itemsets[ frequent_itemsets['itemsets'] == frozenset(('Eggs', 'Onion')) ]
frequent_itemsets[ frequent_itemsets['itemsets'] == frozenset(('Onion', 'Eggs')) ]
示例 3 -- 使用稀疏表示
为了节省内存,您可能希望以稀疏格式表示您的交易数据。如果您有很多产品但交易规模较小,这将特别有用。
oht_ary = te.fit(dataset).transform(dataset, sparse=True)
sparse_df = pd.DataFrame.sparse.from_spmatrix(oht_ary, columns=te.columns_)
sparse_df
苹果 | 玉米 | 莳萝 | 鸡蛋 | 冰淇淋 | 芸豆 | 牛奶 | 肉豆蔻 | 洋葱 | 独角兽 | 酸奶 | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | False | False | False | True | False | True | True | True | True | False | True |
1 | False | False | True | True | False | True | False | True | True | False | True |
2 | True | False | False | True | False | True | True | False | False | False | False |
3 | False | True | False | False | False | True | True | False | False | True | True |
4 | False | True | False | True | True | True | False | False | True | False | False |
apriori(sparse_df, min_support=0.6, use_colnames=True, verbose=1)
Processing 21 combinations | Sampling itemset size 3
支持度 | 项集 | |
---|---|---|
0 | 0.8 | (鸡蛋) |
1 | 1.0 | (芸豆) |
2 | 0.6 | (牛奶) |
3 | 0.6 | (洋葱) |
4 | 0.6 | (酸奶) |
5 | 0.8 | (鸡蛋, 芸豆) |
6 | 0.6 | (鸡蛋, 洋葱) |
7 | 0.6 | (芸豆, 牛奶) |
8 | 0.6 | (芸豆, 洋葱) |
9 | 0.6 | (酸奶, 芸豆) |
10 | 0.6 | (芸豆, 鸡蛋, 洋葱) |
API
apriori(df, min_support=0.5, use_colnames=False, max_len=None, verbose=0, low_memory=False)
从独热编码的 DataFrame 获取频繁项集
参数
-
df
: pandas DataFrame已编码格式的 pandas DataFrame。也支持包含稀疏数据的 DataFrame;更多信息请参阅 (https://pandas.ac.cn/pandas-docs/stable/ user_guide/sparse.html#sparse-data-structures)
请注意,mlxtend >= 0.17.2 不再支持旧的 pandas SparseDataFrame 格式。
允许的值为 0/1 或 True/False。例如,
Apple Bananas Beer Chicken Milk Rice
0 True False True True False True
1 True False True False False True
2 True False True False False False
3 True True False False False False
4 False False True True True True
5 False False True False True True
6 False False True False True False
7 True True False False False False
-
min_support
: float (默认值: 0.5)一个介于 0 和 1 之间的浮点数,表示返回项集的最小支持度。支持度计算为
item(s)_出现的交易数 / 总交易数
。 -
use_colnames
: bool (默认值: False)如果为
True
,在返回的 DataFrame 中使用 DataFrame 的列名而不是列索引。 -
max_len
: int (默认值: None)生成的项集的最大长度。如果为
None
(默认值),则评估所有可能的项集长度(在 Apriori 条件下)。 -
verbose
: int (默认值: 0)如果 >= 1 且
low_memory
为True
,则显示迭代次数。如果=1 且
low_memory
为False
,则显示组合数。 -
low_memory
: bool (默认值: False)如果为
True
,使用迭代器搜索高于min_support
的组合。请注意,low_memory=True
仅应在内存资源有限时用于大型数据集,因为此实现比默认实现慢约 3-6 倍。
返回值
包含列 ['support', 'itemsets'] 的 pandas DataFrame,其中包含所有支持度 >= min_support
且长度 < max_len
(如果 max_len
不为 None)的项集。'itemsets' 列中的每个项集都是 frozenset
类型,这是一种 Python 内置类型,其行为类似于集合,但它是不可变的(更多信息请参阅 https://docs.pythonlang.cn/3.6/library/stdtypes.html#frozenset)。
示例
有关用法示例,请参阅 https://mlxtend.cn/mlxtend/user_guide/frequent_patterns/apriori/