基于Python的A-Priori算法发现购物篮关联规则

前言

一个生动的例子介绍购物篮模型——啤酒与尿布的故事
有10000个消费者购买了商品,其中购买尿布1000个,购买啤酒2000个,购买面包500个,同时购买尿布和啤酒800个,同时购买尿布和面包100个,
我们发现同时购买啤酒与尿布的消费者比较多,一个可能的猜测是年轻的爸爸们在为孩子购买尿布时顺便买了啤酒。
基于上述发现,可以给我们的商品上架或者划分消费人群等提供参考。

本篇给定超市购物记录集sales_detail.csv,提取其中的交易标识符和商品名称构成购物篮数据集。用A-Priori算法发现其中的关联规则。

原理分析及流程

频繁项集定义

如果项集 I 的支持度不小于阈值 s ,则称 I 是频繁项集。
s: 支持度阈值 (support threshold);
项集 I 的支持度(support):包含 I 的购物篮 (记录) 的数目。

一个8购物篮的例子,假设有如下8个购物篮:
(1) { Cat, and, dog, bites }
(2) { Yahoo, new, claims, a , cat, mated, with, a, dog, and, produced, viable, offspring }
(3) { Cat, killer, likely, is, a, big, dog }
(4) { Professional, free, advice, on, dog, training, puppy, training }
(5) { Cat, and, kitten, training, and, behavior }
(6) { Dog, &, Cat, provides, dog, training, in, Eugene, Oregon }
(7) { “ Dog, and, cat “, is, a, slang, term, used, by, police, officers, for, a, male-female, relationship }
(8) { Shop, for, your, show, dog, grooming, and, pet, supplies }

我们来发现其频繁项:

“cat” :6      ( 除了(4)和(8)的全部购物篮中 )
“dog” :7      ( 除了(5)之外的全部购物篮中 )
“and” :5
“a”、“traning” :3
“for”、“is” :2
其它不多于1

假定给出的支持度阈值 s 为3,频繁项集为:{dog}、{cat}、{and}、{a}、{training}
单元素的频繁项在商品销售中可应用于发现人们经常购买的商品。

双元素频繁项集合
一个双元素频繁项集合中的两个元素本身都必须是频繁的,这样该集合才有可能是频繁的。
如上述例子中,可能的双元素频繁项集合只有10个,分别是:
{dog, cat}、{dog, and}、{dog, a}、{dog, training}、{cat, and}
{cat, a}、{cat, training}、{and, a}、{and, training}、{a, training}
更多元素的频繁项集同理。

对于多元素的频繁项集在商品销售中的一个应用就是发现那些顾客经常一起购买的商品,以为我们上架提供参考。

关联规则

不同项集和项之间有许多关联规则,关联规则表示形式如下:
I→j(I为项集,j为项)I \rightarrow j ( I 为项集, j 为项 )I→j(I为项集,j为项)III为先决条件,jjj为相应的关联结果,用于表示数据内隐含的关联性。

1.支持度 Support
支持度是指在所有项集中{I,j}\left \{ I, j \right \}{I,j}出现的可能性,即项集中同时含有III和jjj的概率,该指标作为建立强关联规则的第一个门槛,衡量了所考察关联规则在"量"上的多少。
2.可信度 Confidence
I∩j的支持度/I的支持度I \cap { j }的支持度 / I 的支持度I∩j的支持度/I的支持度即所有包含项集 III 的数据记录中同时包含项 jjj 的比例。置信度表示在先决条件III发生的条件下,关联结果jjj发生的概率,这是生成强关联规则的第二个门槛,衡量了所考察的关联规则在“质”上的可靠性。
3. 提升度 Lift
表示“购买III的用户中同时购买j的比例”与“购买j的用户比例”的比值,该指标与置信度同样衡量规则的可靠性,可以看作是置信度的一种互补指标。
以上三个参数用于衡量关联规则的可采用性。

关联规则参数设置问题

在进行关联规则的发现时,我们应该注意以下问题:对支持度和置信度等参数的设置应该合理。
我们设想以下情况:支持度如果设置过低将导致过多频繁项集的发现,从而对于所得结果不具有代表性,而如果支持度设置过高,则可能频繁项集发现的商品是人们每次购物都会大概率购买的(比如塑料袋),但这并不是我们想要得到的结果,我们想要发现的是那些平时看上去没有联系的商品(如啤酒与尿布)。
对于置信度的设置也是如此,如果置信度设置过低,则关联规则将变得不太可信,而如果设置过高,我们考虑以下情况:某调和油做活动附赠酱油,置信度设置过高将会导致我们发现的结果是这类“捆绑”销售的商品,而不是那些真正有关联的商品。
其他参数也应该合理设置(可多次实验看输出结果)。

A-Priori算法

该算法运用于寻找频繁项集及频繁项集推出高支持度和可信度的关联规则。基于如下理论:
如果某个项集是频繁的,那么它的所有子集都是频繁的;而如果它的超集不再频繁,则称该项集是最大频繁项集。
当项对的数目太多而无法在内存中对所有的项对计数时,A-Priori算法可以减少必须计数的项对数目,其代价是要对数据做两遍而不是一遍扫描。

  1. A-Priori算法的第一遍扫描:采用两张表分别存储项名和该项出现次数,通过对项计数看哪些是频繁的;
  2. A-Priori算法两遍扫描之间的处理:检查所有项的计数值,对频繁项重新编号,编号范围是1到m,得到的表格称为频繁项表格。
  3. A-Priori算法的第二遍扫描:由单调性原理可知,除非一个项对中的两个项都频繁,否则这个项对也不可能是频繁的。因此,只用扫描第2步中编号的频繁项,不用担心丢失任何频繁项对。
    A-Priori算法对于更大频繁项集的发现做法如下:
    先找到频繁 1 - 项集集合 L1,然后利用 L1找到频繁 2 -项集集合 L2,接着用L2找频繁3-项集集合L3……,直到最后找不到为止。

实现流程

所给数据集的每一行的数据是订单号、商品名称及其他参数,首先我们提取所要的订单号及商品名称(去除商品规格),然后按照订单号划分商品所属的购物篮,再利用Python的第三方模块apriori库的apriori包完成频繁项集及关联规则的发现。

具体实现

读入并查看数据集的前5行数据

In [5]: f = pd.read_csv('sales_detail.csv', encoding='utf-8', sep='\t', header=None)
In [6]: f.head()
Out[6]:0  1                    2        3              4                  5   6      7      8      9      10     11
0  34121002436593  1  2012-08-01 07:45:38  5440483        2186463             苦瓜(一级)  公斤  0.262      4  1.048    3.6   0.94
1  34121002436593  2  2012-08-01 07:45:39  5440483        2186463             苦瓜(一级)  公斤  0.192      4  0.768    3.6   0.69
2  34121002436593  3  2012-08-01 07:45:45  5440466        2186359             南瓜(一级)  公斤  4.052   1.98  8.023   1.78   7.21
3  34121002436594  1  2012-08-01 07:45:26  5110324  6934665081392  蒙牛益生菌酸牛奶(原味)1.2kg   桶      1  19.59  19.59  19.59  19.59
4  34121002436595  1  2012-08-01 07:47:18  5110467  6901209206146     光明酸牛奶(红枣味)180g   盒      2    3.5      7    3.5      7

如上,我们所需要的数据是订单号和商品名,分别在第0列和第5列,且我们观察商品名,去掉其不同规格只需要对商品名做如下处理:截取部分是从左边第一个中文字符开始,到右边第一个非中文字符结束,所以我们定义去除商品规格的函数并进行测试:

In [8]: deprive_bracket_specification('L三全面包(草莓味)1.25kg')
Out[8]: '三全面包'

如上,我们定义了一个去除商品规格的函数并进行了测试,最终结果和我们想要的一致。
接下来就是提取出我们需要的第0列和第5列,并对第5列商品名去除规格。

In [17]: tip_shopname = f.loc[:,[0,5]]
In [18]: tip_shopname.columns = ['tip', 'shopname']In [19]: tip_shopname.head()
Out[19]:tip           shopname
0  34121002436593             苦瓜(一级)
1  34121002436593             苦瓜(一级)
2  34121002436593             南瓜(一级)
3  34121002436594  蒙牛益生菌酸牛奶(原味)1.2kg
4  34121002436595     光明酸牛奶(红枣味)180gIn [20]: tip_shopname.shopname = tip_shopname.shopname.apply(func=deprive_bracket_specification)In [21]: tip_shopname.head()
Out[21]:tip  shopname
0  34121002436593        苦瓜
1  34121002436593        苦瓜
2  34121002436593        南瓜
3  34121002436594  蒙牛益生菌酸牛奶
4  34121002436595     光明酸牛奶

如上,我们提取出了单号和商品名,并对商品名去除了规格。
接下来按照单号进行分篮子。

In [24]: grouping_by_grocery_list = []In [25]: for meb in  tip_shopname.groupby('tip'):...:     grouping_by_grocery_list.append(list(meb[1].shopname))In [26]: grouping_by_grocery_list[0:5]
Out[26]:
[['鲜鸡蛋', '良厨杂粮馒头'],['鲜鸡蛋', '鲜鸡蛋', '酒鬼花生', '牛后腿肉', '萝卜', '西兰花'],['牛后腿肉', '云楼精什锦'],['多力葵花籽油', '金龙鱼花生浓香调和油', '野生大白鲢', '野生大白鲢'],['野生大白鲢', '年糕', '鲜鸡蛋']]

分篮结果如上所示,同一个订单中的商品被分到了一起。
接下来我们利用Python的第三方模块apriori库的apriori包完成频繁项集及关联规则的发现。

# 导入所需要的包
from apyori import apriori# 使用apriori包进行频繁项集及关联规则的发现。
result = apriori(grouping_by_grocery_list, min_support=0.0002, min_confidence=0.7, min_lift=10, max_length=3)# 将结果迭代器转保存为列表
result_list = []
for meb in result:result_list.append(meb)

如上,我们经过多次实验,设置了较为合理的参数,并将结果保存在结果列表中,下面我们查看结果列表的一部分数据。

In [34]: # 查看发现的频繁项集...: for meb in result_list[0:10]:...:     print(meb.items)...:
frozenset({'云烟', '七匹狼'})
frozenset({'利群', '七匹狼'})
frozenset({'红双喜', '七匹狼'})
frozenset({'红塔山', '七匹狼'})
frozenset({'七匹狼', '雄狮'})
frozenset({'云烟', '万宝路'})
frozenset({'万宝路', '利群'})
frozenset({'万宝路', '南京'})
frozenset({'万宝路', '红双喜'})
frozenset({'万宝路', '红塔山'})

如上结果所示,前十个频繁项集中两个项均为香烟,这并没有太大的参考价值,因为我们习惯性是将同一类商品放在一起。
我们对所有频繁项集进行观察,发现了下面这条较为有趣的数据:

In [40]: result_list[64]
Out[40]: RelationRecord(items=frozenset({'康师傅冰红茶', '华乐二条装礼盒毛巾'}), support=2.8567383004145996e-05, ordered_statistics=[OrderedStatistic(items_base=frozenset({'华乐二条装礼盒毛巾'}), items_add=frozenset({'康师傅冰红茶'}), confidence=0.92, lift=202.3231029773286)])

如上,本来看上去毫无关联的冰红茶和毛巾,却被多次一同购买。这可以为我们的商品上架提供参考。

另外,我们还可以通过调整参数,发现其他频繁项集和关联规则。

总结

“啤酒与尿布”的故事给了我们许多启示,看似毫无联系的两件商品,被同时购买的次数却不少,通过对频繁项集及关联规则的挖掘,不仅可以寻找到事物之间平时不容易被人们发现的内在联系,跟深层次的挖掘是我们可以去分析形成此种现象背后的原因。

总而言之,它能够为我们提供许多指导。

附录

数据集:sales_detail.csv 及完整代码已放置于:Github

基于Python的A-Priori算法发现购物篮关联规则相关推荐

  1. python电影推荐算法_基于Python的电影推荐算法

    原标题:基于Python的电影推荐算法 第一步:收集和清洗数据 数据链接:https://grouplens.org/datasets/movielens/ 下载文件:ml-latest-small ...

  2. 【PLA】基于Python实现的线性代数算法库之斯密特正交化

    [PLA]基于Python实现的线性代数算法库之斯密特正交化 算法包下载链接:https://download.csdn.net/download/qq_42629529/79481514 from ...

  3. 使用Apriori关联规则算法实现购物篮分析

    Apriori算法是一种挖掘关联规则的频繁项集算法,其核心思想是通过候选集生成和情节的向下封闭检测两个阶段来挖掘频繁项集,而且算法已经被广泛的应用到商业,网络安全等各个领域. 购物篮分析是通过发视频顾 ...

  4. 基于Python技术栈的算法落地踩坑

    背景介绍 在一些业务场景,我们需要把离线训练好的模型以微服务部署线上,如果是简单的使用sklearn pipeline,可以保存为XML格式的pmml供Java调用, 在配置为4 core,8G内存的 ...

  5. python回归算法_基于Python的函数回归算法验证

    看机器学习看到了回归函数,看了一半看不下去了,看到能用方差进行函数回归,又手痒痒了,自己推公式写代码验证: 常见的最小二乘法是一阶函数回归 回归方法就是寻找方差的最小值 y = kx + b xi, ...

  6. 基于Python实现的图的同构算法

    目录 一.概要 1 二.文章结构 1 三.问题描述:图的同构 1 四.判断图同构的算法 2 基于生成全排列序列的算法 2 两种基于深度优先搜索与根据局部匹配进行剪枝的算法 3 基于 canonical ...

  7. 算法(4)购物篮分析

    所谓购物篮分析主要是挖掘出用户感兴趣的数据组合,应用于电商,大型超市.比如京东推荐,购买了此用户的产品同时购买了XX产品, 浏览了此商品的用户同时也浏览了XX商品, 对于大型超市来说道理也一样,这样就 ...

  8. 基于Python爬虫和K-means算法的校园微博热点话题发现系统

    微博由于其"短平快"的信息生产能力和快速传播能力,已经广泛流行于高校学生的日常生活中.但微博上的负面舆情信息给社会.学校和个人带来巨大的危害.由于微博的多而快特点,无法依赖人工对相 ...

  9. 基于python的简单KNN算法(K- Nearest Neighbor)的实现与改进

    最近在自学python的数据分析,还想稍微蹭一蹭深度学习,于是不可避免地接触到了最简单的机器学习算法--KNN算法.该方法的思路非常简单直观:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近) ...

  10. 基于Python实现的模拟退火算法

    模拟退火算法 摘要 该项目主要是利用局部搜索算法(LS)和模拟退火算法(SA)解决 TSP 问题.先是使用 LS 求解 TSP 问题,再尝试 SA 问题,比较两者,在效率上 SA 更占有.最后再在 L ...

最新文章

  1. 安利7款珍藏已久的windows软件,每一个都非常强大
  2. Your CPU supports instructions that this TensorFlow binary was not compiled to use: SSE4.1 SSE4.2 AV
  3. 数据流通与交易国家实验室成立 由上海牵头组建瞄准行业重大需求
  4. Android中文API(130) —— Html
  5. 【AI产品】五一出游赏花草,你一定需要这款“形色”
  6. 【H2 Database】Server模式启动
  7. Migw用CMD编译C语言,NOTEPAD++用MinGW编译C,C++语言
  8. idea提高调试超时_如何提高您的调试技能
  9. CKEditor 4.14 发布,支持复制粘贴 LibreOffice 文档
  10. Java-类型转换,String转Object和Object转String
  11. 人生最重要的三种能力,不是读书能学来的
  12. Vue.js 代码优化浅谈
  13. LINUX-VIM编辑器常用命令大全(超全)
  14. AI教程视频 - 零基础玩转illustrator科研绘图-内容介绍-目录
  15. 利用python通过两点构成的空间直线和平面计算交点
  16. 【邮件处理】邮件eml文件解析
  17. 大厂面试中HR可能会问到的问题
  18. 陈庆平获评2021年湖南省“最美科技工作者”
  19. r720服务器怎么查看硬盘性能,r720服务器如何看配置
  20. 遇到不支持的 Oracle 数据类型 USERDEFINED。

热门文章

  1. wince 百度地图懒人包_百度导航车载wince版下载
  2. MeteoInfoLab脚本示例:利用比湿、温度计算相对湿度
  3. Windows Server 2012R2 虚拟专用网络技术
  4. 单机传奇找不到登陆器服务器列表,如果传奇服务端里面没有带登陆器怎么办?...
  5. openoffic需要的jar包
  6. 神器:PDF批量替换文字
  7. 我喜欢两个男人。。。
  8. 爬虫中requests高级用法(带上cookie做数据请求)
  9. windows11连接无线网后分享热点连接不上
  10. tibco linux安装手册,TIBCO Admin 5.11.1 安装及Domain建立 (Linux)