• 关联规则代码实现


    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)

     

     

     

  • 相关阅读:
    leetcode-电话号码组合(C CODE)
    R语言使用lm函数拟合线性回归模型:使用predict函数和训练好的模型进行预测推理、使用plot函数可视化线图对比预测值和实际值曲线
    【PG】PostgreSQL高可用方案repmgr部署(非常详细)
    Programming Languages PartB Week2学习笔记——用Racket编写解释器
    语法基础(判断语句)
    Python数据处理Tips多层嵌套Json数据展平到DataFrame
    Ansys Zemax | 使用 OpticStudio 进行闪光激光雷达系统建模(上)
    What’s new in Grafana v11.0-preview
    【python3】5.正则表达式
    MODBUS-RTU从站通信(SMART PLC作为MODBUS-RTU从站)
  • 原文地址:https://blog.csdn.net/qq_52053775/article/details/127042876