Apriori算法及python代码实现

来源:互联网 发布:临床试验电子数据采集 编辑:程序博客网 时间:2024/05/29 08:02

Apriori算法作用就是在一个数据集合中,找到满足出现次数大于等于一个阀值的子集及出现个数,这句话可能不是很好理解。举一个例子,比如说你是一家超市的店主,每天你的超市有大量的商品卖出,你想知道哪几样的商品,他们被一起买的次数很多,那么你可以改变超市商品摆放布局,让被一起买的商品放的位置近一些,这样可能能提高超市的销售额。那么假如现在有很多张顾客购买的清单,他们总共购买了n种商品,你想找出这n种商品中,被同时购买次数超过k的所有子集,Apriori算法就是解决这样的问题的。

在说这个算法的具体执行步骤前,我觉得可以先大概分析一下我们所要解决的问题,会发现,假如一个商品集合被购买次数少于k,那么所有包含这个商品集合的商品集合,肯定也是少于k的,所以,这启发我们,要从小到大开始解决这个问题,因为集合中商品种类越多,他被同时购买的可能性越小。

下面按我自己的理解描述和下Apriori算法的具体步骤:

1既然按照规模从小到大的思路,那么首先就是先找出规模为1的集合,这部需要遍历数据集中每一个数据,找出符合条件的结果加入到一个集合中,记为L(L1是一个集合,它的每个元素是规模为1的集合)。

2Li就是规模为i的所有解的集合,每次利用每次用Li生成Li+1,生成的方法就是用找到Li的任意两个元素(每个元素都是一个集合),如果这两个元素的前i-1个元素完全相同,那么这两个元素可以生成一个新的元素,这个新元素的前i-1个元素是就是这两个元素前i-1个元素的公共值,然后分别将两个第i个元素加上去即可,每次生成一个新的元素,就将其放到新的候选集合中,记为Ci+1。

3根据apriori的性质 ,Ci+1任意一个元素(是一个集合)的子集,它必须在前面L1,L2,,...Li出现过,否则直接删除掉这个元素,然后遍历整个数据集,判断是否满足最少次数大于等于k的条件,删去不符合条件的元素后的结果就是Li+1。

4回到2,假如Li为空时,算法停止。

附上python代码如下:

def creatDataSet():    dataset= [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]    return datasetdef apriori(minspt,dataset):    num=len(dataset)    ps=num*minspt    level=1    C=ToC1(dataset)    supt={}    L,supt=CtoL(C,ps,dataset)    Lres=[L]    while 1:        C=un(L,level)        L,supk=CtoL(C,ps,dataset)        if len(L)==0:            break        supt.update(supk)        Lres.append(L)        level+=1    return Lres,suptdef ToC1(dataset):    C=[]    for da in dataset :        for yu in da :            if not [yu] in C:                C.append([yu])        C.sort()    return map(frozenset,C)def CtoL(C,ps,dataset):    cnt={}    L=[]    su={}    for ci in C:        for da in dataset:            if ci.issubset(da):                if not cnt.has_key(ci): cnt[ci]=1                else: cnt[ci]+=1        for cn in cnt:        if cnt[cn]>=ps:            L.append(cn)            su[cn]=cnt[cn]    return L,sudef un(Lk,level):    C=[]    lenk=len(Lk)    for i in range(lenk):        for j in range(i+1, lenk):            L1= list(Lk[i])[:level-1]            L2= list(Lk[j])[:level-1]            L1.sort()            L2.sort()            if L1==L2:                C.append(Lk[i]|Lk[j])    return C

0 0