• 关联规则代码实现


    1.Apripri算法

            问题:

            在探究关联规则时,会得到如图所示的一颗树,每棵树都是一种可能,n个物品的关联一共有2^n-1种可能。这无疑是巨大的运算量

            但是我们可以从中发现一些规律,如果说一个项是非频繁集,那么它的超集也是非频繁集,根据支持度的计算方法,我们可以知道超集的支持度是要小于它本身的项的。因此,项为非频繁集,超级也必定为非频繁集。

            因此,我们可以从上往下进行遍历,并只遍历频繁集的超集

            具体过程为: 

            首先我们遍历一项集,并去掉非频繁集,然后再遍历二巷集,最后,我们再进行一次合并,如图所示,L2的结果有2,3/2,5/3,5,我们就可以合并为(2,3,5)

     

     2.代码实现

            创建数据,首先,我们创建如上图所示的数据

    1. def loadDataSet():
    2. return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]]

             然后我们创建一个冻住的集合,里面包含所有的一元项。

    1. ef createC1(dataSet):
    2. C1 = []
    3. for transaction in dataSet:
    4. for item in transaction:
    5. if not [item] in C1:
    6. C1.append([item])
    7. C1.sort()
    8. return list(map(frozenset,C1))

            对于扫描模块,首先需要计算得到每一个项出现的次数,以求出支持度,并筛选出超过阈值的项集,进行后续的操作。

    1. def scanD(D,CK,minSupport):
    2. ssCnt = {}
    3. for tid in D:
    4. for can in CK:
    5. if can.issubset(tid):
    6. if not can in ssCnt: # 项为上面数据的子集
    7. ssCnt[can] = 1 # 项不在字典中
    8. else:
    9. ssCnt[can] += 1 # 项在字典中
    10. numItems = float(len(list(D)))
    11. retlist = []
    12. supportData = {}
    13. for key in ssCnt:
    14. support = ssCnt[key]/numItems
    15. if support >= minSupport: # 对项的支持度进行筛选
    16. retlist.insert(0,key)
    17. supportData[key] = support
    18. return retlist,supportData

             拼接操作,如代码所示,对于1项集,L1和L2为空,直接进行拼接。对于二项集,如果第一个项相同,则可以进行拼接操作。

    1. def aprioriGen(LK,k):
    2. retlist = []
    3. lenLK = len(LK)
    4. for i in range(lenLK):
    5. for j in range(i+1,lenLK):
    6. L1 = list(LK[i])[:k-2]
    7. L2 = list(LK[j])[:k-2]
    8. if L1 == L2:
    9. retlist.append(LK[i]|LK[j])
    10. return retlist

            挖掘频繁项集,如上图所示,首先扫描一项集,然后进行拼接,一项集直接拼接,2项集第一项相同也进行拼接。最后更新项集和对应的支持度。

    1. def apriori(dataSet,minSupport=0.5):
    2. C1 = createC1(dataSet)
    3. L1,supportData = scanD(dataSet,C1,minSupport)
    4. L = [L1]
    5. k = 2
    6. while(len(L[k-2]) > 0):
    7. CK = aprioriGen(L[k-2],k)
    8. LK,supk = scanD(dataSet,CK,minSupport)
    9. supportData.update(supk)
    10. L.append(LK)
    11. k += 1
    12. return L,supportData

            规则生成模块,首先,我们需要取出多元项集中的每一项,比如【2,3,5】,取出每一个项,[2],[3],[5]。然后计算置信度。如果是二元项集,如[2,3],就分别计算[2],[3]和[3],[2]之间的置信度。如果是三元项集,如[2,3,5],就计算[2],[3,5]以及[3],[2,5],[5],[2,3]的置信度。

    代码如下:

    1. def generateRules(L,supportData,minConf=0.6):
    2. rulelist = []
    3. for i in range(1,len(L)):
    4. for freqSet in L[i]:
    5. H1 = [frozenset([item])for item in freqSet]
    6. rulessFromConseq(freqSet,H1,supportData,rulelist,minConf)
    7. def rulessFromConseq(freqSet,H,supportData,rulelist,minConf=0.6):
    8. m=len(H[0])
    9. while (len(freqSet) > m):
    10. H = calConf(freqSet,H,supportData,rulelist,minConf)
    11. if (len(H)>1):
    12. aprioriGen(H,m+1)
    13. m += 1
    14. else:
    15. break
    16. def calConf(freqSet,H,supportData,rulelist,minConf=0.6):
    17. prunedh = []
    18. for conseq in H:# 置信度的计算
    19. conf = supportData[freqSet]/supportData[freqSet-conseq]
    20. if conf >= minConf:
    21. print (freqSet-conseq,'-->',conseq,'conf:',conf)
    22. rulelist.append((freqSet-conseq,conseq,conf))
    23. prunedh.append(conseq)
    24. return prunedh

            执行代码,结果如下:

    1. if __name__ == '__main__':
    2. dataSet = loadDataSet()
    3. L,support = apriori(dataSet)
    4. i = 0
    5. for freq in L:
    6. print ('项数',i+1,':',freq)
    7. i+=1
    8. rules = generateRules(L,support,minConf=0.5)

     

     

     

  • 相关阅读:
    【Redis】Redis安装步骤和特性以及支持的10种数据类型(Redis专栏启动)
    【go零基础】go-zero从零基础学习到实战教程 - 0环境配置
    JS中改变this指向的六种方法
    Spring整合RabbitMQ-注解方式
    2020-java中级面试题
    【软考 系统架构设计师】嵌入式系统③ 嵌入式系统软件
    Wordtune:文本编辑工具
    Spring和Spring Boot区别
    闲人闲谈PS之三十——新收入准则中的合同资产和合同负债
    HCIP-综合实验 知识覆盖全面 建议收藏
  • 原文地址:https://blog.csdn.net/qq_52053775/article/details/127042876