关联规则
- 在美国,一些年轻的父亲下班后经常要到超市去买婴儿尿布,超市也因此发现了一个规律,在购买婴儿尿布的年轻父亲们中,有30%~40%的人同时要买一些啤酒。超市随后调整了货架的摆放,把尿布和啤酒放在一起,明显增加了销售额。
- 若两个或多个变量的取值之间存在某种规律性,就称为关联
例子:
置信度
置信度: 表示你购买了A商品后,你还会有多大的概率购买B商品。
- 置信度(牛奶→啤酒)=2/4=0.5,代表如果你购买了牛奶,有多大的概率会购买啤酒?
- 置信度(啤酒→牛奶)=2/3=0.67,代表如果你购买了啤酒,有多大的概率会购买牛奶?
- 我们能看到,在 4 次购买了牛奶的情况下,有 2 次购买了啤酒,所以置信度 (牛奶→啤酒)=0.5,而在 3 次购买啤酒的情况下,有 2 次购买了牛奶,所以置信度(啤酒→牛奶)=0.67。
支持度
支持度: 支持度是一个百分比,指某个商品组合出现的次数与总次数之间的比例,支持度越高表示该组合出现的几率越大。
- 在上面图中我们可以发现“牛奶”出现了 4 次,那么这 5 笔订单中“牛奶”的支持度就是 4/5=0.8。
- 同样“牛奶 面包”出现了 3 次,那么这 5 笔订单中“牛奶 面包”的支持度就是 3/5=0.6。
提升度
提升度: 在做商品推荐的时候,提升度是重点考虑对象,提升度代表商品A的出现,对商品B的出现概率提升了多少,即“商品 A 的出现,对商品 B 的出现概率提升的”程度。
从上面的例子中,如果我们单纯看置信度 (可乐→尿布)=1,也就是说可乐出现的时候,用户都会购买尿布,那么当用户购买可乐的时候,我们就需要推荐尿布么?
实际上,就算用户不购买可乐,也会直接购买尿布的,所以用户是否购买可乐,对尿布的提升作用并不大。我们可以用下面的公式来计算商品 A 对商品 B 的提升度:
提升度 (A→B)= 置信度 (A→B)/ 支持度 (B)
这个公式是用来衡量 A 出现的情况下,是否会对 B 出现的概率有所提升。
提升度有三种可能:
- 提升度 (A→B)>1:代表有提升;提升度
- 提升度(A→B)=1:代表有没有提升,也没有下降;
- 提升度 (A→B)<1:代表有下降。
开发环境
- jupyter notebook
- mlxtend
- Apriori
安装
代码语言:javascript复制pip install efficient-apriori
pip install mlxtend
mlxtend
使用mlxtend工具包得出频繁项集与规则
代码语言:javascript复制import pandas as pd
from mlxtend.frequent_patterns import apriori
from mlxtend.frequent_patterns import association_rules
自定义一份购物数据集
代码语言:javascript复制data = {'ID':[1,2,3,4,5,6],
'Onion':[1,0,0,1,1,1],
'Potato':[1,1,0,1,1,1],
'Burger':[1,1,0,0,1,1],
'Milk':[0,1,1,1,0,1],
'Beer':[0,0,1,0,1,0]}
df = pd.DataFrame(data)
df
效果如图
设置支持度 (support) 来选择频繁项集.
- 选择最小支持度为50%
apriori(df, min_support=0.5, use_colnames=True)
frequent_itemsets = apriori(df[['Onion', 'Potato', 'Burger', 'Milk', 'Beer' ]], min_support=0.50, use_colnames=True)
frequent_itemsets
效果如下
观察:返回的3种项集均是支持度>=50%
计算规则
association_rules(df, metric='lift', min_threshold=1)
- 可以指定不同的衡量标准与最小阈值
rules = association_rules(frequent_itemsets, metric='lift', min_threshold=1)
rules
效果如下
- python中的正无穷或负无穷,使用float("inf")或float("-inf")来表示。
返回的是各个的指标的数值,可以按照感兴趣的指标排序观察,但具体解释还得参考实际数据的含义
代码语言:javascript复制rules [ (rules['lift'] >1.125) & (rules['confidence']> 0.8) ]
这几条结果就比较有价值了:
- (洋葱和马铃薯)(汉堡和马铃薯)可以搭配着来卖
- 如果洋葱和汉堡都在购物篮中, 顾客买马铃薯的可能性也比较高,如果他篮子里面没有,可以推荐一下.
Apriori
代码语言:javascript复制from efficient_apriori import apriori
transactions = [('eggs', 'bacon', 'soup'),
('eggs', 'bacon', 'apple'),
('soup', 'bacon', 'banana')]
itemsets, rules = apriori(transactions, min_support=0.5, min_confidence=1)
print(rules) # [{eggs} -> {bacon}, {soup} -> {bacon}]
print(itemsets) # {1: {('bacon',): 3, ('eggs',): 2, ('soup',): 2}, 2: {('bacon', 'eggs'): 2, ('bacon', 'soup'): 2}}
- 官网例子
- min_support表示最小支持度,min_confidence表示最小置信度,最小支持度和最小置信度都是由百分比表示0.5表示50%,可以使用0-1中的数字表示。
- 支持度大于最小支持度就是频繁项集,反正为非频繁项集,不符合最小置信度和最小支持度的项集都会被剔除。
from efficient_apriori import apriori
# 设置数据集
data = [('牛奶','面包','尿布'),
('可乐','面包', '尿布', '啤酒'),
('牛奶','尿布', '啤酒', '鸡蛋'),
('面包', '牛奶', '尿布', '啤酒'),
('面包', '牛奶', '尿布', '可乐')]
itemsets,rules=apriori(data,min_support=0.5,min_confidence=1)
print(itemsets)
print('---------')
print(rules)
- 输出结果:
{1: {('啤酒',): 3, ('尿布',): 5, ('牛奶',): 4, ('面包',): 4}, 2: {('啤酒', '尿布'): 3, ('尿布', '牛奶'): 4, ('尿布', '面包'): 4, ('牛奶', '面包'): 3}, 3: {('尿布', '牛奶', '面包'): 3}}
---------
[{啤酒} -> {尿布}, {牛奶} -> {尿布}, {面包} -> {尿布}, {牛奶, 面包} -> {尿布}]
前面的1表示频繁1项集 2 表示频繁2项集 3表示频繁3项集
表示选啤酒很大几率会买尿布 买牛奶很大几率买尿布 买面包很大几率会买尿布 买牛奶和面包很大几率会买尿布
生活中当然不是这样子,因为数据集是捏造的,你见过有人买牛奶面包,顺便买尿布。