关联分析概述
“关联分析”就是分析在众多的历史交易记录中,出现很多的组合项有哪些,并且得出“购买了 A 物品的顾客还很有可能会一起购买 B 物品”这样的结论。
那么,“分析一起出现的组合项”有什么用呢?
1、我们可以发现哪些商品的组合销量高,例如,我们知道周志华的《机器学习》和李航的《统计学习方法》这两本书通常都是被人们口耳相传一起被推荐给想入门机器学习的朋友,然后顾客一起购买的。作为商家,其实我们并不知道这件事,但是通过关联分析,分析交易记录,我们就可以在众多历史交易记录中发现这个事实,如果我们单独统计《机器学习》的购买次数和《统计学习方法》是不能得出这个结论的;
2、得到“《机器学习》和《统计学习方法》会被一起购买”这个事实有什么用呢?如果一个人他只是来买《机器学习》这本书的,它并不知道《统计学习方法》,我们通过得到“《机器学习》和《统计学习方法》会被一起购买”这个事实,就可以把《统计学习方法》推荐给他。或者我们就把《机器学习》和《统计学习方法》作为套餐一起销售(两本书一起买比分别单独买要便宜),以达到促销的目的。
分析出《机器学习》和《统计学习方法》这两件商品之间的关联性,这就是关联分析能达到的目标之一。
另外,关联分析还能够帮我们得到一些诸如“购买了《机器学习实战》的读者绝大多数还会同时购买了《机器学习》和《统计学习方法》”、“购买了薯条和汉堡的顾客还会购买可乐”这样的结论。当顾客欲购买《机器学习实战》的时候,我们把《机器学习》和《统计学习方法》推荐给他,想购买薯条和汉堡的顾客,我们把可乐推荐给他。即通过关联分析,把以往顾客觉得“一起购买,食用更加”的商品组合挖掘出来,我们就可以推荐给更多有相似购买欲望的顾客,以达到促销的目的。
上面基本说清楚了“关联分析”在做什么,再总结一下,就是通过关联分析算法,通过历史数据,挖掘出历史顾客的购买习惯,发现哪些商品组合会一起被购买。通过事实挖掘出更深层次的事物之间的关联性。
历史上最有名的关联分析的案例就是“啤酒与尿布”的例子了,我最早听到“啤酒与尿布”的案例是看一则关于介绍大数据的案例。下面是一段摘抄(有修改):
通过关联分析算法,我们发现尿布和啤酒的销售是有关联关系的。进一步我们得出了这样的原因:当家里面有了小孩子之后,买尿布的任务往往是让年轻的爸爸去干的。其实爸爸对孩子的出生贡献并不大,但是他觉得自己做出了很大的成绩。所以他买完尿布的时候,会想顺便买一瓶啤酒犒劳自己。因此后来沃尔玛就把啤酒和尿布放在一块儿,啤酒的销售量一下子就增加了。可以说在大数据时代,原来找不到的关联关系现在找得到了。
通过这则经典的案例,我们知道,数据很重要,算法也很重要。没有数据就像“巧妇难为无米之炊”,没有算法,即使有很多数据,也只是占用地方,不能变成价值。
分解关联分析算法
通过上面的例子,我们可以分析出,其实我们做关联分析的一达目的是要做推荐,被推荐的商品或者商品组合要满足的特性之一就是,有很多交易记录都有它。这件事情就叫做发现“频繁项集”。
下面会陆续介绍一些重要的概念,这些概念就是比较多,但一点都不难理解。如果遇到概念不清楚的地方,请结合例子多看几遍,就会很清晰了。
例1:以下是一个简短的交易历史记录,我们给每次交易一个编号,一次交易中购买的商品以列表的形式呈现。
交易号码 | 商品 |
---|---|
001 | 汉堡,薯条,可乐,鸡翅 |
002 | 汉堡,薯条,可乐 |
003 | 可乐,鸡块 |
004 | 可乐 |
说明:每一条交易记录,我们只关心单个商品是否被购买,被购买的数量并不重要。并且这些商品之间没有顺序关系。
下面介绍一些概念:
事务
每一条交易就是一个事务。例 1 中,就包含 4 个事务。所以事务在购物这个场景下,可以被理解为一个订单。
项
事务中的每一个物品,数量为 1,区别与项集(马上就介绍项集是什么)。上表中 {可乐} 、{汉堡} 、 {薯条} 等就是项。但其实,更重要、更广泛的使用的概念叫做项集。
项集
包含零个或者多个项的集合称为项集。上表中的项集有:{可乐}、{汉堡}、{薯条}、{汉堡,薯条}、{可乐,鸡块}、{汉堡,可乐},所以项也是项集。
为什么说项集更普遍呢?因为关联分析其实我们不仅仅关心单个商品之间的关系,我们还关心“商品的组合”与“商品的组合”、“商品的组合”与单个商品之间的关联关系。例如我们前面举的例子:“购买了《机器学习实战》的读者绝大多数还会同时购买了《机器学习》和《统计学习方法》”,这里商品的组合“《机器学习》和《统计学习方法》”就是我们关系的对象之一,它就是项集。
那么我们说商品的组合有很多呀,我们都要拿出来分析吗?事实上的确是这样的,思路没有问题。这不是很麻烦吗?别着急,有一些高效的算法会帮助我们快速得到我们想要的项集。
项集的支持度计数
整个数据集中包含该项集的个数。例如,项集 {汉堡,薯条} 出现在事务 001、002 中,因此,项集 {汉堡,薯条} 的支持度计数为 2。
项集的支持度
支持度计数除以总的事务数。例 1 中,总的事务数为 4,项集 {汉堡,薯条} 的支持度计数为 2,项集 {汉堡,薯条} 的支持度为 ,说明有 的人同时购买了啤酒和尿布。
所以支持度其实就是一个频率,我们用 support 这个记号表示, 就表示项集 {汉堡,薯条} 的支持度为 。
在一些资料介绍“项集的支持度计数”和“项集的支持度度”的资料和书籍中,往往对“支持度计数”和“支持度”不加以区分,但其实它们表示的是一回事,通过上下文就很容易区分开来。值介于 0 和 1 之间的就是支持度,值是整数值的就是支持度计数。
频繁项集
支持度大于或者等于某个阈值的项集称为频繁项集。
其实就是给“频繁”出现的项集一个定义,出现次数高的项集才能称之为“频繁”,那么这个“频繁”如何刻画呢?用一个比例系数来规定。就像我们规定一次百分制的考试中,大于等于 60 分为通过,这个阈值 60 就是人为规定的,完全可以定义 70 分以上为通过,同样,我们会规定一个阈值,不同的阈值就对应有不同的频繁项集。
规则
也叫关联规则,这是一个十分重要的概念,从频繁项集中找出各个频繁项集之间的关系。
开篇举出的例子:“购买了《机器学习实战》的读者绝大多数还会同时购买了《机器学习》和《统计学习方法》”、“购买了薯条和汉堡的顾客还会购买可乐”这样的结论就是两个关联规则。我们可以分别用:{《机器学习实战》} → {《机器学习》、《统计学习方法》} 和 {汉堡,薯条} → {可乐} 这两个记号来表示。
对这个记号的说明:
1、用花括号表示项集,集合表示的事物组合是无序的,因此用花括号表示;
2、箭头 → 是表示先后顺序的,对于规则 {《机器学习实战》} → {《机器学习》、《统计学习方法》} 而言,项集 {《机器学习实战》} 是顾客期望项集,也称之为前件,项集 {《机器学习》、《统计学习方法》} 是被推荐项集,也称之为后件,我比较习惯称之为右边列表,因为它在箭头的右边。右边列表是我们挖掘出来的关联规则中,新的顾客并不知道的商品的组合,是我们要推荐给新顾客的商品组合。
置信度
置信度是针对关联规则而言的,描述关联规则强弱的度量就是置信度,置信度通常用 confidence 表示,对于关联规则 {《机器学习实战》} → {《机器学习》、《统计学习方法》} 而言,置信度的定义是:
这样写,一开始看可能还不太习惯,我们看等式的右边,其实就是条件概率,因此可以这样理解:
因此,置信度就是一个条件概率,对于这个例子而言,就是“购买了《机器学习实战》的顾客,还一起购买了《机器学习》和《统计学习方法》”的概率。说得再直白一些就是,“一个顾客,在购买了《机器学习实战》的前提下,还一起购买了《机器学习》和《统计学习方法》”的概率。
所以,对于一条关联规则的置信度的计算,分子和分母都是项集的支持度,我们不妨都把它理解成支持度计数,分母项集是分子项集的子集,分母子集是关联规则的前件,分子项集与分母项集的差集是被推荐列表,也就是我们前面说的右边列表。
这些都是定义、符合和记号,在理解上没有任何难度。
强关联规则
大于或者等于最小置信度阈值的规则称为强关联规则。
例如:如果我们得出了一个强关联规则 {汉堡,薯条} → {可乐} ,这条强关联规则表示购买了 {汉堡,薯条} 这个组合的顾客,在很大程度上会购买 {可乐} 。用条件概率的说法就是,在购买了 {汉堡,薯条} 这个组合的前提下,有很大概率还会一起购买 {可乐}。
总结一下,这里介绍了很多概念,有两个“度”:“支持度”和“置信度”,“支持度”是一个频率(理解成概率也没问题),“置信度”是一个条件概率。“项集”是单个商品的组合,“频繁项集”表示出现很多次的“物品的组合”,是我们关心的。关联规则描述了“项集和项集”之间的关系,说得更具体一点是“频繁项集和频繁项集之间的关系”(具体原因请见后面 Apriori 原理),关联规则的强弱,用置信度来衡量。
- “支持度”是“项集”的度量,支持度大于等于一个阈值的项集就是“频繁项集”;
- “置信度”是“关联规则”的度量,“关联规则”是“频繁项集和频繁项集之间的关系”,是一个条件概率,通过“频繁项集”的支持度计算得到,置信度大于等于一个阈值的关联规则就是强关联规则;
- 关联分析的一个重要目标就是找出强关联规则。
关联分析的步骤
通过以上分析,我们知道,通过关联分析,我们想找到诸如 {汉堡,薯条} → {可乐} 这样的强关联规则。关联规则描述了项集和项集之间的关联关系,通过项集的支持度定义。
所以,我们得到关联分析的步骤如下。
1、发现频繁项集;
如果一个商品或者商品的组合被购买的次数都不多,它当然不可能成为推荐的对象,因此,我们得先找到频繁项集。
制定一个阈值,小于这个阈值的支持度的项集都不是频繁项集。
2、发现强关联规则。
通过频繁项集的支持度,得到关联规则的置信度。
制定一个阈值,小于这个阈值的关联规则不是强关联规则。
那么好了,其实第一个问题其实是得到商品的组合,如果一个商店有 个商品出售,那么商品的组合就有 个。如果一个商店有 个商品出售,那么商品的组合就有 个。分别计算它们的支持度,再两两组合,得到关联规则,在计算这些关联规则的置信度(条件概率),关注那些条件概率高的关联规则,就是强关联规则了。
上面的叙述是没有问题的,但是实际上,我们没有必要把 个商品的组合都拿出来算一下置信度,这个计算量太大了。
对于例 1 而言,一个显而易见的事实是:如果包含了“鸡翅”的订单都不多的话,那么包含了{“鸡翅”,“可乐”}的订单肯定会更少,即项集 {鸡翅} 的支持度如果很少,项集 {鸡翅,可乐} 的支持度只会与之相等或者更少,绝对不会更多。这是个不证自明的道理,看看例1,结合项集和支持度的定义,就不难理解这个基本事实。
根据这个事实,就可以帮助我们大大减少商品组合数的计算,再想一想,如果连《机器学习》的订购买量都很少的话,一起购买“《机器学习》和《统计学习方法》”的订单只会与之相等或更少,不会更多。
这个事实就被人们总结成为了 Apriori 原理,其实并不是什么晦涩难懂的定理。
Apriori 原理
- 如果某个项集是频繁的,那么它的所有子集也是频繁的;
- 如果某个项集不是频繁项集,那么它的所有超集也一定不是频繁项集。
使用 Apriori 原理可以避免项集的搜索呈指数级增长。下面我们就利用 Apriori 原理的第 2 条:如果某个项集不是频繁项集,那么它的所有超集也一定不是频繁项集,来看看如何得到频繁项集。
频繁项集搜索
万丈高楼平地起,前面我们计算 个商品的组合也是从 1 个商品的组合数、2 个商品的组合数一直到 个商品的组合数,这样来的。搜索频繁项集也不例外。
例2:这里我们使用 《机器学习实战》P205 程序清单 11-1 的例子进行辅助说明。
data_set = [
[1, 3, 4],
[2, 3, 5],
[1, 2, 3, 5],
[2, 5]
]
列出 1-项集
我们先列出只包含一个物品的项集,计算它们的频数和频率。
结果:
1-项集 | 频数(支持度计数) | 频率(支持度) | 是否频繁项集 |
---|---|---|---|
商品 [1] | 2 | 0.5 | 频繁项集 |
商品 [2] | 3 | 0.75 | 频繁项集 |
商品 [3] | 3 | 0.75 | 频繁项集 |
商品 [4] | 1 | 0.25 | |
商品 [5] | 3 | 0.75 | 频繁项集 |
我们定义,只要出现在一般订单以上的项集就是频繁项集,即支持度阈值是 0.5 。那么商品 [4] 在这个阈值定义下,就不是频繁项集。因此只有 1 个商品的频繁项集就是 {商品 [1]}、 {商品 [2]}、 {商品 [3]}、 {商品 [5]}。
列出 2-项集
根据 Apriori 原理,商品 [4] 一定不会出现在多于 1 个商品的项集里,接下来我们找只有 2 个商品的频繁项集,就从 {商品 [1]}、 {商品 [2]}、 {商品 [3]}、 {商品 [5]} 来生成,这其实也是一个组合问题,,我们可以列出如下统计表:
2-项集 | 频数(支持度计数) | 频率(支持度) | 是否频繁项集 |
---|---|---|---|
商品 [1,2] | 1 | 0.25 | |
商品 [1,3] | 2 | 0.5 | 频繁项集 |
商品 [1,5] | 1 | 0.25 | |
商品 [2,3] | 2 | 0.5 | 频繁项集 |
商品 [2,5] | 3 | 0.75 | 频繁项集 |
商品 [3,5] | 2 | 0.5 | 频繁项集 |
因此,在支持度阈值为 0.5 的时候,商品 [1,3]、商品 [2,3]、商品 [2,5]、商品 [3,5] 这 4 个项集是频繁项集。
接下来,我们寻找 3-项集。
列出 3-项集
3-项集由商品 [1,3]、商品 [2,3]、商品 [2,5]、商品 [3,5] 这 4 个项集生成。这个生成的过程也是两两组合,生成的项集只能包含 3 个商品。下面我具体描述一下如何组合的:
组合项1 | 组合项2 | 组合结果 | 是否 3-项集 |
---|---|---|---|
商品 [1,3] | 商品 [2,3] | 商品 [1,2,3] | 是 |
商品 [1,3] | 商品 [2,5] | 商品 [1,2,3,5] | |
商品 [1,3] | 商品 [3,5] | 商品 [1,3,5] | 是 |
商品 [2,3] | 商品 [2,5] | 商品 [2,3,5] | 是 |
商品 [2,3] | 商品 [3,5] | 商品 [2,3,5] | 是 |
商品 [2,5] | 商品 [3,5] | 商品 [2,3,5] | 是 |
商品 [1,2,3,5] 不是 3-项集,在这里我们暂且丢弃,有的朋友要问了,这里能这么草率丢掉吗。答案是可以的,因为项集商品 [1,2,3,5] 还会在生成 4-项集的过程中出现。
得到的 3-项集有:商品 [1,2,3]、商品 [1,3,5]、商品 [2,3,5]。
下面扫描这个数据表,统计3-项集的频数和频率。
3-项集 | 频数(支持度计数) | 频率(支持度) | 是否频繁项集 |
---|---|---|---|
商品 [1,2,3] | 1 | 0.25 | |
商品 [1,3,5] | 1 | 0.25 | |
商品 [2,3,5] | 2 | 0.5 | 频繁项集 |
3-项集中,频繁项集只有商品 [2,3,5] 。3-项集中频繁项集只有 1 个元素了,因此就没有必要分析 4-项集了。刚刚我们不是说“项集商品 [1,2,3,5] 还会在生成 4-项集的过程中出现”,怎么又没有了呢?因为 3-项集“商品 [1,2,3]”不是频繁项集,包含它的 4-项集“商品 [1,2,3,5]”肯定也不是频繁项集,因此我们没有遗漏。
于是,在最小支持度为 0.5 的时候,我们找到了这个数据集的所有频繁项集,它们是:
频繁 1-项集:商品 [1]、 商品 [2]、 商品 [3]、 商品 [5]
频繁 2-项集:商品 [1,3]、商品 [2,3]、商品 [2,5]、商品 [3,5]
频繁 3-项集:商品 [1,2,3]、商品 [1,3,5]、商品 [2,3,5]
频繁项集得到了,下面就得挖掘关联规则了。
挖掘强关联规则
我们复习一下关联规则是如何定义的,关联规则定义的置信度其实是一个条件概率:
可以发现:
- 分母项集一定是分子项集的真子集,这样分子项集与分母项集的差集才非空。
因此我们针对每一个不是 1-项集的频繁项集去挖掘关联规则,这一点很重要。
所以我们就从每一个频繁 2-项集、每一个频繁 3-项集依次挖掘关联规则。再者,我们还发现:
- 对于每一个非频繁 1-项集而言,挖掘关联规则的时候,分子项集的支持度是一样的,不同在于分母项集的支持度,分母项集的支持度越小,最终得到的置信度越大。分母项集计算出来的支持度如果越大,最终得到的置信度就会越小,这是其一;
- 根据 Apriori 原理的第 1 条:如果某个项集是频繁的,那么它的所有子集也是频繁的。如果分母项集的支持度很大,最终得到的置信度就会很小,小到小于最小置信度阈值,这条关联规则就不是强关联规则,那么这个分母项集的子集我们就不必再去计算它们的置信度了;
- 上面这一条反过来说,如果某个右边列表不能成为强关联规则,那么这个右边列表的超集也一定不能成为关联规则,这一条在代码实现的时候会用到,用一个距离的例子来说明就是,如果频繁集是 {汉堡、薯条、可乐、鸡块},计算出来的 {汉堡,薯条} → {可乐} 不能成为强关联规则,即 {可乐} 不会被推荐,那么 {可乐,鸡块} 这个项集也一定不会被推荐,即 {汉堡,薯条} → {可乐,鸡块} 也一定不是强关联规则。
这部分叙述我的叙述有点拗口,下面这张图就展示了这个原理。
这一部分我是在看 《机器学习实战》第 11 章,看到代码实现的时候才搞清楚的。
所以总结一下:
- 不管是寻找频繁项集还是挖掘强关联规则,我们其实都可以无脑地去做组合项,挨个计算,但是这样做明显效率不高;
- 借助 Apriori 原理,我们就可以在寻找频繁项集和挖掘强关联规则的时候,少做很多工作,思路都是一样的,如果子集不行,超集就不用考虑了。