在美国有这样一家奇怪的超市,它将啤酒与尿布这样两个奇怪的东西放在一起进行销售,并且最终让啤酒与尿布这两个看起来没有关联的东西的销量双双增加。这家超市的名字叫做沃尔玛。

你会不会觉得有些不可思议?虽然事后证明这个案例确实有根据,美国的太太们常叮嘱她们的丈夫下班后为小孩买尿布,而丈夫们在买尿布后又随手带回了他们喜欢的啤酒。但这毕竟是事后分析,我们更应该关注的,是在这样的场景下,如何找出物品之间的关联规则。接下来就来介绍下如何使用Apriori算法,来找到物品之间的关联规则吧。

一. 关联分析概述

选择物品间的关联规则也就是要寻找物品之间的潜在关系。要寻找这种关系,有两步,以超市为例

  1. 找出频繁一起出现的物品集的集合,我们称之为频繁项集。比如一个超市的频繁项集可能有{{啤酒,尿布},{鸡蛋,牛奶},{香蕉,苹果}}
  2. 频繁项集的基础上,使用关联规则算法找出其中物品的关联结果

简单点说,就是先找频繁项集,再根据关联规则找关联物品。

为什么要先找频繁项集呢?还是以超市为例,你想想啊,我们找物品关联规则的目的是什么,是为了提高物品的销售额。如果一个物品本身购买的人就不多,那么你再怎么提升,它也不会高到哪去。所以从效率和价值的角度来说,肯定是优先找出那些人们频繁购买的物品的关联物品。

既然要找出物品的关联规则有两步,那我们也一步一步来。我们会先介绍如何用Apriori找出物品的频繁项集,然后下一篇会在Apriori处理后的频繁项集的基础上,进行物品的关联分析。

二. Apriori算法基础概念

在介绍Apriori算法之前,我们需要先了解几个概念,别担心,我们会结合下面的例子来进行说明的。

这些是一个超市里面的一部分购买商品记录:
交易编号 | 购买商品
---|---
0| 牛奶,洋葱,肉豆蔻,芸豆,鸡蛋,酸奶
1| 莳萝,洋葱,肉豆蔻,芸豆,鸡蛋,酸奶
2| 牛奶,苹果,芸豆,鸡蛋
3| 牛奶,独角兽,玉米,芸豆,酸奶
4| 玉米,洋葱,洋葱,芸豆,冰淇淋,鸡蛋

2.1 关联分析的几个概念

支持度(Support):支持度可以理解为物品当前流行程度。计算方式是:

支持度 = (包含物品A的记录数量) / (总的记录数量)

用上面的超市记录举例,一共有五个交易,牛奶出现在三个交易中,故而{牛奶}的支持度为3/5。{鸡蛋}的支持度是4/5。牛奶和鸡蛋同时出现的次数是2,故而{牛奶,鸡蛋}的支持度为2/5。

置信度(Confidence):置信度是指如果购买物品A,有较大可能购买物品B。计算方式是这样:

置信度( A -> B) = (包含物品A和B的记录数量) / (包含 A 的记录数量)

举例:我们已经知道,(牛奶,鸡蛋)一起购买的次数是两次,鸡蛋的购买次数是4次。那么Confidence(牛奶->鸡蛋)的计算方式是Confidence(牛奶->鸡蛋)=2 / 4。

提升度(Lift):提升度指当销售一个物品时,另一个物品销售率会增加多少。计算方式是:

提升度( A -> B) = 置信度( A -> B) / (支持度 A)

举例:上面我们计算了牛奶和鸡蛋的置信度Confidence(牛奶->鸡蛋)=2 / 4。牛奶的支持度Support(牛奶)=3 / 5,那么我们就能计算牛奶和鸡蛋的支持度Lift(牛奶->鸡蛋)=0.83
当提升度(A->B)的值大于1的时候,说明物品A卖得越多,B也会卖得越多。而提升度等于1则意味着产品A和B之间没有关联。最后,提升度小于1那么意味着购买A反而会减少B的销量。

其中支持度和Apriori相关,而置信度和提升度是下一篇寻找物品关联规则的时候会用到。

2.2 Apriori 算法介绍

Apriori的作用是根据物品间的支持度找出物品中的频繁项集。通过上面我们知道,支持度越高,说明物品越受欢迎。那么支持度怎么决定呢?这个是我们主观决定的,我们会给Apriori提供一个最小支持度参数,然后Apriori会返回比这个最小支持度高的那些频繁项集。

说到这里,有人可能会发现,既然都知道了支持度的计算公式,那直接遍历所有组合计算它们的支持度不就可以了吗

是的,没错。确实可以通过遍历所有组合就能找出所有频繁项集。但问题是遍历所有组合花的时间太多,效率太低,假设有N个物品,那么一共需要计算2^N-1次。每增加一个物品,数量级是成指数增长。而Apriori就是一种找出频繁项集的高效算法。它的核心就是下面这句话:

某个项集是频繁的,那么它的所有子集也是频繁的

这句话看起来是没什么用,但是反过来就很有用了。

如果一个项集是 非频繁项集,那么它的所有超集也是非频繁项集

如图所示,我们发现{A,B}这个项集是非频繁的,那么{A,B}这个项集的超集,{A,B,C},{A,B,D}等等也都是非频繁的,这些就都可以忽略不去计算。

运用Apriori算法的思想,我们就能去掉很多非频繁的项集,大大简化计算量。

2.3 Apriori算法流程

要使用Apriori算法,我们需要提供两个参数,数据集和最小支持度。我们从前面已经知道了Apriori会遍历所有的物品组合,怎么遍历呢?答案就是递归。先遍历1个物品组合的情况,剔除掉支持度低于最小支持度的数据项,然后用剩下的物品进行组合。遍历2个物品组合的情况,再剔除不满足条件的组合。不断递归下去,直到不再有物品可以组合。

下面我们来用Apriori算法实战一下吧。

三. Apriori算法实战

我们用一个简单的例子来用一下Apriori吧,这里用到的库是mlxtend。

在放代码之前,先介绍下Apriori算法的参数吧。

def apriori(df, min_support=0.5,
            use_colnames=False,
            max_len=None)
参数如下:
df:这个不用说,就是我们的数据集。
min_support:给定的最小支持度。
use_colnames:默认False,则返回的物品组合用编号显示,为True的话直接显示物品名称。
max_len:最大物品组合数,默认是None,不做限制。如果只需要计算两个物品组合的话,便将这个值设置为2。

OK,接下来就来用一个简单的例子来看看怎么使用Apriori算法找到频繁项集吧。

import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori

#设置数据集
dataset = [['牛奶','洋葱','肉豆蔻','芸豆','鸡蛋','酸奶'],
        ['莳萝','洋葱','肉豆蔻','芸豆','鸡蛋','酸奶'],
        ['牛奶','苹果','芸豆','鸡蛋'],
        ['牛奶','独角兽','玉米','芸豆','酸奶'],
        ['玉米','洋葱','洋葱','芸豆','冰淇淋','鸡蛋']]

te = TransactionEncoder()
#进行 one-hot 编码
te_ary = te.fit(records).transform(records)
df = pd.DataFrame(te_ary, columns=te.columns_)
#利用 Apriori 找出频繁项集
freq = apriori(df, min_support=0.05, use_colnames=True)

首先,需要先将商品进行one-hot编码,编码后用boolean值表示。所谓ont-hot编码呢,直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制。比如冰淇淋只存在最后一共交易单中,其他交易中都没出现。那冰淇淋就可以用[0,0,0,0,1]来表示

这里编码后的数据如下:

     冰淇淋     洋葱     牛奶    独角兽     玉米    肉豆蔻    芸豆     苹果     莳萝     酸奶     鸡蛋
0  False        True   True       False      False    True     True    False    False   True     True
1  False        True  False       False      False    True     True    False     True   True     True
2  False       False   True       False      False   False     True     True    False  False     True
3  False       False   True        True       True   False     True    False    False   True    False
4   True        True  False       False       True   False     True    False    False  False     True

我们设定的最小支持度是0.6,那么只有支持度大于0.6的物品集合才是频繁项集,最终结果如下:

    support      itemsets
0       0.6          (洋葱)
1       0.6          (牛奶)
2       1.0          (芸豆)
3       0.6          (酸奶)
4       0.8          (鸡蛋)
5       0.6      (芸豆, 洋葱)
6       0.6      (洋葱, 鸡蛋)
7       0.6      (牛奶, 芸豆)
8       0.6      (酸奶, 芸豆)
9       0.8      (芸豆, 鸡蛋)
10      0.6  (芸豆, 洋葱, 鸡蛋)

四. 小结

今天我们介绍了关联分析中会用到的几个概念,支持度,置信度,提升度。然后讲述了Apriori算法的作用,以及Apriori算法如何高效得找出物品的频繁项集。

最后使用Apriori算法找出例子中的频繁项集。

以上~


推荐阅读:
Scala 函数式编程指南(一) 函数式思想介绍
通俗地说决策树算法(二)实例解析
大数据存储的进化史 --从 RAID 到 Hadoop Hdfs
C,java,Python,这些名字背后的江湖!

深入浅出Apriori关联分析算法(一)的更多相关文章

  1. Python --深入浅出Apriori关联分析算法(二) Apriori关联规则实战

    上一篇我们讲了关联分析的几个概念,支持度,置信度,提升度.以及如何利用Apriori算法高效地根据物品的支持度找出所有物品的频繁项集. Python --深入浅出Apriori关联分析算法(一) 这次 ...

  2. Apriori 关联分析算法原理分析与代码实现

    前言 想必大家都听过数据挖掘领域那个经典的故事 - "啤酒与尿布" 的故事. 那么,具体是怎么从海量销售信息中挖掘出啤酒和尿布之间的关系呢? 这就是关联分析所要完成的任务了. 本文 ...

  3. 第十四篇:Apriori 关联分析算法原理分析与代码实现

    前言 想必大家都听过数据挖掘领域那个经典的故事 - "啤酒与尿布" 的故事. 那么,具体是怎么从海量销售信息中挖掘出啤酒和尿布之间的关系呢? 这就是关联分析所要完成的任务了. 本文 ...

  4. Apriori关联分析算法概述

    概念 关联分析:从大规模数据集中寻找物品间的隐含关系.物品间关系又分为两种:频繁项集或关联规则,频繁项集是经常出现一块的物品集合:关联规则则暗示物品间存在很强的联系 关联评判标准:支持度和可信度.支持 ...

  5. Apriori关联分析详解

    ------------恢复内容开始------------ 一. Apriori关联分析概述 选择物品之间的关联规则也就是要找出物品之间的关系,要找到这种关系有两步 找出频繁一起出现的物品集的集合, ...

  6. 关联分析Apriori算法和FP-growth算法初探

    1. 关联分析是什么? Apriori和FP-growth算法是一种关联算法,属于无监督算法的一种,它们可以自动从数据中挖掘出潜在的关联关系.例如经典的啤酒与尿布的故事.下面我们用一个例子来切入本文对 ...

  7. 关联分析:FP-Growth算法

    关联分析又称关联挖掘,就是在交易数据.关系数据或其他信息载体中,查找存在于项目集合或对象集合之间的频繁模式.关联.相关性或因果结构.关联分析的一个典型例子是购物篮分析.通过发现顾客放入购物篮中不同商品 ...

  8. 使用Apriori进行关联分析(一)

    大型超市有海量交易数据,我们可以通过聚类算法寻找购买相似物品的人群,从而为特定人群提供更具个性化的服务.但是对于超市来讲,更有价值的是如何找出商品的隐藏关联,从而打包促销,以增加营业收入.其中最经典的 ...

  9. 关联分析FPGrowth算法在JavaWeb项目中的应用

    关联分析(关联挖掘)是指在交易数据.关系数据或其他信息载体中,查找存在于项目集合或对象集合之间的频繁模式.关联.相关性或因果结构.关联分析的一个典型例子是购物篮分析.通过发现顾客放入购物篮中不同商品之 ...

随机推荐

  1. 计算ScrollView的当前页面

    //每页宽度 CGFloat pageWidth = sender.frame.size.width; //根据当前的坐标与页宽计算当前页码 int currentPage = floor((send ...

  2. Map/Reduce的类体系架构

    Map/Reduce的类体系架构 Map/Reduce案例解析: 先以简单的WordCount例程, 来讲解如何去描述Map/Reduce任务. public static void main(Str ...

  3. cotex_m3内核提供的ITM串口打印调试

    cotex_m3内核的ARM提供了ITM串口打印观测的功能,可以不用ARM单片机自己的串口就可在开发时候串口打印调试.节约了宝贵的内部资源,同时也为调试提供了方便.使用方法如下: 1 将下面的SWO_ ...

  4. Nodejs笔记(二)

    Nodejs事件 Node.js 所有的异步I/O 操作在完成时都会发送一个事件到事件队列. Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时分发一个事件, 一 ...

  5. th固定 td滚动的表格实现

    为什么这样? 体验好 原理 通过两个表格,使其th td 对应,产生一种错觉. 代码 1.html <div class="content"> <div clas ...

  6. 从原理角度解析Android (Java) http 文件上传

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/23781773 文件上传是我们项目中经常使用的功能,一般我们的服务器可能都是web ...

  7. iOS开发之仿射变换示例总结

    本篇博客比较简单,但还是比较实用的.其中的示例依然使用Swift3.0来实现,该博客算是下篇博客的一个引子,因为我们下篇博客要介绍使用Swift开发iOS应用中常用的一些Extension.而在这些E ...

  8. Centos7禁止或者允许开机启动服务

    [root@bogon rsyslog.d]# systemctl is-enabled httpd disabled [root@bogon rsyslog.d]# systemctl status ...

  9. 动态规划--最长上升子序列(Longest increasing subsequence)

    前面写了最长公共子序列的问题.然后再加上自身对动态规划的理解,真到简单的DP问题很快就解决了.其实只要理解了动态规划的本质,那么再有针对性的去做这方的题目,思路很快就会有了.不错不错~加油 题目描述: ...

  10. 对Spark2.2.0文档的学习1-Cluster Mode Overview

    Cluster Mode Overview Link:http://spark.apache.org/docs/2.2.0/cluster-overview.html Spark应用(Applicat ...