今天本该是个剁手的日子,只可惜余额不足高攀不起那台i7-8565,只有再写一篇文章聊以慰籍~~
前言:之前很少做关于数据关联分析的题,而当初学关联分析时也是自己写代码来实现底层转换与运算,粗略一点的整体代码量也达到150行左右,所以没有高级的开源工具使用是很费时间的,由此阻碍了一颗想学习的心。后来遇到相关问题便Google了一些解决办法,其中有一个集成很优秀,使用也很方便的GitHub开源项目,也是本篇文章的重点——mlxtend
首先简单介绍一下关联分析的三个相关知识点:
频繁项集:
频繁项集是指那些经常出现在一起的物品,例如上图的{葡萄酒、尿布、豆奶},从上面的数据集中也可以找到尿布->葡萄酒的关联规则,这意味着有人买了尿布,那很有可能他也会购买葡萄酒。那如何定义和表示频繁项集和关联规则呢?这里引入支持度和可信度(置信度)。
支持度:
支持度:一个项集的支持度被定义为数据集中包含该项集的记录所占的比例,上图中,豆奶的支持度为4/5,(豆奶、尿布)为3/5。支持度是针对项集来说的,因此可以定义一个最小支持度,只保留最小支持度的项集。
置信度:
可信度(置信度):针对如{尿布}->{葡萄酒}这样的关联规则来定义的。计算为 支持度{尿布,葡萄酒}/支持度{尿布},其中{尿布,葡萄酒}的支持度为3/5,{尿布}的支持度为4/5,所以“尿布->葡萄酒”的可行度为3/4=0.75,这意味着尿布的记录中,我们的规则有75%都适用(买了尿布的顾客有75%还会买葡萄酒)。
上面简单介绍三个基本概念,下面我们就来利用 mlxtend 完整简单的实现上面购物表单的关联分析问题。
关联分析示例:
首先创建数据:
转换为DataFrame格式,然后再教一个后续转换回来的方法。
import pandas as pd
shopping_list = [['豆奶','莴苣'],
['莴苣','尿布','葡萄酒','甜菜'],
['豆奶','尿布','葡萄酒','橙汁'],
['莴苣','豆奶','尿布','葡萄酒'],
['莴苣','豆奶','尿布','橙汁']]
shopping_df = pd.DataFrame(shopping_list)
转换数据列表:
接着转换DataFrame数据为包含数据的列表。(由于我们接触到的可能是DataFrame数据所以这里介绍了两个转换为上面列表的方法)
# df_arr = shopping_df.stack().groupby(level=0).apply(list).tolist() # 方法一
def deal(data):
return data.dropna().tolist()
df_arr = shopping_df.apply(deal,axis=1).tolist() # 方法二
转换为模型可接受数据:
由于mlxtend的模型只接受特定的数据格式。(TransactionEncoder类似于独热编码,每个值转换为一个唯一的bool值)
from mlxtend.preprocessing import TransactionEncoder # 传入模型的数据需要满足特定的格式,可以用这种方法来转换为bool值,也可以用函数转换为0、1
te = TransactionEncoder() # 定义模型
df_tf = te.fit_transform(df_arr)
# df_01 = df_tf.astype('int') # 将 True、False 转换为 0、1 # 官方给的其它方法
# df_name = te.inverse_transform(df_tf) # 将编码值再次转化为原来的商品名
df = pd.DataFrame(df_tf,columns=te.columns_)
求频繁项集:
导入apriori方法设置最小支持度min_support=0.05求频繁项集,还能选择出长度大于x的频繁项集。
from mlxtend.frequent_patterns import apriori
frequent_itemsets = apriori(df,min_support=0.05,use_colnames=True) # use_colnames=True表示使用元素名字,默认的False使用列名代表元素
# frequent_itemsets = apriori(df,min_support=0.05)
frequent_itemsets.sort_values(by='support',ascending=False,inplace=True) # 频繁项集可以按支持度排序
# print(frequent_itemsets[frequent_itemsets.itemsets.apply(lambda x: len(x)) >= 2]) # 选择长度 >=2 的频繁项集
求关联规则:
导入association_rules方法判断'confidence'大于0.9,求关联规则。
from mlxtend.frequent_patterns import association_rules
association_rule = association_rules(frequent_itemsets,metric='confidence',min_threshold=0.9) # metric可以有很多的度量选项,返回的表列名都可以作为参数
association_rule.sort_values(by='leverage',ascending=False,inplace=True) #关联规则可以按leverage排序
# print(association_rule)
下面便得到了上表中满足设置条件的关联规则
mlxtend使用了 DataFrame 方式来描述关联规则,而不是 —> 符号,其中:
-
antecedents
:规则先导项 -
consequents
:规则后继项 -
antecedent support
:规则先导项支持度 -
consequent support
:规则后继项支持度 -
support
:规则支持度 (前项后项并集的支持度) -
confidence
:规则置信度 (规则置信度:规则支持度support / 规则先导项) -
lift
:规则提升度,表示含有先导项条件下同时含有后继项的概率,与后继项总体发生的概率之比。 -
leverage
:规则杠杆率,表示当先导项与后继项独立分布时,先导项与后继项一起出现的次数比预期多多少。 -
conviction
:规则确信度,与提升度类似,但用差值表示。
提升度计算公式:
其中,当先导项与后继项独立分布时,值为 1
,提升度越大,表示先导项与后继项的关联性越强。
杠杆率计算公式:
确信度计算公式:
确信度值越大,则先导项与后继项的关联性越强。 以上三个值都是越大关联强度也就越大。
mlxtend官网地址:https://rasbt.github.io/mlxtend/
mlxtend GitHub地址:https://github.com/rasbt/mlxtend