Apriori 算法 实例

mushroom.dat

1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114
2 4 9 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
1 3 10 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 16 24 28 34 37 39 40 53 54 59 63 67 76 85 86 90 94 99 109 114
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 98 108 114
2 4 9 15 23 26 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 108 115
2 4 10 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 107 115
1 3 10 15 23 25 34 36 38 43 52 54 59 63 67 76 85 86 90 93 98 110 114
2 4 9 14 23 26 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 107 115
2 3 10 14 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 99 108 114
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 98 107 115
2 4 9 14 23 26 34 36 39 44 52 55 59 63 67 76 85 86 90 93 99 107 114
1 3 10 15 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 110 113
2 3 11 13 24 28 34 37 39 41 53 54 59 64 67 76 85 86 90 94 98 109 114
2 5 11 16 24 28 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 111 113
2 6 11 15 24 28 34 37 39 40 53 54 59 63 67 76 85 86 90 94 99 109 114
1 3 9 13 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 114
1 3 10 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 99 107 113
1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 107 113
2 4 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 107 115
1 3 10 13 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 99 110 114
2 4 10 14 23 27 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 107 115
2 4 10 15 23 26 34 36 39 44 52 55 59 63 67 76 85 86 90 93 99 108 115
2 4 9 15 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 107 115
1 6 9 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 99 110 114
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
2 3 10 15 23 27 34 36 39 44 52 55 59 63 67 76 85 86 90 93 99 108 115
2 6 11 13 24 28 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 111 113
2 3 9 14 23 26 34 37 38 41 53 56 59 63 67 76 85 86 90 93 99 110 116
2 4 9 14 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 99 108 115
1 3 10 15 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 99 107 113
2 3 10 14 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
2 3 10 13 23 27 34 36 39 43 52 57 59 65 67 76 85 86 90 93 99 111 117
2 4 10 14 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 107 115
2 3 11 14 23 27 34 37 38 44 53 56 59 63 67 76 85 86 90 93 99 110 116
2 5 11 16 24 28 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 110 113
1 3 10 13 23 25 34 36 38 44 52 54 59 63 67 76 85 86 90 93 99 107 113
2 3 11 14 23 26 34 37 38 43 53 56 59 63 67 76 85 86 90 93 99 110 116
2 4 9 14 23 27 34 36 39 40 52 55 59 63 67 76 85 86 90 93 98 107 115

#-*- coding: utf-8 -*-
from numpy import *

#生成原始数据,用于测试
def loadDataSet():
        return [[1, 3, 4],
            [2, 3, 5],
            [1, 2, 3, 5],
            [1, 2, 3, 4,5],
            [2, 5]]

      # return [['A', 'C', 'D'],
      #       ['B', 'C', 'E'],
      #       ['A', 'B', 'C', 'E'],
      #       ['B', 'E'],
      #       ['A', 'B', 'C','D', 'E'],
      #       ['A', 'B', 'C','E', 'F']]

    # return [[1, 3, 4],
     #        [2, 3, 5],
        #   [1, 2, 3, 5],
        #   [2, 5]]

    # return [[1,2,3,4],
     #        [2,5,4,6],
        #   [1,3,6],
        #   [1,2,3,5,4,6],
    #         [2,3,4],
    #         [2,3,6],
    #         [1,3,4],
    #         [1,2,3,7,4],
    #         [1,2,7,4]]

    # return [[1,2,3,4],
     #        [2,5,4,6],
        #   [1,3,5,6],
    #         [1,2,3,5,6],
        #   [2,3,4,5,6],
    #         [2,3,4],
    #         [2,3,6],
    #         [1,3,4]]

#遍历数据集每项交易记录,建立候选1-项集
def createC1(dataSet):
    #记录每项物品的列表
    C1 = []
    #遍历每条记录
    for transaction in dataSet:
        #遍历每条记录中的物品
        for item in transaction:
            #判断如果该物品没在列表中
            if not [item] in C1:
                #将该物品加入到列表中
                C1.append([item])
    #对所有物品进行排序            
    C1.sort()
    #frozenset数据类型,指被冰冻的集合
    #集合一旦完全建立,就不能被修改
    return map(frozenset, C1)


#输入:数据集D、候选集Ck、最小支持度
#用最小支持度minSupport对候选集Ck过滤
#输出:本层(第k层)的频繁项集Lk,Ck中的每项的支持度
def scanD(D, Ck, minSupport):
   #建立字典<key,value>
    #key-->候选集Ck中的每项
    #value-->该项在所有记录中出现的次数
   ssCnt = {}

    #遍历数据库D的每条记录
   for tid in D:
        #遍历候选集Ck中的每一项
       for can in Ck:
            #如果候选集Ck中该项在原数据库某条记录中出现
           if can.issubset(tid):
                #如果选集Ck中该项第一次被统计到,次数记为1
               if not ssCnt.has_key(can): ssCnt[can]=1
                #否则次数累加
               else: ssCnt[can] += 1

    #数据库D的总商品购买记录总数,用于计算支持度         
   numItems = float(len(D))
    #记录经最小支持度过滤后的频繁项集
   retList = []
    #记录候选集中满足条件的项的支持度<key,value>结构
    #key-->候选集中满足条件的项
    #value-->该项支持度
   supportData = {}

    #遍历候选集中的每项出现次数
   for key in ssCnt:
        #计算每项的支持度
       support = ssCnt[key]/numItems
        #用最小支持度过滤,
       if support >= minSupport:
            #在列表的首部插入大于最小支持度的项
           retList.insert(0,key)
        #记录每项的支持度       
       supportData[key] = support
    #返回频繁项集,以及每项的支持度
   return retList, supportData



#由频繁k-1项集Lk1,生成候选项集Ck
#输入:频繁k-1项集Lk1,新的候选集元素个数k
#输出:候选集Ck
def aprioriGen(Lk1, k):
   #保存新的候选集 
   retList = []
   #频繁项集记录数 
   lenLk1 = len(Lk1)

    #比较频繁项集中的两个子集元素
    #若两子集元素的前面k-2项都相同,那么就将两子集合并。
    #两个子集元素比较,通过使用两个for循环实现
   for i in range(lenLk1):
       for j in range(i+1, lenLk1):
           #取频繁项集Lk中的一个子集元素的前k-2个项
           L1 = list(Lk1[i])[:k-2]
           #取频繁项集Lk中的另一子集元素的前k-2个项
           L2 = list(Lk1[j])[:k-2]
           L1.sort()
           L2.sort()            
       #两元素的前k-2相同,则合并
           if L1==L2:
               #合并生成大小为k的集合
               retList.append(Lk1[i] | Lk1[j]) 
    #返回生成的候选k项集         
   return retList

#输入:数据集、最小支持度   
def apriori(dataSet, minSupport = 0.5):
    #生成1-项集
   C1 = createC1(dataSet)
    #对数据集进行映射至D,去掉某条记录中重复的商品
   print'C1=',C1
   D = map(set, dataSet)
    #候选项集C1->频繁1-项集L1 
    #supportData存放所有项集的支持度
   L1, supportData = scanD(D, C1, minSupport)
   print'L1=',L1
   #候选1项集所有元素对应的支持度
   print 'supportData1=',supportData

    #L存放所有的频繁项集,会包含L1、L2、L3...
   L = [L1]
   #由L1->C2,设定最初的k项集参数
   k = 2 

    #由L1->C2->L2->C3...,用while循环实现   
    #随着k值增加,循环查找更新Lk,直到Lk为空时退出
    #索引从0开始,L[k-2]即为频繁k-1项集
   while (len(L[k-2]) > 0):
        #由频繁k-1项集,->候选k项集Ck
       Ck = aprioriGen(L[k-2], k)
       print'C',k,'=',Ck

        #Ck->频繁k项集Lk
       Lk, supK = scanD(D, Ck, minSupport)
       print'L',k,'=',Lk
        #更新支持度字典,用于加入新的支持度
       supportData.update(supK)
       #候选集Ck中所有元素对应的支持度
       print 'supportData',k,'=',supK
       #累计已经计算的支持度
       print 'supportDataupdate=',supportData
        #将新的频繁k项集加入已有频繁项集的列表中
       L.append(Lk)
        #k加1,用于产生下一项集
       k += 1

    #返回所有频繁项集及支持度列表 
   return L, supportData

#=================================================================
###注意:1,2,3—>4
###上述规则就只有两部分,箭头前称为前件,箭头后称为后件
##
###产生后件为1项的关联规则,频繁项集{1,2,3,4}
###H=[[1],[2],[3],[4]]。
###H中元素依次做关联规则的后项
###1,2,3——>4 
###1,2,4——>3 
###1,3,4——>2
###2,3,4——>1        
##
###产生后件为2项的关联规则,频繁项集{1,2,3,4}
###H = [[3,4],[2,4],[2,3],[1,4],[1,3],[1,2]]。
###H中元素依次做关联规则的后项
###1,2——>3,4 
###1,3——>2,4 
###1,4——>2,3
###2,3——>1,4        
###2,4——>1,3
###3,4——>1,2
#=================================================================

#***产生关联规则
#输入:频繁项集列表L,支持度列表,最小置信度 
#输出:满足最小置信度的规则列表
def generateRules(L, supportData, minConf=0.7):  
    #置信度规则列表,最后返回
    bigRuleList = []

    #无法从频繁1-项集L[0]中构建关联规则
    #所以从频繁2-项集开始遍历(索引从1开始)
    for i in range(1, len(L)): 
        #遍历当前频繁项集的每一个项集
        #如频繁2项集为:[[1,2],[3,4]]
        for freqSet in L[i]:
            #如取项集为[1,2],则H1为[[1],[2]],单个元素组成
            H1 = [frozenset([item]) for item in freqSet]
            #H1为规则后件
            #频繁项集中元素个数大于2,H1需要不断合并作为整体
            #并利用最小置信度进行过滤
            if (i > 1):
                #L3,L4...项集
                rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
            else: #L2
                #项集只有2个元素即频繁2项集,直接计算置信度进行过滤
                calcConf(freqSet, H1, supportData, bigRuleList, minConf)
    #返回最后满足最小置信的规则列表
    return bigRuleList  

#根据最小置信度过滤候选的关联规则,并返回过滤后的规则的后件
###输入freqSet:某频繁项集、
###      H:关联规则的后件
###supportData:所有项集的支持度
###brl:填充关联规则:前件,后件,置信度
###minConf:最小置信度
def calcConf(freqSet, H, supportData, brl, minConf=0.7):
   #满足最小可信度要求的后件
   prunedH = [] 
    #遍历H中的所有项,用作关联规则的后件
   for conseq in H:
        #置信度计算
       conf = supportData[freqSet]/supportData[freqSet-conseq] 
        #过滤
       if conf >= minConf:
           #显示:前件 -->后件:置信度         
           print freqSet-conseq,'-->',conseq,'conf:',conf
            #保存关联规则:前件,后件,置信度
           brl.append((freqSet-conseq, conseq, conf))
            #满足最小可信度要求的后件
           prunedH.append(conseq)
    #返回满足条件的后项      
   return prunedH

#***基于某个频繁项集,生成关联规则
#输入:频繁项集、关联规则后件列表H、支持度列表
#brl需要填充的规则列表,最后返回
def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
    #后件中的项的个数
    m = len(H[0])
    #规则后件H的项的个数 比频繁项集freqSet中的项的个数少1,
    #超过该条件无法产生关联规则

    if m==1: #后件只有一个项
        #过滤只有一个项的后件(产生规则如1,2,3->4,并返回过滤后的后件)
        H = calcConf(freqSet, H, supportData, brl, minConf)

    if (len(freqSet) > (m + 1)):
        #对后件H元素组合,产生更多的候选规则后件
        #由[1,2],[1,3]组合成[1,2,3]
        Hmp1 = aprioriGen(H, m+1)
        Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
        #过滤后Hmp1
        #如果满足要求的规则不止一条
        #继续使用Hmp1调用函数rulesFromConseq()
        #判断是否可以进一步组合这些规则。
        if (len(Hmp1) > 1):
            rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)


if __name__ == "__main__":

    #***生成频繁项集
    dataSet=loadDataSet()
    print 'dataSet=',dataSet
    L,supportdata=apriori(dataSet,minSupport = 0.4)
    print'L=',L
    print'supportdata=',supportdata

    print'-------------------------------------'
    #***产生关联规则
    rules=generateRules(L,supportdata,minConf=0.5)
    print 'rules=',rules


    # #***毒蘑菇数据测试
    # mushDatSet=[line.split() for line in open('mushroom.dat').readlines()]
    # L,supportdata=apriori(mushDatSet,minSupport=0.3)
    # #与毒蘑菇出现频繁的1项:
    # for item in L[1]:
    #     if item.intersection('2'):
    #         print item

    # #与毒蘑菇出现频繁的3项:
    # for item in L[3]:
    #     if item.intersection('2'):
    #         print item

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值