关联规则apriori算法的python实现

来源:互联网 发布:删除数据库主键约束 编辑:程序博客网 时间:2024/05/24 06:41

学了两天python,想实践下,正好最近在学习数据挖掘,先用python实现下

注:由于后面加了注释,由于编码问题,可能即使是注释,有的环境也不支持汉字的编码,运行报错的话可以将汉字删除后再运行


环境 ubuntu 13.4      python 2


import itertoolsimport copy'''定义全局变量k,即支持度计数k,此k也可以在运行程序之前输入,简单改动即可'''k = 2'''存储频繁项集的列表'''frequenceItem = []'''从txt文件dataset.txt里获取事务集'''def getDataSet(args):    f = open(args,'r')    source = f.readlines()    f.close()    dataset = []    for line in source:        temp1 = line.strip('\r\n')        temp2 = temp1.split(',')        dataset.append(temp2)    return dataset'''初步扫描事务集,从事务集里获取候选1项集方法的基本思路是:定义一个集合tmp,将事务集的第一项作为tmp的初始集合然后扫描事务集,将不在tmp里的数据项加入tmp中'''def find_item( dataset ):    length = len(dataset)    for i in range(0, length):        if  i == 0:            tmp = set(dataset[i])        tmp.update(set(dataset[i]))    candidate=list(tmp)    candidate.sort()    return candidate'''从候选项集里找出频繁项集,其中num代表频繁num+1项集如num为0的为从候选1项集里找出频繁1项集方法基本思路:1、定义一个支持度列表count2、对于每一个候选项,依次扫描事务集,如果该项出现在事务集中就将该项对应的count+1、定义一个支持度列表count+1 3、将每一项的count和k(支持度计数)进行比较,将count小于k的项剔除'''def find_frequent( candidate, dataset, num):    frequence = []    length = len(candidate)    count = []    for i in range(0, length):        count.append(0)        count[i] = 0        if num == 0:'''其实不管num为0还是别的值算法应该是一样的,但是由于程序实现上的问题num为0的时候选项集是一维列表,其它的时候,候选项集是二维列表,毕竟只是自己写着玩的,python还不熟,牵一发而动全身,懒得改了'''            child= set([candidate[i]])        else:            child = set(candidate[i])        for j in dataset:            parent = set(j)            if  child.issubset(parent):                count[i] = count[i]+1    for m in range(0, length):        if  count[m] >= k:            frequence.append(candidate[m])    return frequence'''先验定理,剪枝掉不必要的候选n项集方法思路:1、依次取出候选项集里的项2、取出n项集里的n-1项子集3、如果所有的n-1项集不都都是频繁n-1项集的子集,则删除该候选项集'''def pre_test(candidate, num,frequence):    r_candidate = copy.deepcopy(candidate)    for each in candidate:        for each2 in itertools.combinations(each,num):            tmp= (list(each2))            tag = 0            for j in frequence:                if num == 1:                    if (tmp[0] == j):                        tag = 1                        break                else:                    if  tmp == j:                        tag = 1                        break            if  tag == 0:                r_candidate.remove(each)                break    return r_candidate'''通过频繁n-1项集产生候选n项集,并通过先验定理对候选n项集进行剪枝方法思路:1、如果是频繁1项集,则通过笛卡尔积产生频繁2项集2、如果不是频繁一项集,采用F(k-1) * F(k-1)方法通过频繁n-1项集产生候选n项集注:F(k-1) * F(k-1)方法在我的另一篇关联算法博客上做了理论上的简单介绍,或者也可以直接参看《数据挖掘导论》'''def get_candidata( frequence, num ):    length = len(frequence)    candidate =[]    if  num == 1:        for each in itertools.combinations(frequence,2):            tmp = list(each)            tmp3 = []            tmp3.append(tmp[0])            tmp3.append(tmp[1])            candidate.append(tmp3)    else:        for i in range(0,length-1):            tmp1 = copy.deepcopy(frequence[i])            tmp1.pop(num-1)            for j in range(i+1, length):                tmp2 = copy.deepcopy(frequence[j])                tmp2.pop(num-1)                if  tmp1 == tmp2:                    tmp3 = copy.deepcopy(frequence[i])                    tmp3.append(frequence[j][num-1])                    candidate.append(tmp3)    candidate2 = pre_test(candidate, num, frequence)    return candidate2'''main程序'''if __name__=='__main__':    dataset = getDataSet('dataset.txt')    Item = find_item(dataset)    num = 0    frequenceItem= []'''通过事务集找到频繁项集,直至频繁n项集为空,则退出循环'''    while 1:        if num == 0:            candidate = Item        else:            candidate = get_candidata(frequenceItem[num-1],num)        frequenceItem.append(find_frequent( candidate, dataset, num))        if frequenceItem[num] == []:            frequenceItem.pop(num)            break        num = num+1'''打印出频繁项集'''    for each in frequenceItem:        print each


目录位置:


编译结果:


事务集合



0 0