Apriori 关联分析算法原理分析与代码实现

回到顶部

前言

       想必大家都听过数据挖掘领域那个经典的故事 - "啤酒与尿布" 的故事。

       那么,具体是怎么从海量销售信息中挖掘出啤酒和尿布之间的关系呢?

       这就是关联分析所要完成的任务了。

       本文将讲解关联分析领域中最为经典的Apriori算法,并给出具体的代码实现。

回到顶部

关联分析领域的一些概念

       1. 频繁项集: 数据集中经常出现在一起的物品的集合。例如 "啤酒和尿布"

       2. 关联规则: 指两个物品集之间可能存在很强的关系。例如 "{啤酒} -> {尿布}" 就是一条关联规则。

       3. 支持度: 数据集中,出现了某个物品集的数据项占总数据项的比重(某些地方也解释为次数)。

       4. 可信度: 这个概念是针对某条关联规则而定的。它是指两个物品集的支持度和其中某个物品集的支持度之比,如 "支持度{啤酒,尿布} / 支持度{尿布}"。

       因此,用这些属于来解释啤酒与尿布的故事,那就是:{啤酒,尿布}是一个频繁项集;"{啤酒} -> {尿布}" 就是一条关联规则;顾客买尿布的同时买啤酒的可能性为 "支持度{啤酒,尿布} / 支持度{尿布}"。

       那么对海量的数据,假如要得到支持度大于0.8的所有频繁项集,该怎么做?

       如果用蛮力法一个个统计,是根本不现实的,那样计算量实在太大。

       本文将要介绍的Apriori关联分析算法意义就在于能够大幅度减少这种情况的计算量,并从频繁项集中高效检索出关联规则,从而大大减少关联规则学习所需要消耗的计算量。

回到顶部

Apriori算法基本原理

  如果{0,1}是频繁项集,那么{0}和{1}也都是频繁项集。

  这显然是正确的命题。

  其逆否命题 - ”如果{0}和{1}不都是频繁项集,那么{0,1}不是频繁项集" 自然也是正确的。-> 这就是 Apriori 算法的核心思想之一。

  这样,一旦发现某个集合不是频繁项集,那么它的所有超集也都不是频繁项集,就不用浪费功夫去对它们进行检索了。

  检索出频繁项集之后,接下来检索出所有合乎要求的关联规则。

  如果某条规则不满足最小可信度要求,那么该规则的所有子集也不会满足。 -> 这是 Apriori 算法的核心思想的另一部分。

  PS:这里务必思考清楚规则是怎么划分的,什么叫某个规则的子集。

  这样,和上一步同理,也能高效的从频繁项集中检索出关联规则了。

  具体实现将分为频繁集检索和关联规则学习两个部分进行讲解。

回到顶部

频繁项集检索实现思路与实现代码

  一种经典的实现方法是 "分级法":

  算法框架是在两个大的步骤 - 筛选/过滤之间不断迭代,直到所有情况分析完毕。

  每次筛选的结果都要指定元素个数的情况,因此所谓分级,也就是依次讨论指定元素个数情况的项集。

  在筛选之后,就是过滤。

  过滤有两层意义,一个是项集必须在数据集中存在。这是第一层过滤;还有一层过滤,是指支持度过滤。只有满足支持度要求的项集才能保存下来。

  过滤之后,基于过滤集再进行筛选,每次筛选的元素个数都比上一次筛选的元素个数多一个。

  然后继续过滤。如此反复,直到最后一次筛选过滤完成。

  伪代码实现:

1 当集合中项的个数大于0时:
2     构建一个 k 个项组成的候选项集的列表
3     检查数据以确认每个项集都是频繁的
4     保留频繁项集并构建 k+1 项组成的候选项集列表

       其中检查每个项集是否频繁部分的伪代码:

1 对数据集中的每条交易记录:
2     对每个候选集元素:
3         检查是否为数据集元素,是才保留。
4 对每个数据集
5     如果支持度达到要求才保留
6 返回过滤后的频繁项集 - 也即过滤集

       Python实现及测试代码:

复制代码
  1 def loadDataSet():2     '返回测试数据'3     4     return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]5 6 #===================================7 # 输入:8 #        dataSet: 数据集9 # 输出:10 #        map(frozenset, C1): 候选集11 #===================================12 def createC1(dataSet):13     '创建候选集'14     15     C1 = []16     for transaction in dataSet:17         for item in transaction:18             if not [item] in C1:19                 C1.append([item])20                 21     C1.sort()22     23     # 返回的集合元素都是frozenset类型 -> 因为以后要用来做键。24     return map(frozenset, C1)25 26 #=============================================27 # 输入:28 #        D: 数据集 (set格式)29 #        Ck: 候选集30 #        minSupport: 最小支持度31 # 输出:32 #        retList: 过滤集33 #        supportData: 支持集(挖掘关联规则时使用)34 #=============================================35 def scanD(D, Ck, minSupport):36     '由候选集得到过滤集'37     38     # 统计候选元素出现的次数39     ssCnt = {}40     for tid in D:41         for can in Ck:42             if can.issubset(tid):43                 if not ssCnt.has_key(can): ssCnt[can]=144                 else: ssCnt[can] += 145                 46     # 构建过滤集和支持集47     numItems = float(len(D))48     retList = []49     supportData = {}50     for key in ssCnt:51         support = ssCnt[key]/numItems52         if support >= minSupport:53             retList.insert(0,key)54         supportData[key] = support55         56     return retList, supportData57 58 #===================================59 # 输入:60 #        Lk: 过滤集61 #        k: 当前项集元素个数62 # 输出:63 #        retList: 候选集64 #===================================65 def aprioriGen(Lk, k):66     '由过滤集得到候选集'67     68     # 重组过滤集,得到新的候选集。69     retList = []70     lenLk = len(Lk)71     for i in range(lenLk):72         for j in range(i+1, lenLk): 73             # 留意下重组技巧74             L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]75             L1.sort(); 76             L2.sort()77             if L1==L2:78                 retList.append(Lk[i] | Lk[j])79                 80     return retList81 82 #=============================================83 # 输入:84 #        dataSet: 数据集85 #        minSupport: 最小支持度86 # 输出:87 #        L: 频繁集88 #        supportData: 支持集(挖掘关联规则时使用)89 #=============================================90 def apriori(dataSet, minSupport = 0.5):91     '求频繁项集及其对应支持度'92     93     C1 = createC1(dataSet)94     D = map(set, dataSet)95     L1, supportData = scanD(D, C1, minSupport)96     L = [L1]97     k = 298     while (len(L[k-2]) > 0):99         Ck = aprioriGen(L[k-2], k)
100         Lk, supK = scanD(D, Ck, minSupport)
101         supportData.update(supK)
102         L.append(Lk)
103         k += 1
104         
105     return L, supportData
106     
107 def main():
108     'Apriori频繁集检索'
109     
110     L, s = apriori (loadDataSet())
111     
112     print L
113     print s
复制代码

       测试结果:

       

回到顶部

关联规则学习实现思路与实现代码

       上一部分的工作是从数据集中检索出频繁集;而这一部分是根据频繁集学习关联规则。

       上一部分的工作是通过筛选集中的元素个数进行分级;而这一部分是针对规则右部的元素个数进行分级。

       另外还要注意,只用检索单个频繁集之内的关联规则就可以了。

       实现代码:

复制代码
 1 #===================================2 # 输入:3 #        L: 频繁集4 #        supportData: 支持集5 #        minConf: 最小可信度6 # 输出:7 #        bigRuleList: 规则集8 #===================================9 def generateRules(L, supportData, minConf=0.7):
10     '从某个频繁集中学习关联规则'
11     
12     bigRuleList = []
13     for i in range(1, len(L)):
14         for freqSet in L[i]:
15             H1 = [frozenset([item]) for item in freqSet]
16             if (i > 1):
17                 rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
18             else:
19                 calcConf(freqSet, H1, supportData, bigRuleList, minConf)
20     return bigRuleList         
21 
22 #===================================
23 # 输入:
24 #        L: 频繁集
25 #        supportData: 支持集
26 #        minConf: 最小可信度
27 # 输出:
28 #        bigRuleList: 规则集
29 #===================================
30 def calcConf(freqSet, H, supportData, brl, minConf=0.7):
31     '可信度过滤'
32     
33     prunedH = []
34     for conseq in H:
35         conf = supportData[freqSet]/supportData[freqSet-conseq]
36         if conf >= minConf: 
37             brl.append((freqSet-conseq, conseq, conf))
38             prunedH.append(conseq)
39             
40     return prunedH
41 
42 def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
43     '从某个频繁项集中学习关联规则'
44     
45     # 本次学习的规则右部中的元素个数
46     m = len(H[0])
47     if (len(freqSet) > (m + 1)):
48         # 重组规则右部
49         Hmp1 = aprioriGen(H, m+1)
50         # 规则学习
51         Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
52         if (len(Hmp1) > 1):
53             # 递归学习函数
54             rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)
55               
56 def main():
57     '关联规则学习'
58     
59     L, s = apriori (loadDataSet())
60     
61     rules = generateRules(L, s)
62     print rules
复制代码

       测试结果:

  

       测试数据为: [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]。

       结果的意思也就是说:1->3,5->2,2->5 的概率为 1。

       显然这是和预计相吻合的。

回到顶部

小结

       1. Apriori关联算法在网络购物网站中用的非常多,可以基于此算法搭建商品推荐系统。

       2. 但Apriori算法也有一个缺点,那就是频繁集的检索速度还是不够快,因为每级都要重新检索一遍候选集(虽然候选集越来越小)。

       3. 针对 2 中的问题,下篇文章将介绍一个更为强大的发现频繁集的算法 - FP-growth。(PS:但它不能用来发现关联规则)

转载于:https://www.cnblogs.com/fujian-code/p/7637728.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/369049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring JpaRepository示例(内存中)

这篇文章描述了一个使用内存中HSQL数据库的简单Spring JpaRepository示例。 该代码示例可从GitHub的Spring-JpaRepository目录中获得。 它基于带有注释的Spring-MVC-示例和此处提供的信息 。 JPA资料库 我们为该示例实现一个虚拟bean: Entity AutoProperty public…

java url接口_javaweb 后台使用url接口

String GET_URL"https://wx.hguard.cn:8075/queryProfiledataAction.action?phone"phone"&beginnum"beginnum"&pagesize"pagesize"&sign"newsignString;try {URL url new URL(GET_URL); // 把字符串转换为URL请求地址…

数据分析 - 残酷的世界

数据分析 - 残酷的世界 可视化作品链接地址:http://reinhardhsu.com/game.html 概要 最近读了比尔盖茨的夏日书单中的荐书《乡下人的悲歌》, 书中描述了贫穷、毒品和一系列陋习,像遗传病一样,困扰着一代又一代的美国底层人民…

burpsuite破解版

来源:http://www.vuln.cn/8847 转载于:https://www.cnblogs.com/shengulong/p/8819072.html

Eclipse Juno上带有GlassFish的JavaEE 7

Java EE 7很热。 前四个JSR最近通过了最终批准选票,与此同时GlassFish 4达到了升级版83。 如果您关注我的博客,那么您将了解NetBeans的大部分工作。 但是我确实认识到,那里还有其他IDE用户,他们也有权试用最新和最出色的企业Java。…

photoshop 切片工具进行切图

1、使用切片工具切图 2、存储为web所用格式 3、选择图片格式 4、只保存切片(选择所有用户切片) 5、查看:

HubSwitch工作原理,冲突域,以太网帧结构笔记(2017年10月9日 11:15:46)

一、冲突域 网络中发送的主要是应用程序产生的数据。 数据流需要网络设备进行数据转发,任何应用程序在发送数据流之前都要进行数据封装。 比如:SMAC DMAC | SIP DIP | 报头(Source Port、Destination Port)| QQ的数据载荷&#xf…

在IDEA中实战Git

工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下: 假设小组中有两个人,组长小张,组员小袁 场景一:小张创建项目并提交到远程Git仓库 场景二:小袁从远程Git仓库上获取项目源码 场景三&#xff1…

java抽象类异常_求教JAVA里面的错误继承抽象类我都已经看傻了。

求教JAVA里面的错误我都已经看傻了。我思路是想创建个新对象(经理)并打印他的所有属性,外加上work一个干活的属性。自己看了半天改了半天都不行跪求高手给我改改并讲讲。abstractcl...求教JAVA里面的错误我都已经看傻了。我思路是想创建个新对象(经理)并打印他的所有…

从迁移到Java 7的小技巧

经过几年的努力,我们终于开始在软件级别方面将我们的应用程序从黑暗时代中拉出来,其中一个步骤是将我们的Java版本升级到Java7。在大多数情况下,这相当轻松,但是有一些惊喜: 当我们切换到Java 7时,已经运行…

css 宽高自适应的div 元素 如何居中 垂直居中

在我们 编写css 样式的时候经常会遇见一个问题 那就是一个 宽高未知的元素 要让他 垂直居中如何实现这个呢 下面是我常用的两种方法 上代码 下面的是 结构代码 <div class"wrap">//此处为父组件 我们会设置父级的宽高并让其居中 <div class"center&q…

iOS 图文并茂的带你了解深拷贝与浅拷贝

一、概念与总结 1、浅拷贝 浅拷贝就是对内存地址的复制&#xff0c;让目标对象指针和源对象指向同一片内存空间&#xff0c;当内存销毁的时候&#xff0c;指向这片内存的几个指针需要重新定义才可以使用&#xff0c;要不然会成为野指针。 浅拷贝就是拷贝指向原来对象的指针&…

使用Byteman和JUnit进行故障注入

我们的应用程序独立存在的时间已经很久了。 如今&#xff0c;应用程序是一种非常复杂的野兽&#xff0c;它们使用无数的API和协议相互通信&#xff0c;将数据存储在传统或NoSQL数据库中&#xff0c;通过网络发送消息和事件……例如&#xff0c;如果考虑到数据库&#xff0c;您会…

Ambari Views的自定义

下载ambari源码&#xff0c; ambari-views/examples/ 下面有很多例子&#xff0c;直接编译是不会成功的&#xff0c; 因为每一个例子项目都需要一个依赖 <dependency><groupId>org.apache.ambari</groupId><artifactId>ambari-views</artifactId>…

angular使用sass的scss语法

一、现象 为了简写样式 二、解决 1、安装sass ,利用npm 安装(npm工具如果没有&#xff0c;请先自行安装好) &#xff08;1&#xff09;、npm install node-sass --save-dev &#xff08;2&#xff09;、npm install sass-loader --save-dev 2、修改.angular-cli.json文件 …

linux 查看java cpu_Linux查看CPU和内存使用情况

在系统维护的过程中&#xff0c;随时可能有需要查看 CPU 使用率&#xff0c;并根据相应信息分析系统状况的需要。在 CentOS 中&#xff0c;可以通过 top 命令来查看 CPU 使用状况。运行 top 命令后&#xff0c;CPU 使用状态会以全屏的方式显示&#xff0c;并且会处在对话的模式…

TCP浅谈为什么3次握手

《计算机网络》中的例子是这样的&#xff0c;“已失效的连接请求报文段”的产生在这样一种情况&#xff1a;客户发出的第一个连接请求报文段并没有丢失&#xff0c;而是在某个网络结点长时间的滞留了&#xff0c;以致延误到连接释放以后的某个时间才到达服务。 本来这是一个早已…

Arrays.sort与Arrays.parallelSort

我们都使用Arrays.sort对对象和原始数组进行排序。 该API在下面使用合并排序或Tim排序对内容进行排序&#xff0c;如下所示&#xff1a; public static void sort(Object[] a) {if (LegacyMergeSort.userRequested)legacyMergeSort(a);elseComparableTimSort.sort(a); }即使合…

了解ASP.NET MVC的基本架构

MVC&#xff0c;Model – View – Controller 的简写 Model 封装业务逻辑相关的数据及对数据的处理方法 View 向用户提供交互界面 Controller 负责控制Model和View 首先建立一个模板 在这里发现了一个问题&#xff08;好像vs12没有模板&#xff0c;建不出来&#xff09; 其…

Google Chrome 浏览器JS无法更新解决办法

JS无法更新原因&#xff1a; 浏览器为了加载快&#xff0c;默认是按照自定规则更新缓存&#xff0c;非实时更新。 我们在开发的时候&#xff0c;JS变动很快&#xff0c;需要即时让浏览器加载最新文件&#xff0c;也就是禁用浏览器缓存 &#xff08;1&#xff09;使用F12进入…