Apriori算法解析

背景介绍

维克多迈尔在《大数据时代》中,提出了大数据时代跟传统的信息时代相比,最本质的三个思维变革:1. 要全体数据,而不仅是样本;2. 要混杂,而不要效率偏低的精确;3. 要相关关系,而不是因果关系。这第三条说的就是数据挖掘中,最基础,最简单,也是最为重要的应用——数据相关关系的挖掘。相关关系,其实是数据中蕴含的最直接的知识,而对这种相关关系的挖掘,如今也早已应用到推荐系统,个性化检索,机器学习,以及很多更加高级的领域。所以说,相关关系的挖掘,第一,它极为重要,它几乎是数据挖掘和传统数据分析侧重点的分水岭,在如今这个数据时代,它是最重要也是最基本的数据技能;第二,它不难,一般的相关关系挖掘,不需要太过精深的理论;第三,它很普及,已经渗入了生活的方方面面。而这个问题入门级的算法,就是本文要说的Apriori算法,也叫“先验算法”。

当然,Apriori算法虽然本身不难,也容易理解,但是还是有必要学习一下它的产生思路。一来能有个更深入的认识,二来,也算是对数据相关关系基本特征有个理解。所以,我将用较大的一个篇幅,说明Apriori的相关背景。这一点,我觉得比学习算法本身,更有意义。

这首先得从生活中最普通的购物篮说起,我们去买东西,经常把一下商品放在一起购买,比如,我去买红酒,可能会连带着酒杯一起,我去买被子,可能会连带着枕头一起。因为,这些东西其实背后是存在着某种关联的。当然,我们不妨像维克多迈尔说的那样,先不用去管这样东西背后到底是为什么关联起来的,这是科学家和哲学家想的事情,作为商店的老板,你需要想的,只是知道什么东西之间存在关联就可以了。这样,就能通过对商店里商品的摆放,提高你的营业额。一个著名的例子是沃尔玛超市的“啤酒”和“尿布”。

购物篮的例子,可以用来说明两个问题:

  • 在很多生活实例中,确实事物之间会存在某种关系,或强或弱,而如果我们能通过计算发现这种关联,那就太有用了!
  • 发现这种关联的一个前提条件,就是我得知道哪些东西是经常在一起出现的。

上面两点,就是Apriori算法产生的原因。

相关概念

下面为了说明方便,会给出一些概念,当然,这些概念我不想给出很精确的定义,因为你在任何一个搜索引擎都能查到。我只是给出最容易理解的解释。

  1. 项(item): 项指的是具体的一件东西,比如在购物篮的例子中,你的购物篮里面的大米,被子,红酒等等商品都是项;
  2. 项集(itemset): 顾名思义,项的集合,由一个或多个项组成的一个整体,我们把由 k 个项组成的项集叫 k 项集;
  3. 事务(transaction):一个事务,可以看做是发生的一次事件,比如一个人一次的购物清单,用符号 T 表示,一般来说, T 包含一个它本身的身份—— TID 以及事务中的一个项集。当然,如果我们收集很多这样的清单,构成一个数据库,这个数据库就能作为我们挖掘计算的依据了。这个库,用符号 D 表示。
  4. 关联规则:表示实体之间相关关系,用蕴含式 AB 表示A和B之间相关关系(A和B可以是两个项,也可以是两个项集),关联规则包含支持度(support)和置信度(confidence)两个层面指标;
  5. 支持度(support)和置信度(confidence):这两个标准在数据相关关系中特别重要,我们判断两个实体之间是否存在相关关系,依据就是这两个标准。下面分开来说。假设现在的问题是判断A和B之间相关关系的强弱;
    • 支持度(support):说的是所有事务中,A和B同时出现的次数与总的事务数的比例。换个说法,现实数据中,支持A和B这种关联的比例。用以下公式计算:
      support(AB)=P(AB)
      其中, P(AB) 的意思是事务中同时包含A和B的比例;
    • 置信度(confidence): AB 的置信度说的是包含A的事务中,同时也包含B的事务所占的比例。用以下公式计算:
      confidence(AB)=P(B|A)
      比如说,总共100个事务,有50个包含A,而这50个事务当中,又有20个同时也包含B,那么, confidence(AB)=40%
      了解了支持度(support)和置信度(confidence)两个概念,那么不妨可以再深入一步,拓展一个概念:绝对支持度;
  6. 支持度计数(绝对支持度):绝对支持度又叫支持度计数,频度或计数。上面我们定义的支持度其实也可以叫“相对支持度”,而绝对支持度则说的是一个实体出现的次数,比如:support(A) = A在全体事务数据库 D 中出现的次数。这个概念很重要,因为依靠支持度计数我们就能通过 support(A) support(AB) 来计算置信度:
    confidence(AB)=P(B|A)=support(AB)support(A)
  7. 强规则:我们将实体之间的关联规则定义为强规则,如果实体之间的相对支持度(support)和置信度(confidence)满足我们预定义的最小支持度阈值(min_sup)和最小置信度阈值(min_conf)。换句话说,只要我们在上面的概念5中定义的两个指标都满足,那么,实体之间就是极有强(关联)规则的;
  8. 频繁项集:指的是频繁在事务中出现的项集,所谓“频繁”的标准就是这个项集出现的次数满足最小支持度计数(阈值)。

算法原理

好了,到此,将5,6,7,8四个概念统一起来,我们可以得到一个结论:实体间关联规则的强弱可以通过它们的相对支持度和置信度决定,而这两个指标又可以通过绝对支持度: support(A) support(AB) 来计算。所以说,关联规则挖掘也就可以转化为频繁项集的挖掘。

这样,关联规则的挖掘是一个两步的过程:

  1. 找出所有的频繁项集:根据相对支持度,置信度的定义可知,任意两个实体之间如果存在强关联规则,那么一定存在于频繁项集之中,反之,如果这两个实体不存在于频繁项集,则一定不会产生强关联规则
  2. 由频繁项集产生强关联规则:计算支持度和置信度,找到实体间的强规则

显然,当我们确定了要分析的实体之后,第二步的开销就很小了。关键是第一步:挖掘频繁项集。而Apriori算法解决的就是这个问题。

Apriori翻译成中文是“先验”,所以,不难想到,先验性质就是整个Apriori的核心。

定理1先验性质:频繁项集的所有非空子集也一定是频繁的。

说明:这个概念很容易理解了,比如一个项集 { I1,I2,I3} 是频繁的,那么,说明这三个项同时出现的次数是大于最小支持度计数的,所以,我们可以推知,他的任何非空子集, { I1} , { I2,I3} 等等的支持度计数也一定比预先定义的阈值要大,故而都是频繁的。

反过来,我们可以换个角度来思考这个问题,如果一个项集 I 是频繁的,那么给这个项集在加一个项 A ,则这个新的项集 { IA} 则至少不会比 I 更加频繁,因为加了东西,所以项集中所有项同时出现的次数一定不会增加。

进一步思考可以得到这样一个结论:如果项集 I 是非频繁的,那么无论给它增加什么项,多少项,他都不会变成频繁项集。这种特殊的性质,也叫“反单调性”。我们将这种“反单调性”换个说法,写成下面的定理2:

定理2反单调性:一个项集,如果有至少一个非空子集是非频繁的,那么这个项集一定是非频繁的。

正是利用了上面的定理1,定理2,Apriori被设计出来,它通过逐层搜索的模式,由频繁 k1 项集生成频繁 k 项集,从而最终得到全部的频繁项集。

可见,Apriori最核心的部件就是怎样通过频繁

  • 4
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
下面是Apriori算法的Python代码,配合注释进行解析: ```python # 导入必要库 import itertools # 定义一个函数,用于生成频繁项集 def frequent_itemsets(transactions, support): itemsets = {} # 计算每个项的出现次数 for transaction in transactions: for item in transaction: if item not in itemsets: itemsets[item] = 0 itemsets[item] += 1 # 过滤掉不满足支持度的项 itemsets = {k:v for k,v in itemsets.items() if v >= support} # 构建初始频繁项集 freq_itemsets = [[item] for item in itemsets] freq_itemsets.sort() # 循环生成更高阶频繁项集 k = 2 while True: # 构建候选项集 candidates = [list(x) for x in itertools.combinations(itemsets, k)] for transaction in transactions: for candidate in candidates: if set(candidate).issubset(set(transaction)): tuple_candidate = tuple(candidate) if tuple_candidate not in itemsets: itemsets[tuple_candidate] = 0 itemsets[tuple_candidate] += 1 # 过滤掉不满足支持度的项 itemsets = {k:v for k,v in itemsets.items() if v >= support} # 将满足支持度的项加入频繁项集 freq_itemsets.extend(list(itemsets.keys())) freq_itemsets.sort() # 如果没有新的频繁项集生成,则退出循环 if not itemsets: break k += 1 # 返回频繁项集 return freq_itemsets ``` 该代码实现了Apriori算法的频繁项集生成过程,主要分为以下几个步骤: 1. 计算每个项在所有交易中的出现次数,过滤掉不满足支持度的项; 2. 构建初始频繁项集,即单个频繁项,排序后加入频繁项集列表; 3. 循环生成更高阶的频繁项集,每次生成候选项集,并计算其在所有交易中的出现次数,过滤掉不满足支持度的项,并将满足支持度的项加入频繁项集列表; 4. 如果没有新的频繁项集生成,则退出循环,返回频繁项集列表。 该代码中用到了Python的itertools库,其中combinations()函数用于生成候选项集,它接受一个列表和一个整数k作为参数,会返回一个包含所有长度为k的组合的列表。另外,该代码中使用了字典来保存每个项的出现次数,以及保存频繁项集。最后,该代码返回的频繁项集是以列表形式返回的,每个元素都是一个包含若干项的元组。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值