数据挖掘——关联规则(Association Rule)Apriori算法和python代码实现

news2025/1/6 21:45:42

关联规则(Association Rule)

    • 什么是关联规则
    • 一些基本概念
    • 任务是什么
    • Apriori 算法
        • 核心思想
        • 步骤与流程图
        • 如何找到候选集
    • python代码实现

什么是关联规则

关联规则(Association Rules)是反映一个事物与其他事物之间的相互依存性和关联性,是数据挖掘的一个重要技术,用于从大量数据中挖掘出有价值的数据项之间的相关关系。

用一些例子来说明一下:
当我们在超市进行购物时,超市中有琳琅满目的商品,在每一次购物结束之后,我们会拥有一个购物车然后去结账,然后产生购物小票,购物小票中记录了我们购买的每件商品的信息,如此日积月累,所有的这些记录就会产生海量的用户购买行为。从这些购买行为中,我们特别希望能够发掘出类似买了面包的人就会去购买牛奶这样的规则。
这种规则,在数据挖掘中有很多,比如著名的啤酒和尿布的例子:在美国,一些年轻的父亲下班后经常要到超市去买婴儿尿布,而他们中有30%~40%的人同时也为自己买一些啤酒。产生这一现象的原因是:美国的太太们常叮嘱她们的丈夫下班后为小孩买尿布,而丈夫们在买尿布后又随手带回了他们喜欢的啤酒。
在这里插入图片描述
买了一样商品就会去买另外一件商品,这就是一种关联规则。

一些基本概念

Items(项)
实际上就是一些商品,面包,牛奶,巧克力,啤酒,尿布… 每一个都是一个 i t e m item item

Transaction(交易)
一条交易记录(购物小票),是所有商品的非空子集。可以买一件商品,两件商品… 但是集合不能是空集。

Itemset(项集)
同时购买的一组东西。 i t e m s e t itemset itemset有大有小,购买的东西有可能有1个,2个, k k k个,如果有 k k k个,那么 itemset 就被称作 k − i t e m s e t k-itemset kitemset

Dataset(数据库)
包含一系列的 t r a n s a c t i o n transaction transaction

下面给出一个例子:
在这里插入图片描述
Bread是一个 i t e m item item,Butter也是一个 i t e m item item,而第1、2、4交易记录中,同时购买的Bread和Butter,就组成一个 2 − i t e m s e t 2-itemset 2itemset

Support(支持度)
可以理解成是一种频率,就是在一些 t r a n s a c t i o n transaction transaction 当中某一个 i t e m ( 或 者 i t e m s e t ) item( 或者 itemset) itemitemset出现的频率。
在这里插入图片描述

例如上表中的 Bread$ 的support就是6/8,Bread与Butter的 s u p p o r t support support是3/8,Bread、Butter和Chips的 s u p p o r t support support是0

关联规则 x − > y x -> y x>y的支持度就是一些交易中同时包含 x x x y y y的频率。
在这里插入图片描述
Confidence(置信度)
关联规则 x − > y x -> y x>y的置信度就是一些交易中 同时包含 x x x y y y的数量与 x x x的数量的比。
在这里插入图片描述
也可以被写作下面的公式:
在这里插入图片描述
置信度也可以被理解为是一种条件概率 P ( X ∣ Y ) P(X | Y) PXY,比如当我购买牛奶这个事件发生的时候,又购买面包这个事件发生的概率是多少。

引用上表的例子,如
Bread − > -> > Milk 的 s u p p o r t support support = 2/8 , c o n f i d e n c e confidence confidence = 1/3
Milk − > -> > Bread 的 s u p p o r t support support = 2/8 , c o n f i d e n c e confidence confidence = 2/3

我们需要的规则,它必须是一种强规则,而且要频繁。 s u p p o r t support support度量了一条规则的频繁程度, c o n f i d e n c e confidence confidence度量了一条规则的强度。我们定义两个阈值来量化这条规则的频繁程度和强度:
m i n i m u m minimum minimum s u p p o r t support supportσ
m i n i m u m minimum minimum c o n f i d e n c e confidence confidenceΦ

Frequent itemset(频繁集)
一个itemset,它的 s u p p o r t > σ support > σ support>σ

Strong rule(强规则)
一个规则 x − > y x->y x>y,它既要是频繁的 ( s u p p o r t > σ support > σ support>σ),而且要 c o n f i d e n c e > Φ confidence > Φ confidence>Φ

任务是什么

当已知 I t e m s , d a t a s e t , σ , Φ Items,dataset,σ,Φ ItemsdatasetσΦ,我们要做的就是从 d a t a s e t dataset dataset中挖掘出类似于 x − > y x->y x>y的所有的 Strong rule。
要找出所有的强规则,方法就是:

  1. 找出所有的 f r e q u e n t frequent frequent i t e m s e t s itemsets itemsets
  2. 运用 f r e q u e n t frequent frequent i t e m s e t s itemsets itemsets ,对于每一个 f r e q u e n t frequent frequent i t e m item item,生成它的所有的非空子集,然后利用这些非空子集找出所有可能的关联规则,然后对这些规则进行校验 s u p p o r t support support c o n f i d e n c e confidence confidence

例如:根据集合 a , b , c {a,b,c} a,b,c,找出其所有可能的关联规则。
在这里插入图片描述
根据上面的2个步骤可以找出强规则。但是假如我们共有 d d d种商品,那么所有可能的 i t e m s e t s itemsets itemsets的个数就是 2 d − 1 2^d-1 2d1,这是一个指数级的数字,想象一下,商品的数量如果有成百上千种,那么 i t e m s e t itemset itemset的数量是不可估计的。所以问题的关键就是,如何高效率的找出所有的 f r e q u e n t frequent frequent i t e m s e t s itemsets itemsets,下面介绍的就是解决这个核心问题的一个算法: Apriori 算法

Apriori 算法

核心思想

首先介绍两个核心思想:

  1. 一个频繁集的子集一定是频繁集,
    {Milk, Bread, Coke} is frequent -> {Milk, Coke} is frequent
  2. 一个 i t e m s e t itemset itemset不是频繁集,那么它的所有的超级一定不是频繁集,
    {Battery} is infrequent -> {Milk, Battery} is infrequent
    例如下图,我们知道B不是一个频繁集,那么所有标记为绿色的 i t e m s e t itemset itemset都不是频繁集。

在这里插入图片描述

步骤与流程图

下面介绍Apriori的核心思路
(1) 先生成某一个特定大小的 i t e m s e t s itemsets itemsets,一般从1开始,如{牛奶},{面包},{巧克力}
(2) 扫描数据库,观察这些 i t e m s e t s itemsets itemsets 哪些是频繁的,即频繁集,不频繁的 i t e m s e t itemset itemset直接舍弃
(3) 运用这些频繁集,组合成数量加1个大小的 i t e m s e t s itemsets itemsets(被称为 c a n d i d a t e candidate candidate i t e m s e t s itemsets itemsets 候选集),例如{牛奶,面包},{面包,巧克力},{牛奶,巧克力}。然后重复上面的第(2)步扫描数据库,舍弃不频繁的 i t e m s e t s itemsets itemsets,之后重复(2),(3)步。 i t e m s e t s itemsets itemsets的大小逐一增加。
(4) 综上,核心思想就是尽量避免去生成不频繁的 c a n d i d a t e candidate candidate i t e m s e t s itemsets itemsets

算法流程图:
定义:
C k C_k Ck:大小为 k k k c a n d i d a t e candidate candidate i t e m s e t s itemsets itemsets
L k L_k Lk:大小为 k k k f r e q u e n t frequent frequent i t e m s e t itemset itemset

在这里插入图片描述
首先找出所有的 f r e q u e n t frequent frequent i t e m s items items,长度是一。里面的小循环是扫描数据库中的每一条记录,根据已知的 c a n d i d a t e candidate candidate i t e m s e t itemset itemset,我们在每一条记录中查看一下是否存在这样一个 c a n d i d a t e candidate candidate i t e m s e t itemset itemset,如果存在,那么就 c o u n t + + count++ count++ 计数,也就是说在所有的记录中,有多少条记录包括这样一个特定的 i t e m s e t itemset itemset。里面的循环走完之后,我们就开始过滤操作,比较一下 s u p p o r t support support,如果> 我们之前设置的阈值 σ σ σ,那么就把这个 i t e m s e t itemset itemset留下,否则抛弃。然后外面的大循环,是把这些频繁集进行组合,组合成更大的 c a n d i d a t e candidate candidate i t e m s e t s itemsets itemsets,生成可能频繁的候选集,步数是1。

上面的算法中,最为关键的一步就是如何从 L k L_k Lk生成 C k + 1 C_{k+1} Ck+1
L k L_k Lk是一个集合,集合里面所有的 i t e m s e t itemset itemset 中的 i t e m item item 个数都是一样的,都是 k k k个,而且这些 i t e m s e t itemset itemset都是频繁的
C k + 1 C_{k+1} Ck+1也是一个集合,其中的 i t e m s e t itemset itemset 中的 i t e m item item 个数都是比 L k L_k Lk中的多一个
如何从 L k L_k Lk生成 C k + 1 C_{k+1} Ck+1,要做到必须把所有的频繁集都找到,同时又不能生成太多的冗余的

用下面这个例子进行讲述:
已知 L 1 L_1 L1:{1,2,3,4,5}, L 2 L_2 L2:{ {1,2},{2,3} },即1,2,3,4,5都是频繁的,{1,2},{2,3}也是频繁的。如何利用 L 1 L_1 L1 L 2 L_2 L2生成 C 3 C_3 C3

如何找到候选集

方法一
把一个频繁的加入到两个频繁的,就生成了所有3个的可能频繁的 i t e m s e t itemset itemset
在这里插入图片描述
所以用这个方法得到的 C 3 C_3 C3就是{ {1,2,3},{1,2,4},{1,2,5},{2,3,4},{2,3,5} }
这个方法得到的 C 3 C_3 C3不能说是错误的,但是效率太低。例如我们看到 C 3 C_3 C3中的 {1,2,5},其中它的子集 {1,5}是不在 L 2 L_2 L2当中的,说明{1,5}是不频繁的,而 {1,2,5} 是它的超集,则说明 {1,2,5} 也是不频繁的。因此我们可以清楚的看到方法一生成的 C 3 C_3 C3会有大量的冗余。

方法二
L 2 L_2 L2 中找两个 i t e m s e t itemset itemset x x x y y y,这两个 i t e m s e t itemset itemset要满足一个条件,他们中的 i t e m item item只有一个是不同的。然后把 x x x y y y拼起来。
在这里插入图片描述
用方法二,我们发现我们 L 2 L_2 L2中的两个 i t e m s e t itemset itemset,它们的2是相同的,1和3是不同的,就可以得到 C 3 C_3 C3就是{ {1,2,3} }。方法二的效率要比方法一的效率高很多。但是我们仔细观察会发现,这个{1,2,3}也是不频繁的,因为它的子集{1,3}不在 L 2 L_2 L2当中,所以{1,3}也是不频繁的。

方法三
首先对所有的 i t e m item item 做一个排序,然后从 L 2 L_2 L2 中找两个 i t e m s e t itemset itemset x x x y y y,这两个 i t e m s e t itemset itemset要满足一个条件, x x x y y y的前 k − 1 k-1 k1项都是相同的,第 k k k项是不同的,然后把 x x x y y y k k k项与前 k − 1 k-1 k1项拼起来,组成 k + 1 k+1 k+1大小的 i t e m s e t itemset itemset
在这里插入图片描述
用方法三我们就可以发现,对于上述的 L 2 L_2 L2我们找不出满足方法三的两个itemset,因此得到 C 3 C_3 C3是 {}
如果 L 2 L_2 L2是{ {1,2},{1,3},{2,3} },生成的 C 3 C_3 C3就是 { {1,2,3} },因为我们可以找到两个满足方法三的 i t e m s e t itemset itemset {1,2} 和 {1,3} ,他们的第一位都是1,第2位不相同分别是2和3,由此可以得到 C 3 C_3 C3中的一个满足条件的 i t e m s e t itemset itemset {1,2,3}

但是如果 L 2 L_2 L2是{ {1,2},{1,3} },生成的 C 3 C_3 C3也是 { {1,2,3} },但是我们清楚地知道这个生成的{1,2,3}是不可能频繁的,因为它的子集{2,3}不在 L 2 L_2 L2当中。所以虽然方法三是效率最高的,但是我们在生成了 C 3 C_3 C3之后也要做进一步的验证,即验证它的子集是否都在 L 2 L_2 L2中。

下面是一个具体的例子:
在这里插入图片描述

python代码实现

下面使用python实现上面的Apriori算法,其中通过频繁集生成候选集采用的是方法三。

计算支持率

#计算支持率
def support(item,T):
    n=len(T)   # 事务集合的长度
    l=len(item)
    count=0
    for x in T:
        if  len(set(x)&set(item)) == l:   # 判断是否有交集,有交集,分子加1
            count=count+1
    return  1.0*count/n

生成候选集

def produce_Candinate(L, k):
    candinate = []   # 首先创建一个空的集合
    for x in range(len(L)):   # 每两个元素集合进行比较
        for y in range(x + 1, len(L)):
            flag = True
            x_item = L[x]
            y_item = L[y]
            for i in range(k):
                if x_item[k - 1] == y_item[k - 1]:   # 如果两个元素集合的最后一项相同 ,候选集为空
                    flag = False
                    break
                elif x_item[i] != y_item[i] and i < k-1: # 如果前面 k-1 项有不相同的,候选集为空
                    flag = False
            if flag:
                temp = x_item.copy()
                temp.append(y_item[k - 1])  # 将q中的最后一项添加到p中
                temp.sort()
                if has_frequent_subset(temp, L, k):
                    candinate.append(temp)
    print("候选", k + 1, "-项集:", candinate)
    return candinate
    
# 判断候选集子集是否是频繁集
def has_frequent_subset(c, freq_items, n):
    num = len(c) * n  # 
    count = 0
    flag = False
    for c_item in freq_items:   
        if set(c_item).issubset(set(c)):    #判断上一层的频繁集中的每一项是否是计算出来的候选集的子集
            count += n   # 如果是就把count加上n
    if count == num:     # 如果最后相等(候选集的每个子集都在频繁集当中),就说明这个候选集中的每个子集都是频繁集
        flag = True
    return flag

Apriori算法挖掘频繁项集

#Apriori算法挖掘频繁项集
def Apriori(T,min):
    k=1
    #结果集,用于保存所有的频繁集
    out=[]
    #生成1-候选集
    C=[]
    for x in T:
        C=list(set(x)|set(C))
    #生成1频繁项集
    F=[]
    for i in C:
        if support(list(i),T) >= min:
            F.append([i])

    #迭代
    while (len(F)>0):
        out.append(F)
        #生成k+1候选集
        C=produce_Candinate(F,k)
        #生成k+1频繁项集
        F=[]
        for i in C:
            if support(i,T) >=min:
                F.append(i)
        k=k+1
    return out

主函数调用

T = [['A','B','C','D'], ['B','C','E'], ['A','B','C','E'], ['B','D','E'], ['A','B','C','D'] ]
out = Apriori(T,0.3)
print('频繁项集')
for i in out:
    print(i)

打印结果
在这里插入图片描述
以上就是Apriori算法的全部内容,其中知识点部分参考了b站清华大学-数据挖掘 ,代码部分参考了多篇文章,并加入了一些的注释和自己的理解,有疑问欢迎评论区讨论!

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

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

相关文章

线程2的深度剖析

加锁 synchronized 1.修饰方法&#xff08;普通方法&#xff0c;静态方法&#xff09;普通方法实际上加到了this上&#xff0c;静态方法加到了类对象上。 2.修饰代码块 手动指定加到那个对象上 明确锁对象针对那个对象加锁&#xff0c;如果两个线程针对同一个对象加锁&am…

(1)AWD入门攻略大纲

1.比赛介绍 (1)比赛环境 (2)常见服务器信息介绍 比赛名称 白名单&#xff1a;一般用于防止外部恶意攻击&#xff0c;如果赛方发现名单以外IP可能会进行封禁处理。 服务器账号密码 Token和虚拟IP&#xff1a;token为提交答案的凭证&#xff0c;绑定了队伍&#xff1b;虚拟IP为…

SpringCloud中Feign注解@FeignClient参数一览表

写在前面 Feign是微服务中服务间调用的优选组件&#xff0c;后来的OpenFeign也是基于此来开展的。 为什么要梳理一下Feign注解FeignClient中的各个参数&#xff1f; 踩坑太多面试总问 参数一栏表 FeignClient的源码示例图如下&#xff1a; 今天我们接着来说最后的几个参数。…

Java面试题(六)美团JVM夺命7连问(灵魂拷问)

0.来看一道美团的面试题 这题直接把人给问懵逼了&#xff0c;你能全部答出来吗&#xff1f; Object o new Object();请解释对象的创建过程&#xff1f;DCL要不要加volatile问题&#xff1f;对象在内存中的存储布局&#xff1f;什么是指针压缩&#xff1f;对象头具体包含哪些…

生成树问题汇总

生成树问题汇总注1、最小(大)生成树思路代码例子&#xff1a;1、最小生成树结果是2、最大生成树结果2、在最小生成树中再加一条边&#xff0c;求新的最小生成树思路代码核心代码全部代码例子3、次小生成树思路:在上一个功能基础上进一步扩充代码核心代码全部代码例子4、判断最小…

一个轻量级的分布式日志标记追踪神器,十分钟接入,非常好用!

TLog简介 1、TLog通过对日志打标签完成企业级微服务的日志追踪。它不收集日志&#xff0c;使用简单&#xff0c; 产生全局唯一的追踪码。除了追踪码以外&#xff0c;TLog还支持SpanId和上下游服务信息 标签的追加。 2、为用户使用方便而设计&#xff0c;提供完全零侵入式接入…

es入门(上)

笔记来源于学习 b站中的【IT李老师】的elasticsearch课程 自己在实习做的es模块中的理解。 后续会有 中&#xff0c;下篇笔记更新&#xff0c;目前这一篇是上篇。 目录 Elastic Stack简介 1.1简介 1.2特色 1.3组件介绍 2.Elasticsearch的接收与核心概念 2.1搜索是什么…

【Keras+计算机视觉+Tensorflow】OCR文字识别实战(附源码和数据集 超详细必看)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、OCR文字识别简介 利用计算机自动识别字符的技术&#xff0c;是模式识别应用的一个重要领域。人们在生产和生活中&#xff0c;要处理大量的文字、报表和文本。为了减轻人们的劳动&#xff0c;提高处理效率&#xff0c;从…

[python]初步练习脚本

之前练习的python&#xff0c;编写的脚本&#xff0c;现在作为记录&#xff0c;方便查看~ python 初步练习脚本基础部分的练习脚本脚本代码1、helloworld.py&#xff0c;有for循环语句2、main.py3、range—test.py&#xff0c;范围4、RE.py&#xff0c;花式输出内容5、turtle练…

Jekins安装和部署

1.官网下载 注意jekins各版本不同支持jdk的版本也不同 https://www.jenkins.io/download/ 如图进去后可看见最新版&#xff0c;而past releases是历史版本 查看自己各版本的支持 我下载的是2.346.1版本&#xff0c;是war包形式 2.启动jekins 直接在war包路径 java命令启动…

lspci命令整理

1. 作用&#xff1a; 显示当前主机的所有PCI总线信息 2. 常用指令&#xff1a; lspci -nn 第一列的数字&#xff1a;总线编号(Bus Number)&#xff1a;设备编号&#xff08;Device Number&#xff09;&#xff1a;功能编号&#xff08;Function Number&#xff09; 第一个中括…

全国青少年软件编程等级考试C语言标准解读(1_10级)

考试性质 全国青少年软件编程等级考试标准&#xff08;C/C&#xff09;由中国电子学会科普培训与应用推广中心指定。由全国青少年电子信息科普创新联盟标准工作组开发&#xff0c;由中国电子学会普及工作委员会审核通过&#xff0c;适用于由中国电子学会主办的青少年软件编程等…

vue中的process.env的理解

创建项目的时候突然发现好多前端有好多地方用到了这个process.env.xxxx但是发现其实我的新项目并没有定义这个内容&#xff0c;于是就对这个变量产生了好奇&#xff0c;这里总结一下 上图是我在node命令行下执行的查看了一下变量&#xff0c;看这情况直接是把系统的环境变量给…

少走弯路,关于在线客服系统的二三事

日常生活中&#xff0c;我们购买一个服务或一个商品时&#xff0c;时常会遇到以下场景&#xff1a; 售前咨询&#xff1a;向商家咨询服务的信息咨询、商品的规格产品咨询、以及商场活动、优惠咨询等 售后服务&#xff1a;商品使用问题、商品不满意退/换货等 在移动通信没有普…

Camera Surface 从应用到cameraserver的流转

一、Android相机应用与Surface Camera应用的预览一般通过SurfaceView去显示&#xff0c;SurfaceView作为显示的载体&#xff0c; Surface surface mSurfaceView.getSurfaceHolder().getSurface(); 获取的surface会通过Camera API1/API2的接口下发到framework层&#xff1b;…

基于模型的设计(MBD)在汽车ECU软件开发中的实践

基于模型的设计&#xff08;Model-based Design&#xff0c;以下简称MBD&#xff09;是一种围绕模型展开的项目开发方法&#xff0c;指对开发对象或者项目产品进行精确建模&#xff0c;项目的需求分析、功能设计、系统框架、代码生成、测试验证等开发环节都在模型的基础上展开。…

如何用策略模式,优化你代码里的的if-else?

最近有一个学妹在跟我沟通如何有效的去避免代码中一长串的if else判断或者switch条件判断&#xff1f;针对更多的回答就是合理的去使用设计来规避这个问题。 在设计模式中&#xff0c;可以使用工厂模式或者策略模式来处理这类问题&#xff0c;之前已经分享了工厂模式&#xff…

Hadoop集群中HDFS的API测试案例以及MapReduce的多种提交Job方式案例

这两个案例默认是hadoop集群环境已经搭建好以及IDEA环境也已经配置好 1、HDFS客户端测试案例 1.1、pom依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www…

Java使用ftl模板文件生成Word,以及Word转换图片或Pdf工具类

Java使用ftl模板文件生成Word 一、写在前面 最近在项目中使用打印功能&#xff0c;发现这个功能我已经写过多次了&#xff0c;下面这个文章的发步日期在2020年&#xff0c;不得不感慨时间之快啊。 https://blog.csdn.net/weixin_43238452/article/details/109636200?spm1001…

this关键字,是如何把你难倒的?

作为一名实战前端工程师&#xff0c;在jq时代&#xff0c;是经常被this关键字难倒的。几年前每次我意识到程序出现问题的时候&#xff0c;都本能反应是自己的this没有绑定好&#xff0c;于是重新绑定一下&#xff0c;就能解决了。但是他确实一直为难着我。 转眼到了2022年底&a…