详解十大数据挖掘算法之一的Apriori算法

本文始发于个人公众号:TechFlow,原创不易,求个关注


今天是机器学习专题的第19篇文章,我们来看经典的Apriori算法。

Apriori算法号称是十大数据挖掘算法之一,在大数据时代威风无两,哪怕是没有听说过这个算法的人,对于那个著名的啤酒与尿布的故事也耳熟能详。但遗憾的是,随着时代的演进,大数据这个概念很快被机器学习、深度学习以及人工智能取代。即使是拉拢投资人的创业者也很少会讲到这个故事了,虽然时代的变迁令人唏嘘,但是这并不妨碍它是一个优秀的算法。

我们来简单回顾一下这个故事,据说在美国的沃尔玛超市当中,啤酒和尿布经常被摆放在同一个货架当中。如果你仔细观察就会觉得很奇怪,啤酒和尿布无论是从应用场景还是商品本身的属性来分都不应该被放在一起,为什么超市要这么摆放呢?

看似不合理的现象背后往往都有更深层次的原因,据说是沃尔玛引进了一种全新的算法,它分析了所有顾客在超市消费的记录,然后计算商品之间的关联性,发现这两件商品的关联性非常高。也就是说有大量的顾客会同时购买啤酒和尿布这两种商品,所以经过数据的分析,沃尔玛下令将这两个商品放在同一个货架上进行销售。果然这么一搞之后,两种商品的销量都提升了

这个在背后分析数据,出谋划策充当军师一样决策的算法就是Apriori算法。

关联分析与条件概率

我们先把这个故事的真假放在一边,先来分析一下故事背后折射出来的信息。我们把问题进行抽象,沃尔玛超市当中的商品种类大概有数万种,我们的算法做的其实是根据售卖数据计算分析这些种类之间的相关性。专业术语叫做关联分析,这个从字面上很好理解。但从关联分析这个角度出发,我们会有些不一样的洞见。

我们之前都学过条件概率,我们是不是可以用条件概率来反应两个物品之间的关联性呢?比如,我们用A表示一种商品,B表示另外一种商品,我们完全可以根据所有订单的情况计算出P(A|B)和P(B|A),也就是说用户在购买了A的情况下会购买B的概率以及在购买B的情况下会购买A的概率。这样做看起来也很科学啊,为什么不这样做呢,还要引入什么新的算法呢?

这也就是算法必要性问题,这个问题解决不了,我们好像会很难说服自己去学习一门新的算法。其实回答这个问题很简单,就是成本。大型超市当中的商品一般都有几万种,而这几万种商品的销量差异巨大。一些热门商品比如水果、蔬菜的销量可能是冷门商品,比如冰箱、洗衣机的上千倍甚至是上万倍。如果我们要计算两两商品之间的相关性显然是一个巨大的开销,因为对于每两个商品的组合,我们都需要遍历一遍整个数据集,拿到商品之间共同销售的记录,从而计算条件概率。

我们假设商品的种类数是一万,超市的订单量也是一万好了,那么两两商品之间的组合就有一亿条,如果再乘上每次计算需要遍历一次整个数据集,那么整个运算的复杂度大概会是一万亿。如果再考虑多个商品的组合,那这个数字更加可怕。

但实际上一个大型超市订单量肯定不是万级别的,至少也是十万或者是百万量级甚至更多。所以这个计算的复杂度是非常庞大的,如果考虑计算带来的开销,这个问题在商业上就是不可解的。因为即使算出来结果带来的收益也远远无法负担付出的计算代价,这个计算代价可能比很多人想得大得多,即使是使用现成的云计算服务,也会带来极为昂贵的开销。如果考虑数据安全,不能使用其他公司的计算服务的话,那么自己维护这些数据和人工带来的消耗也是常人难以想象的。

如果想要得出切实可行的结果,那么优化算法一定是必须的,否则可能没有一家超市愿意付出这样的代价。

在我们介绍Apriori算法之前,我们可以先试着自己思考一下这个问题的解法。我真的试着想过,但是我没有得到很好的答案,对比一下Apriori算法我才发现,这并非是我个人的问题,而是因为我们的思维有误区。

如果你做过LeetCode,学过算法导论和数据结构,那么你在思考问题的时候,往往会情不自禁地从最优解以及最佳解的方向出发。反应在这个问题当中,你可能会倾向于找到所有高关联商品,或者是计算出所有商品对之间的关联性。但是在这个问题当中,前提可能就是错的。因为答案的完备性和复杂度之间往往是挂钩的,找出所有的答案必然会带来更多的开销,而且落实在实际当中,牺牲一些完备性也是有道理的。因为对于超市而言,更加关注高销量的商品,比如电冰箱和洗衣机,即使得出结论它们和某些商品关联性很高对超市来说也没有太大意义,因为电冰箱和洗衣机一天总共也卖不出多少台。

你仔细思考就会发现这个问题和算法的背景比我们一开始想的和理解的要深刻得多,所以让我们带着一点点敬畏之心来看看这个算法的详细吧。

频繁项集与关联规则

在我们具体了解算法的原理之前,我们先来熟悉两个术语。第一个属于叫做频繁项集,英文是frequent item sets。这个翻译很接地气,我们直接看字面意思应该就能理解。意思是经常会出现在一起的物品的集合。第二个属于叫做关联规则,也就是两个物品之间可能存在很强的关联关系。

用啤酒和尿布的故事举个例子,比如很多人经常一起购买啤酒和尿布,那么啤酒和尿布就经常出现在人们的购物单当中。所以啤酒和尿布就属于同一个频繁项集,而一个人买了啤酒很有可能还会购买尿布,啤酒和尿布之间就存在一个关联规则。表示它们之间存在很强的内在联系。

有了频繁项集和关联规则我们会做什么事情?很简单会去计算它们的概率

对于一个集合而言,我们要考虑的是整个集合出现的概率。在这个问题场景当中,它的计算非常简单。即用集合当中所有元素一起出现的次数,除以所有的数据条数。这个概率也有一个术语,叫做支持度,英文称作support。

对于一个关联规则而言,它指的是A物品和B物品之间的内在关系,其实也就是条件概率。所以A->B关联规则的概率就是P(AB)/P(A)和条件概率的公式一样,不过在这个问题场景当中,也有一个术语,叫做置信度,英文是confidence。

其实confidence也好,support也罢,我们都可以简单地理解成出现的概率。这是一个计算概率的模型,可以认为是条件概率运算的优化。其中关联规则是基于频繁项集的,所以我们可以先把关联规则先放一放,先来主要看频繁项集的求解过程。既然频繁项集的支持度本质上也是一个概率,那么我们就可以使用一个阈值来进行限制了。比如我们规定一个阈值是0.5,那么凡是支持度小于0.5的集合就不用考虑了。我们先用这个支持度过一遍全体数据,找出满足支持度限制的单个元素的集合。之后当我们寻找两个元素的频繁项集的时候,它的候选集就不再是全体商品了,而只有那些包含单个元素的频繁项集。

同理,如果我们要寻找三项的频繁项集,它的候选集就是含有两项元素的频繁项集,以此类推。表面上看,我们是把候选的范围限制在了频繁项集内从而简化了运算。其实它背后有一个很深刻的逻辑,即不是频繁项集的集合,一定不可能构成其他的频繁项集。比如电冰箱每天的销量很低,它和任何商品都不可能构成频繁项集。这样我们就可以排除掉所有那些不是频繁项集的所有情况,大大减少了运算量。

上图当中的23不是频繁项集,那么对应的123和023显然也都不是频繁项集。其实我们把这些非频繁的项集去掉,剩下的就是频繁项集。所以我们从正面或者是反面理解都可以,逻辑的内核是一样的。

Apriori算法及实现

其实Apriori的算法精髓就在上面的表述当中,也就是根据频繁项集寻找新的频繁项集。我们整理一下整个算法的流程,然后一点点用代码来实现它,对照代码和流程很容易就搞清楚了。

首先,我们来创建一批假的数据用来测试:

def create_dataset():
    return [
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值