免规则采集器列表算法( 如何使用Python实现关联规则的原理和实现步骤(上))
优采云 发布时间: 2022-04-07 18:18免规则采集器列表算法(
如何使用Python实现关联规则的原理和实现步骤(上))
PowerBI商品关联规则的可视化
在上一篇文章中,我解释了关联规则的原理和实现步骤。如果你理解它,它实际上很容易理解。但说起来容易做起来难,如何通过工具处理原创数据以获得有效可靠的结果仍然存在问题。实际的工作是让你解决问题,而不是仅仅谈论解决方案。本文以理论为基础,结合实际数据展示如何使用Python实现关联规则,以及如何在PowerBI中导入Python脚本生成数据表并以可视化的方式动态展示。
使用Python解决一个问题时,实际上并不是从0到1的一步一步构建,这个过程非常繁琐。有时,为了达到一个小的效果,可能要绕很多路,所以就像“调参”一样,我们倾向于使用其他内置的梯子。这就是 Python 语言如此受欢迎的原因,因为它拥有完善的开源社区和无数的工具库来实现某种目的。我们在实现关联规则的计算时,使用机器学习库mlxtend中的apriori、fpgrowth、association_rules算法。apriori 是一种流行的算法,用于提取关联规则学习中的频繁项集。先验算法旨在对收录交易的数据库进行操作,例如商店客户的购买。如果满足用户指定的支持阈值,则项集被认为是“频繁的”。例如,如果支持阈值设置为 0.5 (50%),则频繁项集定义为在数据库中至少 50% 的所有事务中一起出现的一组项。
一、数据集
#导入相关的库
import pandas as pd
import mlxtend #机器学习库
#编码包
from mlxtend.preprocessing import TransactionEncoder
#关联规则计算包
from mlxtend.frequent_patterns import apriori, fpmax, fpgrowth,association_rules
pd.set_option('max_colwidth',150) #对pandas显示效果设置,列显示字段长度最长为150个字符 #导入数据集
Order = pd.read_excel("D:/orders.xlsx")
#查看数据集的大小
Order.shape
#查看数据前10行
Order.tail(5)
数据集中有121253条数据,总共有四个字段。SalesOrderNumber 指订单号;ordernumber 是指子订单号。换行和数字表示订单的子订单。每个订单号下可能有一个或多个子订单。有子订单,每个子订单都是唯一的,对应一个产品;产品是指产品名称。
二、mlxtend
在真正开始之前,我们先来了解一下这个mlxtend中的包是怎么使用的。mlxtend 官网演示了如何实现关联规则的计算。我们来看看这三个步骤:
第一步,导入apriori算法包;
第二步,将原创订单数据处理成算法支持的格式;
第三步,计算support、confidence、lift等指标,过滤掉强规则。
第一步:导入先验算法包
第二步,将原创订单数据处理成算法支持的格式:
得到的实际数据往往和我之前文章中的例子一样,产品在订单号后面排列成一个列表。所以 mlxtend 包接受这种数据格式。但是,它不能直接用于计算。首先,真实数据都是文本。其次,apriori算法包需要将原创数据转换为商品的one-hot编码的Pandas Dataframe格式。这是输入数据:
它使用 TransactionEncoder 包将输入数据转换为我们需要的形式。这是转换后的代码和结果:
接下来,它将处理后的数据格式输入到 apriori 算法包中,以计算频繁项集和支持度。根据预设的最小支持度0.6,排除不频繁项集。
但是,上面有一个问题。上面返回的结果集是一个数字,其实就是df表中每一项(item)的索引,这样比较方便后面的处理,但是如果只想用这个结果的话。为了增加可读性,使用参数 use_colnames=True 来显示原创产品名称。
第三步,计算支持度、置信度和提升度
apriori算法包中没有演示第三步,这是为什么呢?因为apriori算法包只是关联规则的第一步——寻找频繁项集,当然强关联规则是不会找到的!这一步在另一个包 association_rules 中实现。这也是很多初学者容易遇到的问题。他们不知道每个包的用途,也不知道如何调用包。
这样,我们就可以计算出所有满足最小支持度的频繁项集的支持度、置信度和提升度。还有杠杆作用和收敛性。这两个的作用和之前说的lift的作用是一样的。最好使用 KLUC 指标和 IR 不平衡率,但显然 mlxtend 的开发人员更喜欢使用杠杆和信念,并将其放在一边。本案例仅演示支撑升降机的使用。
三、Python实现第一步关联规则代码,生成格式数据
以上是官网给出的关联规则包的使用方法。接下来我使用自己的数据集进行实际操作,演示如何在PowerBI中导入Python脚本生成数据表并以可视化的方式动态显示。上面已经给出了示例数据。可以看出,数据集每个订单有多个商品,但是是逐行的,而不是一个订单后跟一行所有商品的形式。所以这是一种从行转换为列的方法。这里使用了Pandas中的分组功能,要达到的效果如下:
#使用DataFrame的groupby函数
group_df = Order.groupby(['SalesOrderNumber'])
如果你会写SQL,你应该知道groupby必须和聚合函数一起使用,因为它是一个mapreduce过程。如果不使用聚合函数按订单号分组,SQL Server 会报错,Mysql 只会返回第一行数据。而这里直接使用groupby分组,不用聚合功能,这样会不会有问题?让我们看一下生成的 group_df:
group_df.head(2) #查看数据集
上图是groupby的结果(我以为是数据集),拿前2和前5看,发现返回的数据和数据集的大小不一样(注意我们的第一次查看数据显示121253条数据)。其实这个groupby的结果就是一个*敏*感*词*,它返回一个动态的分组过程。如果你想使用结果,你可以输入不同的参数来得到实际的结果。所以使用这个函数来实现group_oncat并生成一个产品列表。
df_productlist = pd.DataFrame({"productlist":group_df['Product'].apply(list)}).reset_index()
df_productlist.head(5)
上面代码的意思是生成一个新表,按SalesOrderNumber分组,然后将每个订单组的Products聚合成一个列表;此表只有两列,一列按 SalesOrderNumber 分组,另一列按 SalesOrderNumber 分组。将其命名为产品列表;最后去掉原创数据目标的索引,重新设置索引,最后得到df_productlist表,这样我们就形成了算法接受的输入数据格式。这是查看前 5 行的结果:
#因为只需要频繁项集,所以这里去掉订单号,将productlist转为numpy数组格式。
df_array = df_productlist["productlist"].tolist()
df_array[0:3] #取前三个查看
可以看出输入数据形成了,然后我们使用TransactionEncoder对数据进行处理,为每个item(item)生成one-hot编码的DataFrame格式:
第二步,生成频繁项集
生成最终的数据格式后,将数据馈送到 apriori 算法包生成频繁项集:
#给定最小支持度为0.01,显示列名
frequent_itemset = apriori(df_item,min_support=0.01,use_colnames=True)
frequent_itemset.tail(5)
算法生成的结果也是DataFrame格式的频繁项集。它将返回所有大于或等于最小支持度的结果,例如频繁 1 项集、频繁 2 项集和频繁 3 项集。这里显示的是频繁 1 项集。
其实为了方便我们查看和过滤,我们还可以统计频繁项集的长度,这样就可以动态索引了。
frequent_itemset['length'] = frequent_itemset['itemsets'].apply(lambda x: len(x))
frequent_itemset[ (frequent_itemset['length'] == 2) &(frequent_itemset['support'] >= 0.01) ]
这段代码的意思是找到支持度大于等于0.01的频繁2项集,也就是我们经常关心的客户购买一个产品的情况,他们会购买哪种产品。
在完成了上面生成频繁项集的第一步之后,下面就是挖掘关联规则了。
第三步,计算支持度、置信度和提升度
association = association_rules(frequent_itemset,metric="confidence",min_threshold=0.01)
association.head()
上表显示,一共找到了 169034 条关联规则可供选择。列名是什么意思?
antecedents:代表先购买的产品(组合),consequents代表后购买的产品(组合);
先行支持:表示先购买的产品(组合)占所有订单的支持;
后续支持:表示后面购买的产品(组合)占所有订单的支持;
support:表示同时购买两种产品(组合)占所有订单的支持;
Confidence:表示同时购买两种产品(组合)与所有订单的支持度与前期支持度的比值,即规则的置信度;
Lift:表示置信度与一致支持的比值,即提升度,验证了先购买产品(组合)再购买产品组合B的可能性的有效性;
最后我们只关注买一买一,买二再买一的情况,这是最常见的实际场景需求。因此生成两个表 df_BuyAB 和 df_BuyABC。下面是完整的代码,如果你有相同格式的数据集,可以直接运行这个算法。
import pandas as pd
import mlxtend
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, fpmax, fpgrowth,association_rules
Allorder = pd.read_excel("D:/4_MySQL/AdventureWorksDW2012/Allorder.xlsx")
group_df = Allorder.groupby(['SalesOrderNumber'])
df_productlist = pd.DataFrame({"productlist":group_df['Product'].apply(list)}).reset_index()
df_array = df_productlist["productlist"].tolist()
trans= TransactionEncoder()
trans_array = trans.fit_transform(df_array)
df_association = pd.DataFrame(trans_array, columns=trans.columns_)
frequent_itemset = apriori(df_association,min_support=0.01,use_colnames=True)
association = association_rules(frequent_itemset,metric="confidence",min_threshold=0.01)
BuyAB = association[(association['antecedents'].apply(lambda x :len(x)==1)) & (association['consequents'].apply(lambda x :len(x)==1))]
BuyABC = association[(association['antecedents'].apply(lambda x :len(x)==2)) & (association['consequents'].apply(lambda x :len(x)==1))]
文章开头的视频展示了如何使用这个Python脚本实现动态可视化,供商务人士使用,提高销售业绩。