逻辑清晰的Apriori 算法介绍与代码实现
本文针对的对象是大概知道什么是 Apriori算法,但是还比较迷糊的读者。
Apriori算法的介绍
Apriori,翻译为“先验的”。顾名思义,是利用已知的数据来获取规律的数据挖掘关联算法。它通过“支持度”,“可信度”,“提升度”三个指标来衡量数据的相关性。首先通过“支持度”获得“频繁项集”,接着由“可信度”和“提升度”对“频繁项集”进行衡量,得到最终的结果“强关联规则”。接下来分别对支持度,可信度,提升度,频繁项集和强关联规则进行说明,并举一个简单的例子便于理解。
支持度
一个表示概率的指标,对于事物A来说,A的支持度为事物A发生的概率,公式表示为:
s
u
p
p
o
r
t
(
A
)
=
P
(
A
)
support(A) = P(A)
support(A)=P(A)
对于两个事物A和B来说,A与B的支持度就是A和B同时发生的概率。公式表示为:
s
u
p
p
o
r
t
(
A
B
)
=
P
(
A
B
)
support(AB) = P(AB)
support(AB)=P(AB)
PS:就是简单的概率公式
频繁项集
一般地,在实际中为了筛选数据,我们会对支持度有一个规定。当一条数据满足最小支持度的时候,我们就说,它是一个频繁项,他们构成的集合称为频繁项集。具体请看接下来的例子。
置信度
同样是一个表示概率的指标,对于事物A和B来说,A对B的置信度就是A和B同时发生的概率与A出现概率的比值。公式表示为:
c
o
n
f
i
d
e
n
c
e
(
A
⇒
B
)
=
s
u
p
p
o
r
t
(
A
B
)
s
u
p
p
o
r
t
(
A
)
confidence(A\Rightarrow B)= \frac{support(AB)} {support(A)}
confidence(A⇒B)=support(A)support(AB)
PS:就是如下的条件概率公式一样:
P
(
B
∣
A
)
=
P
(
A
B
)
P
(
A
)
P(B|A) = \frac{P(AB)} {P(A)}
P(B∣A)=P(A)P(AB)
提升度
仍然是一个表示概率的指标,对于事物A和B来说,他们的提升度公式表示如下:
L
i
f
t
(
A
B
)
=
s
u
p
p
o
r
t
(
A
B
)
s
u
p
p
o
r
t
(
A
)
∗
s
u
p
p
r
o
t
(
B
)
Lift(AB)= \frac{support(AB)} {support(A)*supprot(B)}
Lift(AB)=support(A)∗supprot(B)support(AB)
提升度表示两个数据的相关性,Lift(AB)越大,表示事物A和B的相关性越强。Lift(AB)越小,表示事物A和B的相关性越弱。
如何理解提升度作为指标?举个例子1: 注脚的解释:10000 个超市订单(10000 个事务),其中购买三元牛奶(A事务)的 6000 个,购买伊利牛奶(B事务)的 7500 个,4000 个同时包含两者。我们可以计算出:
s
u
p
p
o
r
t
(
A
)
=
0.6
support(A) = 0.6
support(A)=0.6
s
u
p
p
o
r
t
(
B
)
=
0.75
support(B) = 0.75
support(B)=0.75
s
u
p
p
o
r
t
(
A
B
)
=
0.4
support(AB) = 0.4
support(AB)=0.4
c
o
n
f
i
d
e
n
c
e
(
A
⇒
B
)
=
0.6666667
confidence(A\Rightarrow B)= 0.6666667
confidence(A⇒B)=0.6666667
c
o
n
f
i
d
e
n
c
e
(
B
⇒
A
)
=
0.5333333
confidence(B\Rightarrow A)= 0.5333333
confidence(B⇒A)=0.5333333
A对B事务的置信度为0.67,看似还不错,但是其实算一个误导,因为B原本的出现概率是0.75,而AB同时出现的概率是0.67,也就是说A的出现,让B的出现降低了。因此要引入一个指标防止这种情况,这个指标就是提升度。
一般来讲,在实际的大量数据中,提升度大于3,是一个合理的提升度。但是在自己设计的小数据中,设成0不用考虑就好了。
强关联规则
在筛选出的频繁项集中,如果一个数据通过了最小置信度和最小提升度,那就可以被称为一条强关联规则,作为结果输出了~
例子
一个大型商场的最近几条交易数据如下2:
交易标号 | 商品1 | 商品2 | 商品3 | 商品4 |
---|---|---|---|---|
交易1 | 1 | 1 | 1 | 1 |
交易2 | 1 | 1 | 0 | 0 |
交易3 | 0 | 1 | 1 | 1 |
交易4 | 0 | 1 | 1 | 0 |
交易5 | 1 | 1 | 0 | 1 |
交易6 | 0 | 0 | 1 | 1 |
交易7 | 0 | 1 | 0 | 1 |
我们希望从上述数据中得知哪些物品通常被同时购买。在这个例子中我们规定最小支持度为 3/7,最小置信度为0.8,最小提升度为0。
找到频繁项集
第一步查看单个物品的购买概率,发现所有的物品都满足最小支持度,因此所有物品都为频繁购买。
商品标号 | 购买概率 |
---|---|
商品1 | 3/7 |
商品2 | 6/7 |
商品3 | 4/7 |
商品4 | 5/7 |
接下来,就要生成频繁项的组合及购买频率。之前是一个商品的组合,现在生成两个商品的组合:
商品标号 | 购买概率 |
---|---|
{1,2} | 3/7 |
{1,3} | 1/7 |
{1,4} | 2/7 |
{2,3} | 3/7 |
{2,4} | 4/7 |
{3,4} | 3/7 |
可见,在两个商品的组合中,{1,3}和{1,4}的购买概率未达到最小支持度,因此舍弃,其他的组合保持为频繁项。
接下来,继续生成频繁项的组合以及购买概率,之前是两个商品的组合,现在生成三个商品的组合:
商品标号 | 购买概率 |
---|---|
{2,3,4} | 2/7 |
唯一生成的一个组合并不满足,因此被舍弃。我们注意到,只有{2,3},{2,4},{3,4}都是频繁项,才能生成{2,3,4}的组合。像{1,2,4},因为{1,4}不是频繁项,所以不能生成这样的组合。
经过上述统计,得到的所有的频繁项集为:
{商品1}
{商品2}
{商品3}
{商品4}
{商品1,商品2}
{商品2,商品3}
{商品2,商品4}
{商品3,商品4}
计算置信度和提升度
在实际中,只有一个商品的频繁项没有意义,因此舍弃,对剩下四个求置信度和提升度。最终只有
c
o
n
f
i
d
e
n
c
e
(
商
品
1
⇒
商
品
2
)
>
0.8
confidence(商品1\Rightarrow 商品2) > 0.8
confidence(商品1⇒商品2)>0.8
由此得到了一个强关联规则:商品1和商品2经常被同时购买。
Apriori算法的代码实现(Python)
这里就不展示自己写的函数了。好多好多行,效率还不高…
展示一个调用apriori的库函数的python程序,速度比自己写的快多了。真香呀。例子就用上面提到的例子。
from apyori import apriori
data = [['商品1', '商品2', '商品3', '商品4'],
['商品1', '商品2'],
['商品2', '商品3', '商品4'],
['商品2', '商品3'],
['商品1', '商品2', '商品4'],
['商品3', '商品4'],
['商品2', '商品4']]
min_supp = 3/7
min_conf = 0.8
min_lift = 0.0
rulers = list(apriori(transactions=data, min_support=min_supp, min_confidence=min_conf, min_lift=min_lift))
for rule in rulers:
## 输出详细信息
print(str(rule))
## 只输出规则
print(str(rule)[str(rule).find('{') + 1:str(rule).find('}')])
Apriori算法的优劣
优点就是这是个数据挖掘的入门算法,理解起来还算容易。
缺点是内存负载过大,需要不断扫描数据。而且如果数据如果不能尽快收敛,频繁项集很容易 Memory error。
这个算法再进阶一步就是Fp-growth算法,有兴趣可以去了解一下。