A-priori算法的简单实现

A-priori算法是一种先验算法,经常用于数据挖掘里面寻找关联的子集。我们给定一个数据的集合{{1,2,3},{1,2,3,5,4}…{11,19,28}},需要寻找同时出现次数超过s次的k元集合 (x1,x2...xk). 其基本核心思路如下:

1:首先寻找出现次数超过s次的一元集合,由于这样的集合不会超过元素的总数,一般可以直接计算出来,利用字典(或其他hash结构)可以在O(N)的复杂度情况下得到解。

2:假定我们已经获取了k-1元集合的解,那么容易看出,k元集合里面一定含有k-1元的解,否则不可能出现超过s次。那么我们利用每一个集合对应的k-1元的解加上1元集合的解来构造该集合对应的k元候选集合。例如:如果第三个集合的2元解是{(2,5),(2,3),(3,5)},1元解是{(1),(4),(2),(3),(5)},那么候选的三元解则是{(2,3,4),(3,4,5),(2,5,4),(1,2,5)…(1,3,5)}。然后再去进行计算,检测是否确实出现了s次,过滤掉不满足的候选。

3:coding细节有这样几个需要注意:

[0]由于构造集合时没有顺序,所以我们必须要对集合排序,否则(1,2)与(2,1)对应的是同一个集合,但是确会输出两次。
[1]选取的单个元素有可能已经在k-1元的集合里面了,这时候就直接跳过这个组合。
[2]需要将原始数据复制一份,因为循环过程会改变原始的数据。

4:假设一共有n个集合,每个集合有m元素,我们直接暴力统计2元的解的复杂度是:

m22n ,而过滤之后再统计的复杂度是: mn+si ,其中si是代表过滤之后剩下的候选集合个数。很显然过滤之后的元素个数要比 nm2 得多.更不要说3元,4元直到 m2

def A_pri(raw_data,s,k):

    def get_singlgeitems():
        counts = {}
        for items in raw_data:
            for item in items:
                if item in counts:counts[item] += 1
                else:counts[item] = 1

        counts_filterd = [key for (key,val) in counts.items() if val >= s]
        return counts_filterd
    def select(backet,raw_backet):
        new_backet = set()

        for tuple_items in backet:
            for item in raw_backet:
                if item not in single_items or item in tuple_items :continue
                tmp = tuple_items+(item,)
                new_backet.add(tuple(sorted(tmp)))

        return new_backet
    def Tuple(data):
        tuple_data = []
        for items in data:
            tuple_data.append(set([(item,) for item in items]))
        return tuple_data

    def Set(data):
        set_data = set()
        for items in data:
            for item in items:
                set_data.add(tuple(sorted(item)))
        return set_data

    n = len(raw_data)
    data = Tuple(raw_data)
    single_items = get_singlgeitems()
    for size in range(2,k+1):
        for i in range(n):
            data[i] = select(data[i],raw_data[i])

        for first in range(n):
            items_1 = data[first].copy()
            for tuples in items_1:
                count = 0
                for items_2 in data:
                    count += 1 if tuples in items_2 else 0
                if count < s:data[first].remove(tuples)
    result = Set(data)
    print(result)
A_pri([[1,2,3,4],[1,2],[2,3,4],[1,2,4],[2,3],[3,4]],2,3)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值