【Python机器学习】Apriori算法——从频繁项集中挖掘关联规则

利用关联分析可以返现许多有趣的内容,其中人们最长寻找的两个目标是频繁项集语关联规则。要想找到关联规则,首先从一个频繁项集开始。

我们知道集合中的元素是不重复的,但我们想知道基于这些元素能否获得其他内容。某个元素或者某个元素集合可能会推导出另一个元素。从杂货铺的例子可以得到,如果有一个频繁项集{豆奶、莴苣},那么就可能有一条关联规则“豆奶→莴苣”。这意味着如果有人购买了豆奶,那么在统计上他会购买莴苣的概率较大。但是,这一条反过来并不总是成立。也就是说,“豆奶→莴苣”统计上显著,那么“莴苣→豆奶”也不一定成立。(从逻辑研究上来说,箭头左边的集合称为前件,右边的集合称为后件)。

频繁项集的量化定义是它满足最小支持度要求。对于关联规则,我们也有类似的量化方法,这种量化指标称为可信度。一条规则p右箭头H的可信度定义为support(P|H)/support(P)。

从一个频繁项集中可以产生多少条关联规则呢?下图给出的是从项集{1,2,3,4}产生的所有关联规则:

为了找到感兴趣的规则,我们先生成一个可能的规则列表,然后测试每条规则的可信度。如果可信度不满足最小要求,则去掉该规则。

类似于频繁项集的生成,我们可以为每个频繁项集产生许多关联规则。如果能够减少规则数目来确保问题的可解性,那么计算起来会好很多。可以观察到,如果某条规则并不满足最小可信度要求,那么该规则的所有子集也不会满足最小可信度要求。以上图为例,假设规则012→3并不满足最小可信度要求,那么就知道任何左部为{0,1,2}子集的规则也不会满足最小可信度要求。

可以利用关联规则的上述性质属性来减少所需要测试的规则数目。可以从一个频繁项集开始,接着创建一个规则列表,其中规则右部只包含一个元素,然后对这些规则进行测试。接下来合并所有剩余规则来创建一个新的规则列表,其中规则右部包含两个元素。这种方法也被称为分级法。

代码实现:

def generateRules(L,supportData,minConf=0.7):
    bigRuleList=[]
    #只获取有两个或更多元素的集合
    for i in range(1,len(L)):
        for freqSet in L[i]:
            H1=[frozenset([item]) for item in freqSet]
            if (i>1):
                rulesFromConseq(freqSet,H1,supportData,bigRuleList,minConf)
            else:
                calcConf(freqSet,H1,supportData,bigRuleList,minConf)
    return bigRuleList
def calcConf(freqSet,H,supportData,brl,minConf=0.7):
    prunedH=[]
    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
def rulesFromConseq(freqSet,H,supportData,brl,minConf=0.7):
    m=len(H[0])
    if (len(freqSet)>(m+1)):
        Hmp1=aprioriGen(H,m+1)
        Hmp1=calcConf(freqSet,Hmp1,supportData,brl,minConf)
        if (len(Hmp1)>1):
            rulesFromConseq(freqSet,Hmp1,supportData,brl,minConf)

上述代码中包含三个函数,其中generateRules()为主函数,它调用其他两个函数,其中rulesFromConseq()用于生成候选规则集合,calcConf()用于对规则进行评估。

函数generateRules()有3个参数:频繁项集列表、包含那些频繁项集支持数据的字典、最小可信度阈值。函数最后要生成一个包含可信度的规则列表,后面可以基于可信度对它们进行排序,这些规则存放在bigRuleList中。如果实现没有给定最小可信度的阈值,就默认设置为0.7。generateRules()的另外两个输入参数是apriori()的输出结果,该函数遍历L中的每一个频繁项集并对每个频繁项集创建只包含单个元素集合的列表H1.因为无法从单元素项集中构建关联规则,所以要从包含两个或者更多元素的项集开始规则构建过程。如果从集合{0,1,2}开始,那么H1应该是[{0},{1},{2}]。如果频繁项集的元素数目超过2,那么会考虑对它做进一步非合并。具体合并可以通过rulesFromConseq()来完成。如果项集中只有两个元素,那么使用calcConf()计算可信度值。

我们的目标是计算规则的可信度以及找到满足最小可信度要求的规则。所以这些可以使用函数calcConf()来完成,而其他代码都用来准备规则。函数会返回一个满足最小可信度要求的规则列表,为了保存这些规则,需要创建一个空列表prunedH。接下来,遍历H中的所有项集并计算它们的可信度值。可信度计算时使用supportData中的支持度数据。通过导入这些支持度数据,可以节省大量计算时间。如果某条规则满足最小可信度值,那么将这些规则输出,。通过检查的规则也会被返回,并被用在下一个函数rulesFromConseq()中,同时也需要对列表brl进行填充,而brl是前面通过检查bigRuleList。

为从最初的项集中生成更多的关联规则,可以使用rulesFromConseq()函数,该函数有2个参数:一个是频繁项集,另一是可以出现在规则右部的元素列表H。函数先计算H中的频繁集大小m。接下里是查看该频繁项集是否大到可以移除大小为m的子集。如果可以的话,则将其移除。可以使用aprioriGen()来生成J中元素的无重复组合。该结果会存储在Hmp1中,这也是下一次迭代的H列表,Hmp1包含所有可能的规则。可以利用calcConf()来测试它们的可信度以确定规则是否满足要求。如果不止一条规则满足要求,那么使用Hmp1迭代调用函数rulesFromConseq()来判断是否可以进一步组合这些规则。

代码运行效果:

dataSet=loadData()
L,supportData=apriori(dataSet,minSupport=0.5)
rules=generateRules(L,supportData,minConf=0.7)
print(rules)

结果出给出3条规则:{1}→{3}、{5}→{2}、{2}→{5},可以看到,后两条包含2和5的规则可以交换前件和后件,但是前一条包含1和3的规则不行。

下面降低可信度阈值看一下结果:

dataSet=loadData()
L,supportData=apriori(dataSet,minSupport=0.5)
rules=generateRules(L,supportData,minConf=0.5)
print(rules)

一旦降低可信度阈值,就可以获得更多的规则。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值