尿片与啤酒不得不说的故事
摘要:尿片与啤酒是数据挖掘的经典传奇,是美国第一大零售商沃尔玛公司发现的消费关联模式,本文通过数据挖掘的一般过程和算法,揭示如何发现了这一经典传奇。
关键词:数据仓库、事务数据库、关联规则、支持度、置信度、相关性
数据挖掘(DataMining)就是从大量数据中提取或“挖掘”知识。
一、数据预处理
首先是构造数据仓库(DataWarehouses),数据仓库是一个面向主题的、集成的、时变的、非易失的数据集合,通过数据清理、数据变换、数据集成、数据装入和定期数据刷新来构造。典型的数据仓库结构如下:
一个商店的售出商品包含有多方面的信息,比如常见的有售出时间、区域、种类、品牌等多个维(Dimension),就本议题而言,我们只关心种类这一个维,而其它的维则可以通过上卷(Roll-up)、维归约(Dimensionality Reducation)、切片(Slice)、切块(Dice)等联机分析处理(OLAP)操作进行排除,从而得到所需的事务数据库。
二、事务数据库
事务数据库可以是一个文件,也可以存放在表中,每个记录代表一个事务,每个事务中的项唯一。对于本议题,以顾客的一次购买行为作为一个事务,下表是示例用事务数据库片断(商品ID的第一列为该事务包含的项数):
事务ID | 商品ID |
1 | 9 I17 I20 I22 I35 I37 I60 I62 I72 I73 |
2 | 7 I39 I51 I53 I54 I57 I65 I73 |
3 | 9 I17 I20 I21 I22 I34 I37 I62 I73 I76 |
… | … |
三、关联规则挖掘中的概念
尿片与啤酒为什么能联系在一起作为一种消费组合,关联规则挖掘就是寻找给定数据集中项之间的有趣联系。关联规则是否“有趣”,取决与规则的支持度和置信度。
设I={i1, i2,…,im}是项的集合,设任务相关的数据D是数据库事务的集合,其中每个事务T是项的集合,T是I的子集;设A是一个项集,事务T包含A当且仅当A是T的子集。关联规则是形如AèB的蕴涵式,其中A、B是I的真子集,且A∩B=空集。规则AèB在事务D中成立,具有支持度s和置信度c;其中s是事务D中包含A∪B的百分比,c是事务D中包含A的事务同时也包含B的百分比。用公式表示如下:
support(A è B) = P(A∪B)
confidence(A è B) = P(A|B)
对于本论题而言,顾客一次购买行为是一个购买事务,则支持度是同时购买尿片和啤酒的事务数占所有购买事务数的百分比,置信度是在所有购买尿片的事务中也购买啤酒的事务的百分比。
满足给定支持度的项的集合,称为频繁项集(frequent itemset)。
满足给定支持度和置信度的规则称为强关联规则。
关联规则的挖掘一般分为两个步骤:
1) 找出所有的频繁项集;
2) 由频繁项集产生强关联规则。
四、关联规则挖掘
关联规则挖掘的方法有Apriori算法和频繁模式增长(frequent-pattern growth)等算法。Apriori算法需要产生候选项集,且需要重复的扫描数据库因而效率很低。在此主要介绍频繁模式增长算法(简称频繁模式增长或FP-增长)。
FP-增长采用如下分治策略:将提供频繁项集的数据库压缩到一棵频繁模式树(或FP-树),但仍保留项集相关信息;而后将这种压缩后的数据库分成一组条件数据库(一种特殊类型的投影数据库),每个关联一个频繁项,并分别挖掘每个数据库。考察如下事务数据:
事务ID | 项ID |
T100 | I1, I2, I5 |
T200 | I2, I4 |
T300 | I2, I3 |
T400 | I1, I2, I4 |
T500 | I1, I3 |
T600 | I2, I3 |
T700 | I1, I3 |
T800 | I1, I2, I3, I5 |
T900 | I1, I2, I3 |
假定最小事务支持计数为2,则第一次扫描该事务数据库的到频繁1-项集L1=[I2:7, I1:6, I3:6,I4:2, I5:2]。
构建FP-树的步骤如下:
1) 创建树的根节点,项ID由null标记;
2) 再次扫描事务数据库,每个事务中的项按L1中递减支持度秩序排序,并对每个事务创建一个分枝,如果后续加入的事务和之前的有共享的前缀节点,则共同前缀上的每个节点计数增加1。
3) 创建一个项头表,使得每个项通过一个节点链指向树中的节点。
经过上述步骤,数据库频繁模式的挖掘问题转化成挖掘FP-树的问题。如下图:
接下来是FP-树的挖掘,由长度为1的频繁模式(初始后缀模式)开始,构造它的条件模式基(一个“子数据库”,由FP-树中与后缀模式一起出现的前缀路径集组成);然后,构造它的条件FP-树,并递归地在该树上进行挖掘。模式增长通过后缀模式与由条件FP-树产生得分频繁模式连接实现。结果如下表:
项 | 条件模式基 | 条件FP-树 | 产生的频繁模式 |
I5 | {(I2 I1:1),(I2 I1 I3:1)} | <I2:2,I1:2> | I2 I5:2,I1 I5:2,I2 I1 I5:2 |
I4 | {(I2 I1:1),(I2:1)} | <I2:2> | I2 I4:2 |
I3 | {(I2 I1:2),(I2:2),(I1:2)} | <I2:4,I1:2>,<I1:2> | I2 I3:4,I1 I3:4,I2 I1 I3:2 |
I1 | {(I2:4) } | <I2:4> | I2 I1:4 |
对于I3节点,其条件FP-树如下:
FP-树的挖掘总结如下表:
算法:FP-增长。使用FP-树,通过模式段增长,挖掘频繁模式。 输入:事务数据库D;最小支持度阈值min_sup。 输出:频繁模式的完全集。 方法: (1) 按一下步骤构造FP-树: (a) 扫描事务数据库D一次,收集频繁项佛然集合F和它们的支持度。对F按支持度降序排序,结果为频繁项表L。 (b) 创建F-树的根节点,以“null”标记它。对D中每个事务Trans,执行:选择Trans中的频繁项,并按L中的次序排序。设排序后的频繁项表为[p|P],其中p是第一个元素,而P是剩余元素的表。调用insert_tree([p|P],T),该过程执行情况如下。如果T有子女N使得N.item-name = p.item-name,则N的计数增加1;否则创建一个新节点N,将其计数设置为1,链接到它的父节点T,并且通过节点链结构将其链接到具有相同item-name的节点。如果P非空,递归地调用insert_tree(P,N)。 (2) FP-树的挖掘通过调用FP_grown(FP_tree, null)实现。实现如下: Procedure FP_growth(Tree, α) 1) if Tree含单个路径P Then 2) for 路径P中节点的每个组合(记作β) 3) 产生模式β∪α,其支持度support = β中节点的最小支持度; 4) else for eachαi 在Tree的头部 { 5) 产生一个模式β=αi∪α,其支持度support=αi.support; 6) 构造β的条件模式基,然后构造β的条件FP-树Treeβ; 7) if Treeβ≠空 then 8) 调用FP_growth(Treeβ, β) |
FP-增长方法将发现长频繁模式的问题转换成递归地发现一些短模式,然后连接后缀;使用最不频繁的项作后缀,提供了好的选择性。该方法大大降低了搜索开销。
给定支持度为25%,频繁项集为K=2,执行本文附带的例程,得到如下结果:
事务数:5577 项数:74 支持度项数:1394 真实K项集:2 共 7 项频繁 1-项集 [事务数 支持度] I28 [2826 50.6724%] I73 [2813 50.4393%] I22 [2652 47.5524%] I65 [2012 36.0767%] I54 [1865 33.4409%] I71 [1582 28.3665%] I59 [1455 26.0893%] 共 5 项频繁 2-项集 [事务数 支持度] I73 I65 [1928 34.5706%] I73 I54 [1820 32.634%] I65 I54 [1593 28.5637%] I73 I22 [1521 27.2727%] I73 I28 [1424 25.5334%] |
我们假定I73代表啤酒,I54代表尿片,则
support(尿片è 啤酒) = P(I73∪I54)/ 5577 = 1820/5577 =32.634%
confidence(尿片è 啤酒) = P(I73∪I54)/P(I73) = 1820/2826 =64.402%
如果我们指定置信度阈值为60%,那么如下的布尔关联规则是强关联规则:
buys(X, “尿片”) è buys(X, “啤酒”)
五、相关性分析
强关联规则并不一定都有趣,有时A è B,并不代表A的出项就蕴涵着B的出现。因此,我们还需要进行相关性分析,A和B之间的相关性可通过如下公式计算:
corrA,B = P(A∪B)/ P(A)P(B)
来衡量,corrA,B的结果小于1,则A的出现和B的出现负相关,即A的出现导致B的减少;结果大于1,是正相关,即A的出现会导致B可能出现;结果等于1,则A和B是独立的。
对于本论题,尿片和啤酒的相关性为
corr尿片,啤酒 = P(I73∪I54)/ P(I73)P(I54) = 0.32634/(0.504393*0.334409)= 1.93
结果大于1,所以尿片和啤酒是正相关的。
给定支持度为25%,频繁项集为K=2的测试中没有负相关的例子,不过可以重置给定支持度和频繁项集数,比如5%和2,可以找到如下负相关的例子:
corrI73,I34 = P(I73∪I34)/ P(I73)P(I34) = 0.0591716/(0.504393*0.131074) = 0.895
即I73、I34是负相关的。实际的购物行为中,常会碰到一种商品销量的增加会导致另一种商品销售量的减少。
六、附带例程说明
VC例程和测试数据可在(程序先不上传啦) 下找到,FP-增长算法在fptree.h中,用标准C++模板编写,在Windows和Linux平台下均已测试, Bin子目录下是执行程序、测试用数据和输出结果,请拷贝到本地机器测试。