第六章 Apriori算法

1、Apriori算法介绍

        Apriori算法是Agrawal和R.Srikant于1994年提出的,为布尔关联规则挖掘频繁项集的原创性算法。算法的名字基于这样的事实:算法使用频繁项集性质的先验知识。

        Apriori算法使用一种称为逐层搜索的迭代算法,其中k项集用于探索(k+1)项集。首先,通过扫描数据库,累计每个项的计数,并收集满足最小支持度的项,找出频繁1项集的集合,该集合记为L1。然后,使用L1找出频繁2项集的集合L2,使用L2找出L3,如此下去,直到不能再找到频繁k-项集。找出每个Lk需要一次数据库的完整扫描。

        为了提高频繁项集逐层产生的效率,一种称为先验性质的重要性质用于压缩搜索空间。先验性质:频繁项集的所有非空子集也一定是频繁的

2、连接步和剪枝步

        “如何在算法中使用先验性质?”为理解这一点,我们考察如何使用Lk-1找出Lk,其中k>=2。下面的两步过程由连接步剪枝步组成。

      (1)连接步:为找出Lk,通过将Lk-1与自身连接产生候选k项集的集合。该候选项集的集合记为Ck。设l1l2是Lk-1的项集,为了有效的实现,Apriori算法假定事务或项集中的项按字典序排序。两个项集连接的条件:前k-2项相同,第一个项集的k-1项小于第一个项集的k-1项(为了确保不产生重复)。

      (2)剪枝步:为了压缩Ck,可以使用先验性质。任何非频繁的(k-1)项集都不是频繁k项集的子集。注意,由于Apriori算法使用逐层搜索技术,给定候选k项集后,只需检查它们的(k-1)项所有子集是否频繁。

3、Apriori算法的例子


       上图为某商场的交易记录,共有9个事务,利用Apriori算法寻找所有的频繁项集的过程如下(最小支持度计数为2):


       该过程的中间步骤是递归形式:先自连接、再剪枝、最后再支持度计数

4、Apriori算法伪代码


5、由频繁项集产生关联规则

        一旦由数据库D中的事务找出频繁项集,就可以直接由它们产生强关联规则。对于置信度,可以用下式计算:

                                                    Confidence(A=>B)=P(B|A)=support_count(AB)/support_count(A)

        关联规则产生步骤如下:

        1)对于每个频繁项集l,产生其所有非空真子集;

        2)对于每个非空真子集s,如果support_count(l)/support_count(s)>=min_conf,则输出规则s=>(l-s),其中,min_conf是最小置信度阈值。

        例如,在上述例子中,针对频繁集{I1,I2,I5}。可以产生哪些关联规则?该频繁集的非空真子集有{I1,I2},{I1,I5},{I2,I5},{I1},{I2}和{I5},对应置信度如下:

                                                                         {I1,I2}=>I5       confidence=2/4=50%

                                                                         {I1,I5}=>I2       confidence=2/2=100%     

                                                                         {I2,I5}=>I1       confidence=2/2=100%

                                                                         I1=>{I2,I5}        confidence=2/6=33%

                                                                         I2=>{I1,I5}       confidence=2/7=29%

                                                                         I5=>{I1,I2}       confidence=2/2=100%

        如果min_conf=70%,则强规则有{I1,I5}=>I2,{I2,I5}=>I1,I5=>{I1,I2}。

6、算法的python实现

6.1 使用Apriori算法发现频繁项集

from numpy import *

def loadDataSet():  # 测试数据集 
    return [[1,2,5],[2,4],[2,3],[1,2,4],[1,3],[2,3],[1,3],[1,2,3,5],[1,2,3]]

def createC1(dataSet): # 构建集合C1
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item])
                
    C1.sort()  # C1中的元素进行排序,生成[[1],[2],[3],[4],[5]]
    return map(frozenset, C1)  # 把每个单元列表映射到frozenset(), frozenset是指被“冰冻”的
                               # 集合,就是说它们是不可改变的,这里不能用set,因为之后必须要将
                               # 这些集合作为字典键值使用。
                               
def scanD(D, Ck, minSupport): # 用于从Ck生成Lk,并返回一个包含支持度值的字典supportData以备后用
    ssCnt = {}
    for tid in D:
        for can in Ck:
            if can.issubset(tid): # 计数
                if not ssCnt.has_key(can): 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.insert(0,key)  # 列表的首位置插入字典的关键字
        supportData[key] = support
    return retList, supportData

def aprioriGen(Lk, k): # 其实这里是用Lk-1生成Ck,但这里的Lk-1都直接使用Lk来代替了
    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: # 前k-2个项相同时,将两个集合Lk[i]和Lk[j]合并
                retList.append(Lk[i] | Lk[j]) 
    return retList

def apriori(dataSet, minSupport = 0.22):  # 主函数
    C1 = createC1(dataSet)
    D = map(set, dataSet)
    L1, supportData = scanD(D, C1, minSupport)
    L = [L1]
    k = 2 # 先从L1构建C2开始
    while (len(L[k-2]) > 0):
        Ck = aprioriGen(L[k-2], k)
        Lk, supK = scanD(D, Ck, minSupport) # scan DB to get Lk
        supportData.update(supK) # 更新supportData
        L.append(Lk)
        k += 1
    return L, supportData
运行结果:

>>> ================================ RESTART ================================
>>> 
>>> dataset=loadDataSet()
>>> dataset
[[1, 2, 5], [2, 4], [2, 3], [1, 2, 4], [1, 3], [2, 3], [1, 3], [1, 2, 3, 5], [1, 2, 3]]
>>> L, supportData=apriori(dataset)
>>> L
[[frozenset([1]), frozenset([3]), frozenset([2]), frozenset([5]), frozenset([4])], [frozenset([1, 3]), frozenset([2, 5]), frozenset([2, 3]), frozenset([1, 5]), frozenset([1, 2]), frozenset([2, 4])], [frozenset([1, 2, 5]), frozenset([1, 2, 3])], []]
>>> L[0]  # 频繁1项集
[frozenset([1]), frozenset([3]), frozenset([2]), frozenset([5]), frozenset([4])]
>>> L[1]  # 频繁2项集
[frozenset([1, 3]), frozenset([2, 5]), frozenset([2, 3]), frozenset([1, 5]), frozenset([1, 2]), frozenset([2, 4])]
>>> L[2]  # 频繁3项集
[frozenset([1, 2, 5]), frozenset([1, 2, 3])]
>>> L[3]  # 频繁4项集
[]



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


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Apriori 算法是一种经典的数据挖掘算法,用于发现频繁项集和关联规则。它基于频繁项集性质,通过迭代的方式逐渐增加项集中的元素来搜索频繁项集。 下面是 Apriori 算法的基本流程: 1. 初始化候选项集列表 C_1,包含单个元素的项集。 2. 根据最小支持度阈值,通过扫描数据集,计算每个候选项集的支持度。删除支持度小于阈值的项集。 3. 使用频繁项集列表 L_1 存储第一次扫描得到的频繁项集。 4. 根据频繁项集列表 L_k-1,生成候选项集列表 C_k。C_k 的生成过程是将 L_k-1 中的频繁项集两两组合,并检查是否满足“前缀相同”的性质。 5. 根据最小支持度阈值,通过扫描数据集,计算每个候选项集的支持度。删除支持度小于阈值的项集。 6. 使用频繁项集列表 L_k 存储第 k 次扫描得到的频繁项集。 7. 重复步骤 4 和步骤 5,直到无法生成新的候选项集。 8. 返回所有频繁项集的列表 L。 Apriori 算法的关联规则挖掘步骤如下: 1. 对于每个频繁项集 L_i,生成其所有的非空子集,作为规则的前件。 2. 对于每个前件,生成其对应的后件,即补集。 3. 对于每个规则,计算其支持度和置信度。 4. 根据最小置信度阈值,过滤掉置信度小于阈值的规则。 5. 返回满足条件的关联规则。 这就是 Apriori 算法的基本过程。通过计算频繁项集和关联规则,我们可以发现数据集中的频繁模式和有意义的关联关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值