关联分析是一种无监督学习,它的目标就是从大数据中找出那些经常一起出现的东西,不管是商品还是其他什么 item,然后靠这些结果总结出关联规则以用于后续的商业目的或者其他项目需求。

关联分析原理

那么这里介绍两种算法, Apriori算法和FP-growth算法

先讲解Apriori算法,

python 关联分析法 推算销量 关联分析python代码_频繁项集


项集(Item Set): 项集可以是单个的项,也可以是一系列项目的合集。在我们的例子中,项目就是ABCDE等商品,一个小票上的内容就可以看作一个项集,通过关联分析得到的经常一起出现的a和b可以称为一个“频繁项集”。

关联规则: 根据频繁项集挖掘出的结果,例如 {A}→{B},规则的左侧称为先导,右侧称为后继

Support(支持度): 支持度就是一个项集在数据中出现的比例。在我们的 10 条数据中,{A} 出现了 9 次,那它的支持度就是 0.9;{B} 出现了 8 次,B的支持度就是 0.8。{A,B} 的支持度是 8/10=0.8,以此类推。支持度还可以用来判定一条规则是否还需要继续进行挖掘,如果支持度已经很低,再加入新的项肯定会更低,挖掘的意义不大。
支持度(A) = A出现的次数/购物小票的数量 = 0.9
Support(A->B)=P(AUB)

Confidence(置信度): 置信度指的是在一条规则中,出现先导也出现后继的比例。我们可以用公式来看一下,置信度表示的是一条规则的可靠程度。
置信度(A→B) = 支持度(A,B) /支持度(A) = 0.8 /0.9 = 0.89
Confidence(A->B)=P(B|A)

Lift(提升度): 在置信度中,只考虑了规则中的先导与后继同时发生的情况,而对于后继单独发生的情况没有加以考虑。所以又有人提出了一个提升度,用来衡量先导和后继的独立性。比如在前面我们算出“A→B”的置信度为 0.89,这说明买了“A”的人里有 89% 会买“B”,这看起来已经很高了。但是如果在没有买“A”的购物小票中,购买“B”的概率仍然为 0.89,那其实购买“A”和购买“B”并没有什么关系。所以,提升度的计算公式如下:
提升度(A→B) = 支持度(A,B)/(支持度(A) × 支持度(B)) = 0.8/(0.8 × 0.9) = 1.1

提升度反映了关联规则中的 A 与 B 的相关性,提升度 > 1 且越高表明正相关性越高,提升度 < 1 且越低表明负相关性越高,提升度 = 1 表明没有相关性。

关联挖掘的目标已经很明确了,而关联挖掘的步骤也就只有两个:第一步是找出频繁项集,第二步是从频繁项集中提取规则。Apriori 算法的核心就是:如果某个项集是频繁项集,那么它的全部子集也都是频繁项集。

我预先画出了数据集中所有可能存在的项集关系,就如下图显示:

python 关联分析法 推算销量 关联分析python代码_python 关联分析法 推算销量_02

首先,需要设定一个最小支持度阈值,假设我们设定为 0.5,那么高于 0.5 的就认为是频繁项集。然后,我们计算出所有单个商品的支持度,如下表所示:

一阶项集支持度:

python 关联分析法 推算销量 关联分析python代码_数据_03


从这里可以看出,“E”的支持度达不到阈值,于是把它删掉。因此,所有跟“E”相关的父集也都是低频的,在后续的计算也不会涉及了.

二阶项集支持度:

python 关联分析法 推算销量 关联分析python代码_搜索_04


到了这一步,后四个项集的支持度已经达不到我们的阈值 0.5,于是也删掉

python 关联分析法 推算销量 关联分析python代码_频繁项集_05


到了这里,再根据我们的需求设定阈值来筛选最终需要留下来的规则.

算法应用

其实我个人学习这个东西, 只是为了能用在实际当中, 从网上搜了搜这个算法的实际应用场景
(1):购物篮分析
通过查看那些商品经常在一起出售,可以帮助商店了解用户的购物行为,这种从数据的海洋中抽取只是可以用于商品定价、市场促销、存货管理等环节.
(2):用户关键字搜索
通过对用户搜索关键字的关联分析,可以得到类似于搜索了苹果之后又搜索了iPhone,搜索了三星之后又搜索了HTC,这种模型可用于搜索推荐。搜索联想等场景,有利于改进搜索体验,提高客户目标转换率.
(3):招聘信息分析
例如你爬虫爬下来某些网站的某个岗位的招聘信息, 例如数据分析师, 岗位的要求有, EXCEL, SQL, Python, Spss, R, Hive等, 但是有的求职只需要其中几项, 看看哪几项一起出现的频率最高, 再加上给定的薪资范围, 根据薪资范围, 可以对比自己看看, 哪方面可以提高.
(4): 广告恶意流量
广告主一般会有很多渠道投放广告, 但有些渠道会用机器, 或者脚本刷广告流量, 可以基于点击广告的用户ID, IP地址, 设备型号, 设备MAC地址, 跳转链接等检查恶意刷广告流量的渠道. 让广告主知道哪些渠道存在恶意流量, 从而优化渠道.

应用案例

电商购物的方式和实体超市购物的方式不太一样, 超市购物的时候会一次性结完账, 一个账单有多个商品罗列出来; 但例如京东, 淘宝购物, 虽然也有购物车, 相信很多人看中了直接购买, 但有的人会先把想买的都先加入购物车, 再直接清空购物车. 那么网购怎么算一单呢, 可以根据用户ID, 下单时间判定是否算一起购买, 比如一个用户在上午10点购买了篮球鞋, 用逛了逛运动服, 逛了俩小时, 在中午12点购买了运动服, 在下午的2点又买了篮球和打气筒. 可以以用户ID和付费时间段, 来算一单.
说这么多总结一下, 在写模型算法的时候, 要了解业务和数据, 不然可能结果会不一致, 作为新手的我确实有亲身体会, 实体店购物或者电商买东西的时候, 后端数据表可能都不一样, SQL语句也不一样, 所以根据场景自己调整.

这里以杂货店的购买数据为例,

读取购买数据, 这个购买货物的业务相比就不用多说了, member_number看做用户ID, Date看做日期, itemDescription看做购买商品的内容

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
data = pd.read_csv('Groceries_dataset.csv')
data.head()

python 关联分析法 推算销量 关联分析python代码_搜索_06


接下来数据的理解

按照用户ID和日期排名

#将日期格式化一下, 改成年-月-日的形式 
data['Date'] =pd.to_datetime(data.Date)
data.sort_values(by=["Member_number","Date"],ascending=[True,True]).head(10)

python 关联分析法 推算销量 关联分析python代码_频繁项集_07


实际上, 同一个人一天内杂货店购买的东西为一单, 如果将同一个人多天的商品算为一单, 是不是在关联性上就有很大的问题了.

同一个人同一天为一单, 但是在整合之前呢, 要去除重复项, 例如: 某人 在某天 买了三次酸奶, 咱们是要看不同的商品类型之间的关联性, 如果不去重会得到 用户ID- 日期- (酸奶, 酸奶, 酸奶) 这样的数据, 所以要先去重

#去重
data= data.drop_duplicates(keep="first")
#按照用户ID和日期分组, 对itemDescription进行整合.
new_data = data.groupby(['Member_number','Date'])['itemDescription'].apply(','.join).reset_index()
new_data.head(10)

python 关联分析法 推算销量 关联分析python代码_python 关联分析法 推算销量_08


好现在整合完了, 得到了我们想要的数据, 进行apriori算法进行关联分析.

先安装efficient-apriori包

from efficient_apriori import apriori
#因为这个算法包支持的是列表里面套元组, 所以需要将itemDescription这一列转化成元组
new_data = new_data['itemDescription'].apply(lambda x: tuple(x.split(",")))
new_data

python 关联分析法 推算销量 关联分析python代码_python 关联分析法 推算销量_09


在将其转化成列表, 然后设定支持度,和置信度

order_list = list(new_data)
itemsets, rules = apriori(order_list, min_support = 0.01, min_confidence= 0.1)
print(itemsets)  #这里是各个项集及其出现的次数

python 关联分析法 推算销量 关联分析python代码_搜索_10

其实咋一看, 牛奶和酸奶的数量确实比较多,

python 关联分析法 推算销量 关联分析python代码_python 关联分析法 推算销量_11


这里可以看到二级项集以及相应的数量,

print(rules)  #这个是满足支持度和置信度筛选出来的结果

python 关联分析法 推算销量 关联分析python代码_数据_12


最终满足结果是上述, 那么可以根据上面的条件对商店进行活动或者策略改进, 提高销售量, 例如库存调整, 货架摆放调整.但是前面为何把 支持度和置信度设置的这么低, 是由于数据量的问题,

python 关联分析法 推算销量 关联分析python代码_频繁项集_13


一共14963单, 货品售卖种类167个.

其实可视化部分应该放在数据处理部分, 本文只不过主要讲解apriori算法的过程, 可视化的就先简单的画几张.

x = list(data['itemDescription'].value_counts()[:10].index)
y = list(data['itemDescription'].value_counts()[:10].values)
ax=sns.barplot(x=y,y=x, palette=sns.color_palette("spring_r"))
plt.title('Best Sellers')

销量排行前十

python 关联分析法 推算销量 关联分析python代码_频繁项集_14


销售最多的是whole milk 约2500单, 总单数15000左右(偷懒估算下), 支持度(whole milk) = 2500/15000 = 0.1666, 其实二级项集可能就不会这么多了, 所以在调参的时候也尝试过, 稍微将其中一个参数调大点, 最后的结果可能一条没有, 根据实际情况来吧, 这里只是为了展示用例, 但实际生活当中, 很可能某家店铺的所有商品都没有关联, 例如: 某运动鞋商场, 很可能出现所有顾客只买一双鞋, 很少有买完李宁买乔丹, 买阿迪达斯买耐克, 很可能数据算出没有关联, 所以不一定所有的购物都有关联性.

话题再说回来, 其实也可以按分成年份和季度来画图, 看看每个季度是不是对商品销售量有影响, 不同的季度有不同商品需求, 关联有可能会改变, 所以还可以继续分析与挖掘, 此处就不在过多写代码了.