今天在看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个元素,自然不符合要求,也就不用求集合的并集了!