Apriori代码的一个巧妙点

今天在看Peter Harrington的机器学习第11章Apriori,这里面有个地方(aprioriGen方法),需要对n维集合进行合并扩维,即枚举所有n+1维的组合可能性,简单的说,就是:

对于原始1维set的集合(先取3个元素):

[{A}, {B}, {C}]

那么其2维联合组合可能性集合为:

[{A,B}, {B,C}, {A,C}]

再扩张到3维,很显然,唯一结果是:

[{A,B,C}]

看起来很简单哈,只需要嵌套2层for循环,进行集合并集操作即可,伪代码为:

D=[{A},{B},...{}] // D为n维集合的列表 

nextDimSet=[] // 输出n+1维集合列表

for i = 1 to len(D):

  for j = i+1 to len(D):

    candidate = D[i] | D[j]

    if size(candidate)==n+1 AND !nextDimSet.contains(candidate)

      nextDimSet.append(candidate)

return nextDimSet

但考虑上面2维-->3维的过程:

{A,B}|{B,C} ≡ {B,C}|{A,C} ≡ {A,C}|{A,B}

集合合并操作进行了3次,但结果都是一样的,当然还需要另外算上集合去重的开销

接着考虑另外一种情况:

[{1,2,3,...,8,X},{1,2,3,...,8,Y},{2,3,4,...,8,M,N}]

很显然,结果应当为:

[{1,2,3,...,8,X,Y}]

也就是第一个和第二个集合的合集,第三个集合与前二者都不相似,也就不应该参与集合求并的操作

那么,问题来了,如何知道某一个集合不应该参与求并操作呢?

Harrington的方案是:对于每每2个进行比较的n维集合,先排序,然后再取各自前(n-1)的元素进行比较,如果前n-1位一样,再求并集,即把各自的最后一位再加到这共同的n-1个元素集合里面

这样,n-1+2=n+1,就获得了扩张1维的集合。

以上述为例,{1,2,3,...,8,X},{1,2,3,...,8,Y}的前n-1位相同,符合合并条件,那么就进行合并;

{2,3,4,...,8,M,N}的第一位就与其他不同,也就是说,它与其他元素的合并,必然有多于n+1个元素,自然不符合要求,也就不用求集合的并集了!

posted @ 2019-02-15 14:19  老賊  阅读(220)  评论(0编辑  收藏  举报