apriori算法python,apriori算法数据实例
这里把之前的实验报告搬出来,代码参考了一下各位大哥的,然后自己再温习一遍~
作为数据挖掘的典型算法(也是机器学习的典型算法),Apriori算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集。关于其更多的介绍网上很多就不写了。
算法的基本步骤如下:
1. 首先先扫描数据集,计算每个单项集的支持度,根据给定的最小支持度的值,得到第一项频繁集。
2. 然后通过运算,得到二项候选集,对每个候选集再次扫描数据集,得出每个候选集的支持度,再与最小支持度比较,删除不合格的单项集,得到二项频繁集。
3. 如此进行下去,直到不能连接产生新的候选集为止。
4. 对于找到的所有频繁集,用规则提取算法进行关联规则的提取,算出置信度。
算法的关键代码如下:
一个题外话,为了把实验报告做得好看一些 :-) ,本人使用了Figlet这个工具来生成大大的华丽的字符再添加到输出中,至于它的下载安装网上教程很多也很简单,这里就看看效果:
接着直接将整个字符图形都复制粘贴到输出就OK了。
走正题,代码如下:
#!/usr/mdyb/python#coding=utf-8import itertools#事务数据库,和课本上的数据一致Data = {'T100':['I1','I2','I5'], 'T200':['I2','I4'], 'T300':['I2','I3'], 'T400':['I1','I2','I4'], 'T500':['I1','I3'], 'T600':['I2','I3'], 'T700':['I1','I3'], 'T800':['I1','I2','I3','I5'], 'T900':['I1','I2','I3']}#定义Apriori类class Apriori:def __init__(self,min_sup=0.2,dataDic={}):#事务数据库dataself.data = dataDic#获取事务的数量self.size = len(dataDic)#最小支持度阈值self.min_sup = min_supself.min_sup_val = min_sup * self.size#找出频繁1项集的集合L1def find_frequent_1_itemsets(self):#这里的字典格式设置为: {itemset1:freq1,itemsets2:freq2}FreqDic = {}for event in self.data:for item in self.data[event]:if item in FreqDic:FreqDic[item] += 1else:FreqDic[item] = 1L1 = []for itemset in FreqDic:if itemset >= self.min_sup_val:L1.append([itemset])return L1#实现连接和剪枝def apriori_gen(self,L_last):k = len(L_last[0]) + 1Ck = []for itemset1 in L_last:for itemset2 in L_last:#连接步:产生候选flag = 0for i in range(k-2):if itemset1[i] != itemset2[i]:flag = 1break;if flag == 1:continueif itemset1[k-2] < itemset2[k-2]:c = itemset1 + [itemset2[k-2]]else:continue#剪枝步:删除非频繁的候选if self.has_infrequent_subset(c,L_last,k):continueelse:Ck.append(c)return Ck#使用先验知识def has_infrequent_subset(self,c,L_last,k):#返回列表中元组的项subsets = list(itertools.commdybations(c,k-1))for each in subsets:#将元组转换成列表each = list(each)if each not in L_last:return Truereturn False#运行Apriori算法def run(self):L_last = self.find_frequent_1_itemsets()L = L_lasti = 0j = 2while L_last != []:Ck = self.apriori_gen(L_last)FreqDic = {}for event in self.data:#获取所有支持的子集for c in Ck:#判断是否是子集if set(c) <= set(self.data[event]):if tuple(c) in FreqDic:FreqDic[tuple(c)]+=1else:FreqDic[tuple(c)]=1Lk = []num = []Lo = []for c in FreqDic:if FreqDic[c] > self.min_sup_val:Lk.append(list(c))num.append(FreqDic[c])L_last = LkL += Lkif len(Lk) != 0:print "[*] 频繁%d项集L%d:"%(j,j)for i in xrange(0,len(Lk)):print Lk[i],':',num[i]printj += 1return Ldef main():print ''' _ _ _ / \ _ __ _ __(_) ___ _ __(_) / _ \ | '_ \| '__| |/ _ \| '__| | / ___ \| |_) | | | | (_) | | | |/_/ \_\ .__/|_| |_|\___/|_| |_| |_| '''a = Apriori(dataDic=Data)result = a.run()print "[*] 所有的频繁项集:"for r in result:print rif __name__ == '__main__':main()
这里将数据也写在脚本中,数据是跟书上一模一样的(具体的可以看《数据挖掘概念与技术 第三版》,具体第几页忘了)
运行结果: