机器学习实战第十一章 - 使用Apriori算法进行关联分析

本文深入探讨了关联分析的基础,包括频繁项集和关联规则,并详细介绍了Apriori算法的工作原理。通过实例展示了如何生成候选项集、挖掘频繁项集以及从频繁项集中提炼关联规则。文章还提供了Python代码实现,帮助读者理解并应用Apriori算法。
摘要由CSDN通过智能技术生成

一,关联分析(或关联规则学习)

关联分析是一种在大规模数据集中寻找有趣关系的任务。这些关系主要有两种形式:

  • 频繁项集:经常出现在一块的物品的集合。
  • 关联规则:暗示两种物品之间可能存在很强的关系。

量化关联分析是否成功的评价准则也有两个:

  • 支持度(support):支持度是针对频繁项集来定义的,一个项集的支持度被定义为数据集中包含该项集的记录所占的比例。
  • 置信度(confidence):置信度是针对关联规则来定义的。例如{尿布}->{啤酒}这条关联规则的置信度为:support({尿布,啤酒})/support({尿布})。

二,Apriori原理

对于包含N种物品的数据集共有 2N1 2 N − 1 种项集组合。
例如4个物品的项集组合如下:
1

如果暴力寻找频繁项集会及其的耗时,为了加快寻找的速度,需要用到Apriori原理。

Apriori原理:如果某个项集是频繁的,那么它的所有子集也是频繁的。虽然直观上看并没有什么帮助,但是如果反过来看就有用了。也就是说也就是说如果一个项集是非频繁集,那么它的所有超集也是非频繁的。如下图所示:
2

使用该规则就可以避免项集数目的指数增长,从而在合理时间内计算出频繁项集。

三,使用Apriori算法来发现频繁集

关联分析的目标包括两个:发现频繁项集和发现关联目标。首先需要找到频繁项集,然后才能获得关联规则。
Apriori算法只需要两个参数:数据集和最小支持度。

1,生成候选项集

其中主要的一个辅助函数就是扫描数据集过滤掉那些支持度过低的项集。scanD()伪代码如下:

对数据集中的每一条记录trans
对每个候选集can:
    检查can是否是tran的子集:
        如果是,则增加can的计数。
对每个候选项集:
    如果其支持度不低于最小值,则保留该项集。
返回所有频繁项集列表

Python代码如下:

def loadDataSet():
    return [[1,3,4,],[2,3,5],[1,2,3,5],[2,5]]
def createC1(dataSet):
    C1 = []
    for trans in dataSet:
        for item in trans:
            if [item] not in C1:
                    C1.append([item])
    C1.sort()
    return [frozenset(t) for t in C1]
def scanD(D,Ck,minSupport):
    ssCnt = {}
    for tid in D:
        for can in Ck:
            if can.issubset(tid):
                if can not in ssCnt:
                    ssCnt[can] = 1
                else:
                    ssCnt[can] += 1
    numItems = float(len(D))
    retList = []
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key]/numItems
        if support >= minSupport:
            retList.append(key)
        supportData[key] = support
    return retList,supportData

2,组织完整的Apriori算法

整个Apriori算法的伪代码如下:

当集合中项的个数大于0时
    构建一个k个项组成的候选项集的列表
    检查数据以确定每个项集都是频繁的
    保留频繁项集并构建k+1项组成的候选项集的列表

Python代码如下:

def aprioriGen(Lk,k):  #create Ck
    retList = []
    lenLk = len(Lk)
    for i in range(lenLk):
        for j in range(i+1,lenLk):
            L1 = list(Lk[i])[:k-2]
            L2 = list(Lk[j])[:k-2]
            L1.sort()
            L2.sort()
            if L1==L2:
                retList.append(Lk[i]|Lk[j])
    return retList
def apriori(dataSet,minSupport=0.5):
    D = list(map(set,dataSet))
    C1 = createC1(dataSet)
    L1,supportData = scanD(D,C1,minSupport)
    L = [L1]
    k = 2
    while len(L[k-2])>0:
        Ck = aprioriGen(L[k-2],k)
        Lk,supK = scanD(D,Ck,minSupport)
        supportData.update(supK)
        L.append(Lk)
        k += 1
    return L,supportData

四,从频繁项集中挖掘关联规则

1,从一个频繁项集中产生关联规则

我们先生成一个可能的关联规则列表,然后测试每条规则的可信度,如果可信度不低于最小要求,就去掉该规则。
例如项集{0,1,2,3}产生的所有关联规则如下:
1

怎样来减少需要测试的规则数目的?
利用这一性质:如果某条规则不满足最小可信度要求,那么该规则的所有子集也不会满足最小可信度的要求。如上图阴影部分所示:012->3不满足,则右件包含3的规则都不满足要求。

从频繁项集中挖掘关联规则主要思想如下:

  1. 首先从一个频繁项集开始,接着创建一个规则列表,其中规则右部只包含一个元素,然后对这些规则进行测试。
  2. 接下来合并所有剩余规则来创建一个新的规则列表,其中规则右部包含两个元素。
  3. 循环下去。

这种方法也被成为分级法。

2,Python代码实现

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)

主要难度在rulesFromConseq()。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值