前言
上回提到,Power BI借助Python做关联分析,可以轻松地找出物品中的频繁项集,且该频繁项集内的物品数量不限于2个。实现方式既可以通过Power BI里添加Python可视化控件直接生成Python式图表,也可在PQ里借助Python处理数据。前者最大的好处体现在与切片器联动中,是即时计算新的频繁项集。不足在于Python图表的风格与Power BI不一致,而且由于直接输出Python图(没有输出数据源),不便于开展其他分析。后者,正好解决了这些不足。
方法
首先点击【转换数据】进入Power Query(PQ)界面。
接下来,我们复制一份源数据。因为在PQ里用Python进行数据清洗,实际上会修改覆盖掉原来的这份数据记录,所以复制一份以便备份。
再接下来,是用Python清洗数据的关键。网上同类话题的文献都讲的比较简单,这里把每一步截图给大家看看。
如图所示依次点开Python编辑器。编辑器中输入输出都是Python的DataFrame数据结构。打开后,系统默认将数据源转成DataFrame的dataset。也即在此编辑器中,已经有了数据dataset。
将上篇推文那段Apriori算法的代码复制到此编辑器。区别是,之前需要输入图表,而这次无需,因此可以把最后几行代码删掉。输入的代码如下:
代码语言:javascript复制from mlxtend.frequent_patterns import apriori
from mlxtend.preprocessing import TransactionEncoder
import pandas as pd
import matplotlib.pyplot as plt
data=dataset
data.Item=data.Item.str.lower()
data=data.drop(data[data["Item"]=='none'].index) #删除无物品的记录
# 将数据集进行格式转换
orders_series = data.set_index("Transaction")["Item"]
transactions = []
temp_index = 0
for i, v in orders_series.items():
if i != temp_index:
temp_set = set()
temp_index = i
temp_set.add(v)
transactions.append(temp_set)
else:
temp_set.add(v)
# 数据转码
te = TransactionEncoder()
te_ary = te.fit(transactions).transform(transactions)
df = pd.DataFrame(te_ary, columns=te.columns_)
# 求频繁项集
frequent_items=apriori(df,min_support=0.02,use_colnames=True) # 支持度阈值为0.02
frequent_items["itemsets"]=frequent_items["itemsets"].apply(lambda x:[x for x in x]) # 频繁项集frozenset转list
frequent_items["itemsets"]=frequent_items["itemsets"].apply(lambda x:','.join(x)) # 频繁项集list转str
frequent_items=frequent_items.sort_values(["support"],ascending=False) # 按支持度降序排序
点击【确定】完成后,将提示数据隐私安全性,选择【公共】。
最后是将算法运行结果转化为Power BI 的表,这也是相关文献演示得最少的地方。步骤3后会得到如下的表。前几行为数据表原有的字段,最后一行为Python处理后得到的结果(Python代码中最后得到的dataframe)。
单击最后一行的Table,将得到Python处理的结果。
结果里有2个字段(列),support——支持度,即频繁项集的出现概率;itemsets——频繁项集。这个集合里,可能是1个、2个、3个甚至更多个物品组合,具体视数据源的特征以及支持度的阈值而定。在itemsets中,不同物品的名称使用逗号分开的。如需进一步分析,我们可以按逗号拆分列,再添加索引列,如下图所示。
最后点击关闭并应用,数据处理完成。
总结与延展
在PQ中使用Python对原有数据处理,可以生成Power BI原生的数据集。相比上一篇中使用Python可视化控件直接输出Python图表,增加了更多的灵活性和可延展性。如下图所示,使用矩阵可以做出频繁项集的列表。(注:本数据集数据量太少,因此频繁项集里只有1-2个物品。)
细心的读者可能会发现,这种做法也有不足——由于此方法是从数据源入手的,因此无法通过切片器改变数据源的计算范围。比如当数据源计算的是整个时间段(如全年)的频繁项集,则无法通过切片器即时地改变数据源生成部分时间段(如某月)的频繁项集。有没有解决办法呢?【参数化查询】是目前Power BI应对的一个权宜之计。详情参见本文——Power BI的时间序列预测,除了移动平均还能怎么做?