目录
一、概念
1、背景
关联规则(Association Rules)反映一个事务与其他事务之间的相互依存性和关联性。如果2个或多个事务之间存在一定的关联关系,那么,其中一个事务九能够提过其他事务预测到。
- 关联规则是无监督学习方法,用于知识发现,而非预测
- 关联规则的学习器无需事先对训练数据进行打标签,因为无监督学习没有模型训练步骤。缺点是很难对关联规则学习器进行模型评估,一般可以通过业务观测结果是否合理
- 关联规则著名案例:尿布与啤酒、购物篮分析,可以用于电影推荐。关联分析的结果可以用于市场规划、广告策划、分类设计等
2、使用场景
- 销售:通过交叉分析获得更大收入
- 保险:分析索赔要求发现潜在欺诈行为
- 银行:分析顾客消费行业,针对性的推荐其感兴趣的服务
- 制作业:分析制造零件和设备装置与故障事件关联性
- 医学:哪些病人和药物属性与结果有关联
- 新闻推荐:根据浏览历史推荐;
3、事务数据库(transaction database)
- 存储着二维结构的记录集,记为D,或称事物记录集D,简称事务集D
- 事务集D中包含事物的个数称为|D|
- 下表为一个简单的事务数据集,|D|=7
TID | 商品 |
---|---|
t1 | 牛肉、鸡肉、牛奶 |
t2 | 牛肉、奶酪 |
t3 | 奶酪、靴子 |
t4 | 牛肉、鸡肉、奶酪 |
t5 | 牛肉、鸡肉、牛奶、衣服、奶酪 |
t6 | 鸡肉、牛奶、衣服 |
t7 | 鸡肉、牛奶、衣服 |
4、所有项集
- 设I = {i1,i2,…im}是m个不同项目的集合,每个ik(k=1,2,…,m)称为一个项目(item),I是所有项目item的集合,称之为所有项集items
- 示例中I= {牛肉、鸡肉、牛奶、衣服、奶酪},其中,“牛肉”、“鸡肉”等均称之为项目item
5、事务
- 在事务数据集里的每一笔记录,记为T,T∈D
- 每个事务T(transaction)是所有项集I的一个子集,即T⊆I
- {牛肉、鸡蛋、牛奶}便是一个事务
- 每个事务有一个唯一的标识-事务号,记作TID
6、项集ItemSet
- 项目的集合X称之为项目集合ItemSet,简称为项集。其中元素个数为项集的长度,长度为k的项集成为k-项集
- 如{牛奶}、{鸡肉}均为1-项集,{牛肉、奶酪}为2-项集
7、支持度
-
对于项集X,count为事务集D中包含X的数量,项集X的支持度就是项集X出现的概率。项集支持度用于描述X的重要性,计算方式:
Support(X) = count(X⊆T) / |D|
-
项集的支持度就是该项集出现的次数除以总的记录数(事务数)
Support({牛肉、鸡肉}) = 3/7
Support({奶酪、鸡肉}) = 2/7
8、频繁项集
- 支持度的意义在于度量项集在整个事务集中出现的频次。我们在发现规则的时候,希望关注频次高的项集;
- 发现关联规则要求项集必须满足的最小支持度阈值,称为项集的最小支持度(minimum Support),记为supmin
- 支持度大于或等于最小支持度的项集称为频繁项集,简称频繁集,反之称为非频繁集
- 通常k-项集如果满足supmin,称为k-频繁集,记作Lk
9、关联规则
- 关联规则可以表示为一个蕴含式:R:X→Y
- 其中X⊂I,Y⊂I,并且X∩Y=∅
- X是这条规则的left-hand-side(LHS or antecedent,前件),Y是这条规则的right-hand-side(RHS or consequent,后件)
- LHS和RHS的项集不能有交集
- 示例:
R: 纸尿裤→啤酒
R:牛肉→鸡肉
10、关联规则的支持度
-
关联规则可以表示为一个蕴含式:R:X→Y,并且X⊂I,Y⊂I,并且X∩Y=∅
-
规则R的支持度三交易集中同时包含X和Y的交易数与所有交易数之比
Support(X→Y) = Count(X∪Y) / |D|
-
支持度计算在事务集中,既有X又有Y的概率
-
例如:在7条记录中,既有鸡肉又有牛肉的记录有3条,则
R:牛肉→鸡肉的支持度为3/7,Support(A→B) = P(AB)表示在所有顾客当中有3/7同时购买来牛肉和鸡肉,其反映了同时购买鸡肉、牛肉的顾客在所有顾客当中的覆盖范围
11、关联规则的置信度confidence
-
对于关联规则可以表示为一个蕴含式:R:X→Y,并且X⊂I,Y⊂I,并且X∩Y=∅;
-
规则R的置信度是指包含X和Y的交易数与包含Y的交易数之比:
confidence(X→Y) = Support(X∪Y) / Support(X)
-
规则的置信度的意义在于项集{X,Y}同时出现的次数占项集{X}出现次数的比例,即发生X的条件下又发生Y的概率;
-
例如:在7条记录中,购买牛肉的记录有4条,在4条记录中又有3条记录显示购买了鸡肉,即R:牛肉→鸡肉的置信度为3/4,表示来在购买牛肉的顾客当中有3/4的人买了鸡肉,反映了可预测的程度,即顾客买了牛肉的话有多大可能性买鸡肉;
-
从概率论角度看,可以把顾客买了牛肉之后有多大可能性买鸡肉看作是条件概率,即:
confidence(X→Y) = P(X|Y)
最小支持度(minimum Support)记为supmin,最小置信度(minimum confidence)记为confmin,分别表示关联规则需要满足的最低重要性、可能性;为阈值参数,必须在算法运行前指定;表示用户只对某些规则感兴趣,这些规则表示数据集的最低支持度、拥有比较高的概率。supmin用于对项集限制,而不是对规则限制,confmin对项集无影响,影响的是规则。
如果Support(X→Y) ≥supmin confidence(X→Y) ≥confmin则称为强关联规则,否则为弱关联规则。
12、提升度Lift
-
规则的提升度的意义在于度量项集{X}和项集{Y}的独立性
Lift(X→Y) = Support(X∪Y) / [ Support(X) * Support(Y) ]
= confidence(X→Y) / Support(Y)
-
如果2个条件互相独立,则P(XY) = P(X) * P(Y),即提升度为1;如果小于1,说明使用这条规则推荐无效;一般在数据挖掘中提升度大于3时,才认为挖掘出的关联规则是有价值的;
-
例子:如果10000个事务中,6000个事务包含计算机游戏,7500包含游戏机游戏,4000个事务同时包含二者:
关联规则(计算机游戏→游戏机游戏)支持度为4000/10000=0.4,置信度为4000/6000=0.67,但这个规则存在误导;
提升度角度计算:假设购买计算机游戏为X,购买游戏机游戏为YLift(X→Y) = Support(X∪Y) / [ Support(X) * Support(Y) ] = confidence(X→Y) / Support(Y) = 0.67 / 0.75 = 0.89 0.89<1,推荐无效,不如不推荐。
二、关联规则生成
1、生成候选项集
生成候选项集,然后根据指定的最小支持度,过滤掉非频繁项集,生成频繁项集
2、重复遍历
第一次遍历,对所有单项的支持度进行计数,并确定频繁项;在后续的每次遍历中,利用上次遍历所得频繁项集作为种子项集,产生新的频繁项集-候选项集,并对候选项集的支持度进行计数,在本次遍历结束时统计满足最小支持度的候选项集,本次遍历对应的频繁项集就算是确定了,这些频繁项集又成为下一次遍历的种子;重复此遍历过程,直到不再能发现新的频繁项集。
3、示例
现有5种商品交易记录,找出频繁项集并生成关联规则,假设最小支持度和最小置信度均为≥50%
交易号 | 商品代码 |
---|---|
T1 | A,C,D |
T2 | B,C,E |
T3 | A,B,C,E |
T4 | B,E |
1、寻找频繁项集-第一次扫描
- 生成候选1-项集C1,计算支持度
- 根据最小支持度,生成频繁1-项集L1
C1:
项集 | 支持度 |
---|---|
{A} | 50% |
{B} | 75% |
{C} | 75% |
{D} | 25% |
{E} | 75% |
L1:
频繁项集 | 支持度 |
---|---|
{A} | 50% |
{B} | 75% |
{C} | 75% |
{E} | 75% |
2、第二次扫描
- 生成候选2-项集C2,计算支持度
- 根据最小支持度,生成频繁2-项集L2
C2:
项集 | 支持度 |
---|---|
{A,B} | 25% |
{A,C} | 50% |
{A,E} | 25% |
{B,C} | 50% |
{B,E} | 75% |
{C,E} | 50% |
L2:
频繁项集 | 支持度 |
---|---|
{A,C} | 50% |
{B,C} | 50% |
{B,E} | 75% |
{C,E} | 50% |
3、第三次扫描
- 生成候选3-项集C3,计算支持度
- 根据最小支持度,生成频繁3-项集L3
C3:
项集 | 支持度 |
---|---|
{A,B,C} | 25% |
{A,C,E} | 25% |
{B,C,E} | 50% |
L3:
频繁项集 | 支持度 |
---|---|
{B,C,E} | 50% |
4、生成关联规则
- 生成关联规则时,最简单的办法就是对每个频繁项集,列出其所有非空真子集,任取其中2个座位LHS、RHS,形成关联规则,并及时关联规则置信度,删除弱规则
- 上例中,对于频繁项集{B,C,E},其非空子集有{B},{C},{E},{B,C},{B,E},{C,E},据此获得的关联规则及其置信度,置信度≥50%(最小置信度),都是强规则
规则 | 置信度 |
---|---|
B →{C,E} | 66.7% |
C→{B,E} | 66.7% |
E →{C,B} | 66.7% |
{C,E} →B | 1 |
{B,E} →C | 66.7% |
{C,B} →E | 1 |
生成频繁项集的过程中,对于4种物品的集合,需要遍历数据15次;对于包含N种物品的数据有2的n-1次方种项集组合;假设有100种商品,则有1.26*10∧30种可能的项集组合,计算量巨大,apriori算法可以减少计算量。
三、Apriori算法
1、原理
Apriori算法是发现频繁项集的一种方法,Apriori算法的两个输入参数分别三最小支持度和数据集。该算法首先会生成所有单个元素的项集列表。接着扫描数据集来查看哪些项集满足最小支持度要求,那些不满足最小支持度的集合会被去掉。然后对剩下来的集合进行组合以生成包含2个元素的项集。接下来在重新扫描交易记录,去掉不满足最小支持度的项集,该过程重复进行直到所有项集都被去掉。
原理:
- 某个项集是频繁的,那么它的所有子集也是频繁的;更常用的三它的逆命题,如果一个项集三非频繁的,那么它的所有超集也是非频繁的(称为项集的反单调性,向下闭合性)
- Apriori在拉丁语指“来自以前”。当定义问题时,通常会使用先验知识或假设,称作“一个先验(Apriori)”。在贝叶斯统计中,使用先验知识作为先验判断。
- 反单调性能迅速剪枝,提高搜索频繁项集的处理效率。
示例:已知阴影项集{2,3}是非频繁的,利用Apriori原理,我们知道项集{0,2,3},{1,2,3},{0,1,2,3}也是非频繁的,紧接着就可以排除它们
从频繁项集中挖掘相关规则: - 如果某条规则并不满足最小置信度要求,那么该规则的子集也不会满足最小置信度要求。假设{0,1,2}→{3}不满足最小置信度要求那么就知道任何前件为{0,1,2}子集的规则也不会满足最小置信度要求,可以利用关联规则的上述性质来减少测试的规则数目,类似apriori算法求解频繁项集
2、寻找频繁项集
- apriori假设事物或项集里的各项已经预先按字典顺序进行排列
- apriori三已知逐层搜索的迭代方法,利用k-项集搜索(k+1)-项集。首先找出频繁1-项集的集合,记为L1;再用L1找频繁2-项集的集合L2;再用L2找L3…如此下去,直到不能找到频繁k-项集为止;找每个Lk需要扫描一次数据库
- 整个过程由连接和剪枝两步组成,即:连接步产生候选项集,剪枝步确定频繁项集
1、寻找频繁项集:连接步
- 为找Lk,可通过Lk-1与自己连接,产生一个候选k-项集的集合,该候选项集的集合记作Ck
- 设p和q是Lk-1中的项集,记号p[i],q[i]分别表示p、q的第i项,为方便计,假设事务或项集中的项集中的项按字典次序排序
- 连接条件1:p和q的前k-2个项相同,即p[1]=q[1]&p[2]=q[2]&…&p[k-2]=qk-2
- 连接条件2:p[k-1]<qk-1
2、寻找频繁项集:剪枝步
- Ck是Lk的超集,即它的成员不一定都是频繁项集,但所有的频繁k-项集都包含在Ck中
- 扫描数据库,确定Ck中每个候选项集的计数,从而确定Lk。然而Ck的可能很大,这样所涉及的计算量就很大
- 未来压缩Ck,利用apriori的性质:任何非频繁项集的(k-1)-项子集不在Lk-1中,则该候选也不可能三频繁的,从而可以从Ck中删除
3、生成关联规则
- 得到频繁项集后,则需要从频繁项集中找出符合条件的关联规则。最简单的办法是:遍历所有的频繁项集,然后从每个项中一次取1、2、…k个元素作为前件,则该项集中的其他元素作为后件,计算该规则的置信度进行筛选即可
- 利用apriori原理进行兼职
四、Apriori算法示例
1、读取数据
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
df=pd.read_excel("./data/apriori/Online Retail.xlsx")
df.head(5)
2、查看数据信息
# invoiceNO发票编号
# Stodckcode商品的代码
# Description 商品的描述
# Quantity 商品的数量
# InvoiceDate开票的日期
# UnitPrice单价
# CustomerID客户编码
# Country地区
df.info()
df.isnull().sum()
3、数据清洗
df_copy=df.copy()
#对于description这一列有空 不知道商品内容 delete
df_copy.dropna(subset=["Description"],inplace=True,axis=0)
# 对于description这一列的数据去掉首尾的空格
df_copy["Description"].str.strip()
#去掉包含C字母开头的发票编号的订单 这些订单表示退货
df_copy=df_copy.loc[~df_copy["InvoiceNo"].astype(str).str.contains("C")]
df_copy.head()
如果电脑内存不够,则需要缩小数据集
df_copy_France=df_copy[df_copy["Country"]=="France"]
df_copy_France
# 去重后查看数据
df_copy_France.drop_duplicates(inplace=True)
df_copy_France=df_copy_France.pivot_table(index="InvoiceNo",columns="Description",values="Quantity")
df_copy_France
# 数据编码,有值表示购买,赋值为1,无值表示未购买,赋值为0
def encode_units(x):
if x>0:
return 1
else:
return 0
df_copy_France=df_copy_France.applymap(encode_units)
df_copy_France.head()
#这些商品中 邮费 POSTAGRE这个商品不是我们想要的 删除
df_copy_France.drop(columns="POSTAGE",inplace=True)
4、算法建模
# 模块安装: pip install -i https://pypi.tuna.tsinghua.edu.cn/simple mlxtend
from mlxtend.frequent_patterns import apriori,association_rules
关联算法无训练过程,直接建模,第一步首先找频繁项集
frequent_itemsets=apriori(df_copy_France,min_support=0.07,use_colnames=True)
frequent_itemsets
生成规则
rules=association_rules(frequent_itemsets,metric="lift",min_threshold=3)
rules.head(5)
可以对规则进一步筛选
rules[
(rules["lift"]>=6) # 提升度
&
(rules["confidence"]>=0.8) # 置信度
]
可以做出一些新的特征 如前件的长度
rules["ant_length"]=rules["antecedents"].map(lambda x:len(x))
rules.head(5)