数据挖掘算法-Apriori算法

Apriori算法是一种用于挖掘频繁项集和关联规则的数据挖掘算法。它通过逐层搜索迭代的方式,从频繁1项集开始,逐渐生成更长的频繁项集,直到找不到新的频繁项集为止。算法主要利用反单调性和超集原理减少计算量。文章还介绍了Apriori的C++和Python实现,并探讨了如何从频繁项集生成关联规则。
摘要由CSDN通过智能技术生成

前言

假设你是商场的一名推销员,正与一位刚在商店买了面包的顾客交谈。你应该向她推荐什么产品?你应该想知道你的顾客在购买了面包之后频繁的购买的哪些物品,这些信息是非常有用的。在这种情况下,频繁模式和关联规则正是你想要挖掘的知识。

基本概念

频繁模式(frequent pattern)是指频繁地出现在数据集中的模式,例如频繁的同时出现在交易数据集中的商品(比如牛奶和面包)集合是频繁项集。
如果我们想象全域是商店中商品的集合,则每种商品可以代表一个布尔变量,表示该商品是否被购买过。那么可以用一个“商品A=>商品B”这种形式的布尔向量来表示商品A与商品B的关联程度。如何去衡量这个关联程度呢?我们引入两个测距:支持度与置信度。

支持度(support)代表该关联规则的重要性,定义为集合中商品A出现且商品B出现的次数除以总的商品个数,即support(A=>B) = P(A U B)。
置信度(confidence)代表该关联规则的可靠性,定义为集合中商品A出现且商品B出现的次数除以商品A出现的次数,即confidence(A=>B) = P(B | A)。
因为我们认为满足最小支持度阈值(min_sup)和最小置信度阈值(min_conf)的规则是强规则。这两个最小阈值是由相关领域的专家人为给定的。

项的集合称为项集。包含k个项的项集称为k项集。比如之前提到的面包和牛奶这些商品就可以理解为项,某次购买中购买了商品的集合{牛奶,面包,坚果}就可以称为项集,在本例中也就是3项集。若该项集的支持度与置信度均大于给定的最小值,那么就认为该项集是频繁项集,记作Lk。

那么如何找到这样强关联规则呢?由置信度的定义可以得到
confidence(A=>B) = P(B | A) = support(A U B) / support(A) = support_count(A U B) / support_count(A)
也就是说,如果获得了AUB、A的支持度计数,也就是出现的次数,那么就可以很容易的获得规则A=>B的置信度。因此,关联规则的挖掘就可以演变为 频繁项集的挖掘。

一般方法

那么如何挖掘频繁项集呢?首先可以想到如下算法:

1.输入事务集D,每一个事务都是一个项集(比如代表某一次购买的商品集合),以及总的项集合T、结果集C2.对于T的每一个子集t
    遍历一遍D,统计t在D中出现的次数cnt
    如果cnt大于等于给定的阈值
        那么将t加入结果集C中
    否则就继续

假设共有n项,那么T的子集就有2^n个。上述算法的复杂度就是O(2^n*size(D))。显然指数级的复杂度是难以接受的。因此就轮到本文的主角登场了,Apriori算法(方便称为 爱普弱算法,虽然好像不是这么发音的:D)

Apriori算法

首先介绍一下Apriori性质:
1.若A是一个频繁项集,则A的每一个子集都是一个频繁项集。
该性质具有反单调性,于是我们得到:
2.若A不是一个频繁项集,那么它的所有超集也一定不是频繁的。(超集的意思就是说集合Y的子集为A,且Y不等于A)。
该算法的主要思想是利用 逐层搜索迭代的方法,即用k项集来探索(k+1)项集,我们用Lk来代表频繁k项集,Ck来代表长度为k的候选项集,那么该算法的流程可以概括如下:
L1->C2->L2->C3->L3->…->一直到某一集合为空
那么该算法显然可以概括为如下两个步骤:

Step1.自连接,即如何由Lk产生Ck+1
Step2.剪枝,按如下规则剪枝:
1.根据性质12,如果Ck中的某一k-1子集不在Lk-1中,那么其一定不是频繁项集,可以直接将其剪去。
2.1的基础上,遍历D对每个候选进行计数,得到的结果再与最小支持度比较来进行剪枝。

对于Step1,首先假定事务或项集中的项按字典序排序。对于Lk中的每两个项集,规定若其前k-1项都相同,且前者的第k项小于后者的第k项,那么就把两者求个并,得到一个k+1项的候选项集。
这么做的主要方法是为了避免重复。

下面给出Apriori算法的伪代码,然后给出C++和Python的实现。

算法1 Apriori。使用逐层迭代方法基于候选产生找出频繁项集
输入:
    1.D: 事务数据库
    2.min_sup: 最小支持度阈值
输出: L, D中的频繁项集。
方法:
    (1) L1 = find_frequent_itemsets(D) //首先找出频繁1项集
    (2) for (k=2; Lk-1 != 空集; k++) {
    (3)   Ck = apriori_gen(Lk-1);
    (4)   for each 事务t∈D {   //扫描D,进行计数
    (5)       Ct = subset(Ck, t);
    (6)       for each 候选c∈Ct
    (7)          c.count++;
    (8)   }
    (9)   Lk = {c(Ck|c.count >= min_sup)}
    (10) }
    (11) return L = 所有Lk的集合

    procedure apriori_gen(Lk-1: frequent(k-1) itemset)
    (1)  for each 项集l1∈Lk-1
    (2)    for each 项集l2∈Lk-1
    (3)      if (l1[1]==l2[1]) && (l1[2]==l2[2]) && ... &&
    (4)          (l1[k-2] == l2[k-2]) && (l1[k-1] < l2[k-1]) {
    (5)          c = l1 link l2;
    (6)          if has_infrequent_subset(c, Lk-1) then
    (7)             delete c;
    (8)          else add c to Ck;
    (9)return Ck;

    producer has_infrequent_subset(c: candidate k itemset; Lk-1: frequent(k-1 itemset))
    (1) for each(k-1) subset sof c
    (2)   if s 不属于 Lk-1 then
    (3)     
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值