关联规则挖掘(Association rules mining)
项目(Item)
ID | Items bought |
---|---|
10 | A,B,D |
20 | A,C,D |
30 | A,D,E |
支持度(support)
项集{x,y}\{x,y\}{x,y}在总项集中出现的概率(x,yx,yx,y同时出现)
Support(x→y)=P(x,y)P(I)=P(xUy)P(I)Support(x\to y)=\frac{P(x,y)}{P(I)}=\frac{P(xUy)}{P(I)} Support(x→y)=P(I)P(x,y)=P(I)P(xUy)
置信度(Confidence)
当xxx出现时,yyy也一起出现的概率,表示为x,yx,yx,y同时出现的概率占xxx出现的概率
Confidence(x→y)=P(y∣x)=P(xy)P(x)Confidence(x\to y)=P(y|x)=\frac{P(xy)}{P(x)} Confidence(x→y)=P(y∣x)=P(x)P(xy)
提升度(Lift)
x,yx,yx,y同时出现的频率,但是还需要再考虑二者各自出现的概率,从而表现出二者的相关性。提升度=1表示没有相关性(独立),高于一正相关,低于一负相关。
Lift(x→y)=ConfidenceP(y)=P(xy)P(x)P(y)Lift(x\to y)=\frac{Confidence}{P(y)}=\frac{P(xy)}{P(x)P(y)} Lift(x→y)=P(y)Confidence=P(x)P(y)P(xy)
一般来说,我们评估一个规则是否合理,会设置一定的最小支持度或者最小置信度阈值,大于这个阈值的规则,我们认为是感兴趣的。
举个例子
ID | Items |
---|---|
1 | A,B |
2 | A,B,C |
3 | A,D |
4 | A,B,C |
5 | B,C |
6 | B,D |
这个表格中,AAA的出现次数为444,ABABAB的出现次数为333,其支持度A→BA\to BA→B为:3/83/83/8,而置信度A→BA\to BA→B为3/43/43/4,提升度为3∗6/(4∗5)3*6/(4*5)3∗6/(4∗5).
布尔型与数值型关联规则
一般来说,关联规则的挖掘可以看做以下两步的过程:
由于第二步的开销远小于第一步,所有总体性能是由第一步决定的。例如:
一个长度为100的频繁项集,包含了
C1001+C1002+...+C100100−1=1.2730C_{100}^1+C_{100}^2+...+C_{100}^{100}-1=1.27^{30} C1001+C1002+...+C100100−1=1.2730
这么多个频繁项
1️⃣ Apriori算法
Apriori算法由Agrawal和Strikant在1994
年提出,是布尔关联规则挖掘的原创性算法,通过限制候选产生发现频繁项集。Apriori
算法使用一种称为逐层搜索的迭代方式,其中kkk项集用于生成(k+1)(k+1)(k+1)项集。
Apriori算法假定频繁项集的所有非空子集都是频繁的,这是一个先验性质,可以进一步过滤掉很多项集。其算法的核心分为两步:剪枝和连接
连接步
剪枝步
关联规则
置信度
Confidence(A→B)=Support(AUB)Support(A)≥minCConfidence(A\to B)=\frac{Support(AUB)}{Support(A)}\ge minC Confidence(A→B)=Support(A)Support(AUB)≥minC
由于规则由频繁项集产生,因此每个规则都自动地满足最小支持度。他们的支持度可以预先放在散列表中。
栗子
ID | Items |
---|---|
1 | I1,I2,I5 |
2 | I2,I4 |
3 | I2,I3 |
4 | I1,I2,I4 |
5 | I1,I3 |
6 | I2,I3 |
7 | I1,I3 |
8 | I1,I2,I3,I5 |
9 | I1,I2,I3 |
最小支持度为40%
第一次迭代:
Items | Support |
---|---|
I1 | 6/9 |
I2 | 7/9 |
I3 | 6/9 |
I4 | 2/9 |
I5 | 2/9 |
此时,I4,I5小于最小支持度,应该被剪枝
剩下的集合为
Items | Support |
---|---|
I1 | 6/9 |
I2 | 7/9 |
I3 | 6/9 |
他们之间可以生成下一项:
Items | Support |
---|---|
I1,I2 | 4/9 |
I1,I3 | 4/9 |
I2,I3 | 4/9 |
没有需要剪枝的,再进行下一步
Items | Support |
---|---|
I1,I2,I3 | 1/9 |
并不算频繁规则,所以最后的频繁项集为:{I1,I2,I3,{I1,I2},{I2,I3},{I1,I2}}
然后是置信度方面,置信度的计算可以表示为:
A→B,Confidence=support(B∣A)support(A)A\to B,Confidence=\frac{support(B|A)}{support(A)} A→B,Confidence=support(A)support(B∣A)
说人话就是发生A的条件下,有多少次是带着B玩。
Apriori算法的挑战与改进
挑战
改进
实现
import math
import numpy as np
from collections import defaultdictd=np.array(["milk,water,juice","milk,water","milk,rice,water","water","tomato,juice","juice,cucumber"])def Apriori(data,min_spport=2,min_confidence=0.5):FP=[]Data=[]# 初始化项集I=[]# 因为字符串不好做运算,所以我们映射成数组str2num=defaultdict(int)cnt=0for i in data:for j in i.split(","):if j not in str2num.keys():str2num[j]=cntcnt+=1for i in data:t=[]for j in i.split(","):I.append(j)t.append(str2num[j])Data.append(set(t))I=[[i] for i in set(I)]def scan(setI):tem=defaultdict(int)for i in setI:for j in Data:# 做个映射for k in i:if str2num[k] not in j:breakelse:tem[",".join(i)]+=1return [[i,j] for i,j in tem.items() if j>=min_spport]def comb(setI):# 记录FP.append(setI)# 按字典序排序I=[sorted([i[0]]) for i in setI]T=[]for i,v in enumerate(I):for j in I[i+1:]:if len(v)>1 and v[:-1]==j[:-1]:T.append(v[:-1]+v[-1]+j[-1])elif len(v)==1:T.append(v+j)return [set(i) for i in T]while 1:# 每次都需要扫描I=scan(I)# 这个I是已经进行剪枝后的了# 然后要进行连接步,要求前K-2项相同if I==[]:return FPI=comb(I)print(Apriori(d))
2️⃣ Partition: Scan Database Only Twice
首次提出:
A. Savasere, E. Omiecinski, and S. Navathe. An efficient algorithm for mining association in large databases. In VLDB’95.
分区技术
思想
细节
3️⃣ DHP: Reduce the Number of Candidates
首次提出
J. Park, M. Chen, and P. Yu. An effective hash-based algorithm for mining association rules. In SIGMOD’95
基于哈希思想的技术
思想
对应的哈希桶计数低于阈值的k项集不能频繁出现
4️⃣ DIC算法
基本思想:把数据库分成若干块,每一块都有一个开始点(start point),在每一个开始点处都可以加入新的候选项集。一旦确定所有子集都是频繁的,就可以在任何起点添加新的候选项。
目的:减少数据库的查找次数
如上图所示,初始时,加入所有的一项集,然后扫描B1,得到一项集在B1中的支持度,选出频繁一项集组成的候选二项集,在B2的start point位置加入,然后扫描B2,给候选项集里的项集计数,然后再生成新的频繁项集,在B1的start point上加入。重复这个过程,直到没有新的频繁项集生成。
5️⃣频繁模式增长算法(Frequent Pattern Growth, FP-Growth)
优势
算法步骤
一、创建FP树
第一次扫描数据库时,导出频繁项的集合,并按照频繁项支持度计数进行降序排序。例如:
接着,再次扫描数据库,构建FP树。算法描述如下:
下面是FP树的生成实现
class FPTree:def __init__(self,name="NULL"):self.children=[]self.val={} # name:[val,loc]self.cnt=0self.n=self,namedef growth(self,items):node=selffor i in items:if i in node.val.keys():node.val[i][0]+=1else:node.val[i]=[1,node.cnt]node.cnt+=1node.children.append(FPTree(i))node = node.children[node.val[i][1]]def __str__(self):return str(self.n)def getFPTree(self):tem=list(zip(list(self.val.items()),self.children))while tem:a=tem.pop()print("Node: %s"%a[0][0],"val: %d"%a[0][1][0])tem+=list((zip(list(a[1].val.items()),a[1].children)))A=FPTree()
A.growth(["a","b","c","d"])
A.growth(["a","b","c","e"])
A.getFPTree()Node: a val: 2
Node: b val: 2
Node: c val: 2
Node: e val: 1
Node: d val: 1
二、FP树挖掘
现在,我们需要从项头表的底部开始向上挖掘,找到每一项的条件模式基(Condition Pattern Base)。
所谓的条件模式基,就是一个以当前要挖掘节点为叶子结点的路经集合,或者说是一颗子树。
例如:
在这颗FP树中,到节点m
的路径有:fcafcafca和fcabfcabfcab,对这个路径集合每个节点的计数设为叶子节点mmm的计数:
fca:2,fcab:1fca:2,fcab:1fca:2,fcab:1,此时,各个节点的计数为:
Node | Cnt |
---|---|
f | 3 |
c | 3 |
a | 3 |
b | 1 |
此时删除低于支持度的节点,并对剩下的节点递归构建FP树。直到只剩下单一路径为止。
这单一路径上的所有节点组合,都可以是频繁模式。
优点
这个一般涉及到概念级的挖掘了。例如:
统一支持度
▪ 自上而下,水平
▪ 对每个级别使用统一的最小支持度
▪ 在每个级别执行Apriori
▪ 优化:如果祖先不频繁,可以避免对后代的搜索
缺点
错过阈值过高的感兴趣规则
生成太多不感兴趣的阈值太低的规则
减少支持度
▪ 自上而下,水平
▪ 每个概念级别都有自己的最低支持阈值
▪ 级别越低,阈值越小
▪ 在每个级别执行Apriori
优化–按单个项目进行级别交叉过滤
▪ 按单个项目进行级别交叉过滤
•如果第(i-1)级的父概念频繁,则检查第i级的项目
•如果概念不常见,则从数据库中删除其后代
缺点
优化–通过单个项目进行受控制的层级交叉过滤
下一级min sup<水平通过阈值
如果满足等级通过阈值,则允许检查不满足min_sup的项目的子项
由于项目之间的“祖先”关系,某些规则可能是多余的
实例
牛奶→\to→ 小麦面包 [支持度=8%,置信度=70%]
2%牛奶$\to $小麦面包 [ 支持度=2%,置信度=72%]
我们说第一条规则是第二条规则的祖先,如果基于规则的祖先,规则的支持接近“预期”值,则该规则是多余的
一维规则:
购买(X,“牛奶”)→\to→ 购买(X,“面包”)
多维规则:>2维或谓词
▪ 维度间关联规则(无重复谓词)
年龄(X,“19-25”)andandand 职业(X,“学生”)→\to→ 购买(X,“焦炭”)
▪ 混合维度关联规则(重复谓词)
年龄(X,“19-25”)andandand 购买(X,“爆米花”)→\to→购买(X,“焦炭”)
数值属性动态离散化
▪ 使得挖掘的规则的置信度或紧凑性最大化
关联规则聚类系统(ARCS)
▪ 装箱:二维网格,可管理大小
▪ 查找频繁的谓词集:扫描数据库,计数
每个网格单元的支持
▪ 对规则进行聚类:对相邻单元格进行聚类以形成规则
to$ 小麦面包 [支持度=8%,置信度=70%]
一维规则:
购买(X,“牛奶”)→\to→ 购买(X,“面包”)
多维规则:>2维或谓词
▪ 维度间关联规则(无重复谓词)
年龄(X,“19-25”)andandand 职业(X,“学生”)→\to→ 购买(X,“焦炭”)
▪ 混合维度关联规则(重复谓词)
年龄(X,“19-25”)andandand 购买(X,“爆米花”)→\to→购买(X,“焦炭”)
数值属性动态离散化
▪ 使得挖掘的规则的置信度或紧凑性最大化
关联规则聚类系统(ARCS)
▪ 装箱:二维网格,可管理大小
▪ 查找频繁的谓词集:扫描数据库,计数
每个网格单元的支持
▪ 对规则进行聚类:对相邻单元格进行聚类以形成规则