你不懂的关联规则

2019-08-29 11:27:22 浏览数 (1)

关联规则

  • 在美国,一些年轻的父亲下班后经常要到超市去买婴儿尿布,超市也因此发现了一个规律,在购买婴儿尿布的年轻父亲们中,有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)
代码语言:javascript复制
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)
  • 可以指定不同的衡量标准与最小阈值
代码语言:javascript复制
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中的数字表示。
  • 支持度大于最小支持度就是频繁项集,反正为非频繁项集,不符合最小置信度和最小支持度的项集都会被剔除。
代码语言:javascript复制
from efficient_apriori import apriori
# 设置数据集
data = [('牛奶','面包','尿布'),
           ('可乐','面包', '尿布', '啤酒'),
           ('牛奶','尿布', '啤酒', '鸡蛋'),
           ('面包', '牛奶', '尿布', '啤酒'),
           ('面包', '牛奶', '尿布', '可乐')]

itemsets,rules=apriori(data,min_support=0.5,min_confidence=1)

print(itemsets)
print('---------')
print(rules)
  • 输出结果:
代码语言:javascript复制
{1: {('啤酒',): 3, ('尿布',): 5, ('牛奶',): 4, ('面包',): 4}, 2: {('啤酒', '尿布'): 3, ('尿布', '牛奶'): 4, ('尿布', '面包'): 4, ('牛奶', '面包'): 3}, 3: {('尿布', '牛奶', '面包'): 3}}
---------
[{啤酒} -> {尿布}, {牛奶} -> {尿布}, {面包} -> {尿布}, {牛奶, 面包} -> {尿布}]
前面的1表示频繁1项集 2 表示频繁2项集 3表示频繁3项集
表示选啤酒很大几率会买尿布 买牛奶很大几率买尿布 买面包很大几率会买尿布 买牛奶和面包很大几率会买尿布

生活中当然不是这样子,因为数据集是捏造的,你见过有人买牛奶面包,顺便买尿布。

0 人点赞