Apriori算法是一个发掘数据内在关联的频繁项集算法,是数据挖掘领域内的经典算法。
一、几个概念
假设现有四种物品,分别为A、B、C、D。任一种和几种物品都可能会同时出现,我们想要了解这四种物品在出现时之间是否有联系,比如AB常常一起出现。以下几条记录为它们的出现情况。
- AB
- AC
- ABCD
- BC
- ABD
频繁项集:frequent item set,是经常出现在一起的物品的集。例 {A,B} 在以上记录中同时出现了三次。
关联规则:相当于物品之间有关联的条件。例如我们由以上记录可以简单推断一条关联规则{B}->{A}。
关联分析:也就是对关联规则的学习,寻找物品间的隐含关系,形成规则用于预测和更好的推荐。
对于频繁项集,我们需要有一个衡量指标来认定一个项集是否频繁,有两个概念:支持度和可信度。
支持度:定义为数据中包含某项集的记录所占的比例,例如项集 {AC} 的支持度为2/5=0.4
可信度:又称为置信度,定义为对某一条规则进行相关支持度的计算。例如对于{B}->{A}这条规则,置信度计算为:支持度({A,B})/支持度({B})=(3/5)/(4/5)=0.75
二、Apriori原理
以上述四个物品为例,它们可以组合的各种情况有
,在我们确定频繁项集的时候,比如我们要找出支持度大于0.8的项集,这样我们需要对所有记录进行遍历,然后对可能出现的15种情况依次计算出现的次数,当记录数目很庞大,并且物品数目也更加多,这样遍历会十分费时费力,Apriori原理可以帮助减少可能感兴趣的项集,即我们不必对15种情况都进行遍历。
Apriori——a priori,意为“一个先验”。如果我们说某个项集是频繁的,那么这个项集的子集也是频繁的。这句话反过来,如果一个项集是非频繁的,那么这个项集的超集也是非频繁的。如此一来,当我们确定{A,B}不频繁,那么{A,B,C},{A,B,D},{A,B,C,D}都不频繁,也就无需就这些情况进行遍历。
如此,Apriori算法从频繁1-项集开始寻找,频繁1-项集集合记作L1,之后根据此找L2,一直到Lk。
以下为《机器学习实战》中的代码示例:
def aprioriGen(Lk, k):
retList = []
lenLk = len(Lk)
for i in range(lenLk):
for j in range(i+1, lenLk):
L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]
L1.sort(); L2.sort()
if L1==L2:
retList.append(Lk[i] | Lk[j])
return retList
def apriori(dataSet, minSupport = 0.5):
C1 = createC1(dataSet)
D = map(set, dataSet)
L1, supportData = scanD(D, C1, minSupport)
L = [L1]
k = 2
while (len(L[k-2]) > 0):
Ck = aprioriGen(L[k-2], k)
Lk, supK = scanD(D, Ck, minSupport)
supportData.update(supK)
L.append(Lk)
k += 1
return L, supportData