如何在python中为apriori算法生成k-itemset

Posted

技术标签:

【中文标题】如何在python中为apriori算法生成k-itemset【英文标题】:How to generate k-itemset for apriori algorithm in python 【发布时间】:2014-10-23 13:56:52 【问题描述】:

这是我第一次尝试在 python 中编写代码并且我正在实现 Apriori 算法。我已经生成了 2 项集,下面是我必须通过组合 1 项集的键来生成 2 项集的功能。

如何使这个函数成为通用函数?我的意思是,通过传递字典的键和元组中所需的元素数量,算法应该使用这些键生成所有可能的 n-number(k+1) 个子集。我知道集合上的联合是一种可能性,但是有没有办法将元组联合起来,这本质上是字典的键?

# generate 2-itemset candidates by joining the 1-itemset candidates
def candidate_gen(keys):
    adict=
    for i in keys:
        for j in keys:
            #if i != j and (j,i) not in adict:
            if j>i:
        #call join procedure which will generate f(k+1) keys
        #call has_infrequent_subset --> generates all possible k+1 itemsets and checks if k itemsets are present in f(k) keys
                adict[tuple([min(i,j),max(i,j)])] = 0
    return adict

例如,如果我的初始字典看起来像:key, value --> value 是频率

'382': 1163, '298': 560, '248': 1087, '458': 720, 
 '118': 509,  '723': 528, '390': 1288

我把这个字典的键值传递给上面提到的candidate_gen函数 它将生成 2 项集的子集并给出键的输出。然后,我会将键传递给函数,通过与原始数据库进行比较来查找频率,从而获得以下输出:

('390', '723'): 65, ('118', '298'): 20, ('298', '390'): 70, ('298', '458'): 35, 
 ('248', '382'): 88, ('248', '458'): 76, ('248', '723'): 26, ('382', '723'): 203,
 ('390', '458'): 33, ('118', '458'): 26, ('458', '723'): 26, ('248', '390'): 87,
 ('118', '248'): 54, ('298', '382'): 47, ('118', '723'): 41, ('382', '390'): 413,
 ('382', '458'): 57, ('248', '298'): 64, ('118', '382'): 40, ('298', '723'): 36, 
 ('118', '390'): 52

如何从上述键生成 3 项集子集。

【问题讨论】:

你能给出一些示例输入和预期的输出吗?这将使每个人都更清楚您的问题。 你的代码有if j>i: adict[tuple([min(i,j),max(i,j)])] = 0,但它相当于更简单的if j>i: adict[i,j]=0 在您的代码中,keys 是字符串,如果字符串长度相同,则比较 j>i 有效。请在解释器提示符下尝试print('oh!' if '99'>'100' else 'ok.')... 【参考方案1】:

我认为,鉴于您的领域,您可以从研究 python 的itertools 库中受益匪浅。

在您的用例中,您可以直接使用 itertools combinations 或将其包装在辅助函数中

from itertools import combinations
def ord_comb(l,n):
    return list(combinations(l,n))

#### TESTING ####
a = [1,2,3,4,5]
print(ord_comb(a,1))
print(ord_comb(a,5))
print(ord_comb(a,6))
print(ord_comb([],2))
print(ord_comb(a,3))

输出

[(1,), (2,), (3,), (4,), (5,)]
[(1, 2, 3, 4, 5)]
[]
[]
[(1, 2, 3), (1, 2, 4), (1, 2, 5), (1, 3, 4), (1, 3, 5), (1, 4, 5), (2, 3, 4), (2, 3, 5), (2, 4, 5), (3, 4, 5)]

请注意,n-uples 中元素的顺序取决于您在传递给 combinations 的迭代中使用的顺序。

【讨论】:

感谢您的回复。这将在包含 a = [1,2,3,4,5] --> 单个元素的列表上提供 n 个组合。假设我的输入是 a = [(1,2),(3,4),(1,5)] 等等。如何在此之上生成 n 个组合?比如,输出 --> a= [(1,2,3),(1,2,4)...,(1,2,5)] 等等。 @prakyathj,我的TESTING 代码中的最后一个案例,这不是您要找的吗?在您的示例中,2 级元组的数量为 21,即 ((7x8)/2-7) 原始 7 个项目的所有非重复组合 2 乘 2,所以我推断(没有先验算法专业知识)您需要原始七种物品中 3 种物品的所有不同的、有序的组合...如果对于第 3 级您需要与这些组合不同的东西,请告诉我,因为我无法理解。 @prakyathj 我想强调一下,在我的答案中标有 Output 的框中的最后一行是完全 在您之前评论的末尾写道,就未满足的要求而言。【参考方案2】:

这个?

In [12]: [(x, y) for x in keys for y in keys if y>x]
Out[12]: 
[('382', '723'),
 ('382', '458'),
 ('382', '390'),
 ('458', '723'),
 ('298', '382'),
 ('298', '723'),
 ('298', '458'),
 ('298', '390'),
 ('390', '723'),
 ('390', '458'),
 ('248', '382'),
 ('248', '723'),
 ('248', '458'),
 ('248', '298'),
 ('248', '390'),
 ('118', '382'),
 ('118', '723'),
 ('118', '458'),
 ('118', '298'),
 ('118', '390'),
 ('118', '248')]

【讨论】:

OP 需要 3 级组合,如 [ (x, y, z) for x in l for y in l for z in l if x < y < z],所以你很接近。如果他需要更深层次的(4, ..., n)恕我直言,最好使用itertools.combinations之类的功能 如果他需要更深层次和灵活性,那么可以。他粘贴的代码生成 2-itemsets

以上是关于如何在python中为apriori算法生成k-itemset的主要内容,如果未能解决你的问题,请参考以下文章

Python --深入浅出Apriori关联分析算法 Apriori关联规则实战

Python中的Apriori关联算法-市场购物篮分析

在 python 2.7 中运行 Apriori 算法

实现Apriori算法(python)

Apriori 算法python实现

python实现apriori算法的关联规则之支持度置信度提升度