Apriori算法

    xiaoxiao2026-08-06  14

    #coding=utf-8 def load_data(): return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]] def create_c1(data): #把数据中单个元素转成列表格式,且不重复。 c1=[] for transaction in data: for item in transaction: if not [item] in c1: c1.append([item]) c1.sort() return map(frozenset,c1) def prob(set_data,c1,min_frequency): #计算各种组合在数据中出现的概率并选出大于最小概率的组合 ss_cnt={} for tid in set_data: for can in c1: if can.issubset(tid): #判断can是否在tid中 if not ss_cnt.has_key(can):ss_cnt[can]=1 #如果字典中不含can,则加进去并初始值为1 else:ss_cnt[can]+=1 #如果已经存在了,则对其出现次数进行统计 num_items=float(len(set_data)) #就是集合的数量 ret_list=[] element_frequency={} for key in ss_cnt: frequency=ss_cnt[key]/num_items #也就单个元素出现的频率 if frequency>=min_frequency: #判断成立的话就在ret_list中首位插入key ret_list.insert(0,key) element_frequency[key]=frequency return ret_list,element_frequency def p_and_c(lk,k): #进行排列组合 #步骤:根据最初的到的C1 [1,2,3,5] 俩俩组合 成k=2时的ck 即c2 #再根据c2 [[1,2],[1,3],[1,5],[2,3],[2,5],[3,5]] 三三组合成 k=3时的ck 即 c3 #c4即[1,2,3,5] ret_list=[] len_lk=len(lk) for i in range(len_lk): for j in range(i+1,len_lk): l1=list(lk[i])[:k-2] l2=list(lk[j])[:k-2] print l1,l2 l1.sort();l2.sort() if l1==l2: #这里用并集进行组合,而不用itertools.combinations #是因为,每次组合都是在前者已经筛选过概率的基础上进行的 #这样可以减少计算量 ret_list.append(lk[i]|lk[j]) #并集 return ret_list def apriori(data,min_frequency=0.5): c1=create_c1(data) d=map(set,data) l1,element_frequency=prob(d,c1,min_frequency) l=[l1] k=2 #k即单个组合中元素数量 while len(l[k-2]) >0: pc=p_and_c(l[k-2],k) #获取组合 lk,supk=prob(d,pc,min_frequency) #计算组合概率并返回大于最小概率的 element_frequency.update(supk) #更新并添加新的组合 l.append(lk) print l k+=1 return l,element_frequency def test(): data=load_data() l,s=apriori(data) print '\n',l,'\n',s test() def generate_rules(group,element_frequency,min_conf=0.7):     '''筛选出出现条件概率在min_conf以上的组合'''     #即1出现的情况下3出现的概率,选出这种概率在min_conf上的     result=[]     #大规则列表     for i in range(1,len(group)):         #之所以从1开始是因为group[0]是单个元素,这也是由数据样本定的。         #数据量足够大,也可以从0开始         for freqset in group[i]:             #遍历上面函数计算出的大于某一概率的组合             #分开组合中各元素,打包成列表             h1= [frozenset([item]) for item in freqset]           #  print h1             if i > 1:                 #i>1是因为组合内元素数超过2了                 rules_from_conseq(freqset,h1,element_frequency,result,min_conf)             else:                 calculate_probability(freqset,h1,element_frequency,result,min_conf)     return result def calculate_probability(freqset,h,element_frequency,result,min_conf=0.7):     '''计算条件概率'''     pruned_h=[]     #修剪     for conseq in h:         #遍历组合计算以组合中非conseq为条件的概率         #即组合[2,3],conseq=2,则计算以3为前提下出现组合[2,3]的概率         probability=element_frequency[freqset]/element_frequency[freqset-conseq]         if probability>=min_conf:             #若条件概率大于阈值,则取这个组合并附加到结果里             #并把conseq附加修剪列表,说明该元素不适合做前提条件             print freqset-conseq,'--->',conseq,'probability:',probability             result.append((freqset-conseq,conseq,probability))             pruned_h.append(conseq)     return pruned_h def rules_from_conseq(freqset,h,element_frequency,result,min_conf=0.7):     '''计算上面函数筛除的元素间是否存在大于指定概率的组合'''     m=len(h[0])     #这里m=1     if len(freqset)>(m+1):         #当组合中元素总数大于2时,将组合内所有元素两两组合         #然后再计算条件概率         hmp1=p_and_c(h,m+1)         hmp1=calculate_probability(freqset,hmp1,element_frequency,result,min_conf)         #返回的hmp1是不适合做前提条件的元素         if len(hmp1)>1:             #若hmp1大于1,则计算这一集合元素间是否存在大于阈值的组合             rules_from_conseq(freqset,hmp1,element_frequency,result,min_conf)
    转载请注明原文地址: https://ju.6miu.com/read-1310915.html
    最新回复(0)