【Apriori算法】

本文介绍了先验算法(Apriori)在数据挖掘中的应用,通过实例展示了如何处理购物篮数据,发现商品间的关联规律,如啤酒与尿布的故事。算法涉及频繁项集、关联规则、支持度、置信度和提升度的概念,以及其实现过程和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

先验算法(Apriori)

1.概述

在计算机科学以及数据挖掘领域中,先验算法(Apriori Algorithm)是关联规则学习的经典算法之一。

先验算法的设计目的是为了处理包含交易信息内容的数据库。例如,顾客购买的商品清单或者网页常访清单等。

先验算法采用广度优先搜索算法进行搜索并采用树结构来对候选项集进行高效计数。通过长度为k-1的候选项集来产生长度为k的候选项集,然后从中删除包含不常见子模式的候选项。根据向下封闭性引理,该候选项目集包含所有长度为k的频繁项目集。之后,就可以通过扫描交易数据库来决定候选项目集中的频繁项目集。

1.1 问题引入

啤酒与尿布的故事

有一个故事发生于20世纪90年代的美国超市中,超市管理人员分析销售数据时发现了一个令人难于理解的现象:在某些特定的情况下,“啤酒”与“尿布”两件看上去毫无关系的商品会经常出现在同一个购物篮中,这种独特的销售现象引起了管理人员的注意,经过后续调查发现,这种现象出现在年轻的父亲身上。

故事起因在美国有婴儿的家庭中,一般是母亲在家中照看婴儿,年轻的父亲前去超市购买尿布。父亲在购买尿布的同时,往往会顺便为自己购买啤酒,这样就会出现啤酒与尿布这两件看上去不相干的商品经常会出现在同一个购物篮的现象。

如果这个年轻的父亲在卖场只能买到两件商品之一,则他很有可能会放弃购物而到另一家商店,直到可以一次同时买到啤酒与尿布为止。

超市发现了这一独特的现象,开始在卖场尝试将啤酒与尿布摆放在相同的区域,让年轻的父亲可以同时找到这两件商品,并很快地完成购物。

这个故事是因为有数据分析的结果支持才会获得成功并得到广泛传播,通过分析购物篮中的商品集合数据,找出商品之间的关联关系,发现客户的购买行为,从而获得更多的商品销售收入。

1.2 基本概念

许多商业企业在日复一日的运营中积累了大量的数据。例如,食品商店的收银台每天都收集大量的顾客购物数据,其中,一位顾客一次购买商品的记录就是一条事务,称为购物篮事务(market basket transaction)。零售商对分析这些数据很感兴趣,以便了解他们的顾客的购买行为,可以使用这种有价值的信息来支持各种商务应用,如市场促销,库存管理和顾客关系管理等。

关联分析是用于发现隐藏在大型数据集中有意义的联系,所发现的联系可以用关联规则或频繁项集的形式表示。除了购物篮数据外,关联分析也可以应用于其他领域,如生物信息学、医疗诊断、网页挖掘和科学数据分析等。

在对购物篮数据进行关联分析时,需要处理两个关键的问题:第一,从大型事务数据集中发现模式可能在计算上要付出很高的代价;第二,所发现的某些模式可能是虚假的,因为它们可能是偶然发生的。

项集:在关联分析中,包含0个或多个项的集合被称为项集。

频繁项集(frequent item sets):集合内商品数量大于阈值的项集,经常出现在一块的物品的集合。

关联规则(associational rules):形如X⟶Y的蕴含表达式,其中X和Y是不相交的项集,即X∩Y=∅,暗示两种物品之间可能存在很强的关系。

支持度(support):确定规则可以用于给定数据集的频繁程度。

置信度(confidence):确定Y在包含X的事务中出现频繁程度。

提升度(lift): 置信度除以规则后件Y的支持度(引入这个指标的原因是置信度忽视了规则后件带来的影响,也就是说置信度很高可能仅仅是因为规则后件支持度很高造成的,该规则可能没有实际意义)。

**K项集 **:如果事件A中包含k个元素,那么称这个事件A为k项集,并且事件A满足最小支持度阈值的事件称为频繁k项集。

规则的产生:其目标是从上一步发现的频繁项集中提取所有高置信度的规则,这些规则称作强规则。

获取候选K频繁项集
通常采取合并K-1频繁项集的方法来获得K频繁项集。
1.合并:由于频繁项集是有序的,所以若两个K-1频繁项集的前K-2个相同,则考虑合并。
2.剪枝:合并后。只能确定原来的两个K-1项集是频繁的。还需要根据先验原理,检验K项集是否频繁。即逐个判定该K项集的子K-1项集是否频繁。

产生规则
一个K频繁项可以产生多个规则。同样,需要根据先验原理,去除置信度低于阈值的规则。(频繁项集产生的规则必定满足支持度,故无需考虑支持度)

初始化候选规则,即规则前件含有K-1个项
依次计算候选规则的置信度,大于阈值则存储规则,反之抛弃。
根据上一轮规则集合,合并前件产生新一轮的候选规则, 转步骤2。直到候选规则为空。

2.算法实现

2.1 算法思想

  • 首先找出所有的频集,这些项集出现的频繁性至少和预定义的最小支持度一样。
  • 然后由频集产生强关联规则,这些规则必须满足最小支持度和最小可信度。
  • 然后使用第1步找到的频集产生期望的规则,产生只包含集合的项的所有规则。一旦这些规则被生成,那么只有那些大于用户给定的最小可信度的规则才被留下来。

2.2 算法过程

第一步:通过迭代,检索出事务数据库中的所有频繁项集,即支持度不低于用户设定的阈值的项集;

第二步:利用频繁项集构造出满足用户最小信任度的规则。

  • 具体做法就是:首先找出频繁1-项集,记为L1;
  • 然后利用L1来产生候选项集C2,对C2中的项进行判定挖掘出L2,即频繁2-项集;
  • 不断如此循环下去直到无法发现更多的频繁k-项集为止。每挖掘一层Lk就需要扫描整个数据库一遍。
  • 算法利用了一个性质:任一频繁项集的所有非空子集也必须是频繁的

2.3 算法原理

在这里插入图片描述

图2.3 先验原理图

假设我们一共有 4 个商品: 商品0, 商品1,商品2, 商品3。

所有可能的情况如下:如果我们计算所有组合的支持度,需要计算 15 次。随着物品的增加,计算的次数将呈指数增长 。若使用Apriori 原理,即某个项集是频繁的,那么它的所有子集也是频繁的。能得到,如果 {0, 1} 是频繁的,那么 {0}, {1} 也是频繁的。反之,如果一个项集是非频繁项集,那么它的所有超集也是非频繁项集,如上图所示。

假设已知 {2,3} 是 非频繁项集,那么{0,2,3} {1,2,3} {0,1,2,3} 都是 非频繁的。 也就是说,计算出 {2,3} 的支持度,知道它是非频繁的之后,就不需要再计算 {0,2,3} ,{1,2,3} ,{0,1,2,3} 的支持度,因为我们知道这些集合不会满足我们的要求。 使用该原理就可以避免项集数目的指数增长,从而在更短更合理的时间内计算出频繁项集。

2.4 算法优缺点

优点

  • 易于理解、易于在大型数据集上实现 。

缺点

  • 需要扫描整个数据集,对计算能力要求高,如果是大型数据集,计算会十分耗时。

  • 适用数据类型:数值型或者标准型数据。

2.5 实例

假设有4000个客户交易,然后我们计算两种产品的Support、Confidence 和 Lift,比如说饼干和巧克力,因为客户经常一起购买这两种商品。在 4000 笔交易中,其中400笔包含饼干,而其中600笔包含巧克力,这600笔交易中包括200笔包含饼干和巧克力的交易。使用这些数据,我们将找出支持度、置信度和提升度:

支持度(饼干) = (饼干) / (总交易) = 400/4000 = 10%

置信度 = (饼干和巧克力) / (饼干) = 200/400 = 50%,这意味着 50% 的购买饼干的顾客也购买了巧克力。

提升度 = (置信度 (饼干和巧克力)/ (支持度(饼干) = 50/10 = 5

这意味着人们同时购买饼干和巧克力的概率是单独购买饼干的概率的五倍。如果提升度低于 1,则人们不太可能同时购买这两种物品。 值越大,组合一起被购买的几率越大。

2.6 python实现

案例一

本案例是使用超市的销售记录作为数据集。

代码

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

#读取数据
Data = pd.read_csv(r'C:\Users\我的电脑\OneDrive\桌面\AlgorithmDebugging\FrequentPattern\数据\Market_Basket_Optimisation.csv', header = None)
#print(Data)

#转换为列表
# Intializing the list
transacts = []
# populating a list of transactions
for i in range(0, 7501):
    transacts.append([str(Data.values[i,j]) for j in range(0, 20)])

#训练先验模型
from apyori import apriori
rule = apriori(transactions = transacts, min_support = 0.003, min_confidence = 0.2, min_lift = 3, min_length = 2, max_length = 2)

#可视化结果
output = list(rule) # returns a non-tabular output
# putting output into a pandas dataframe
def inspect(output):
    lhs         = [tuple(result[2][0][0])[0] for result in output]
    rhs         = [tuple(result[2][0][1])[0] for result in output]
    support    = [result[1] for result in output]
    confidence = [result[2][0][2] for result in output]
    lift       = [result[2][0][3] for result in output]
    return list(zip(lhs, rhs, support, confidence, lift))
output_DataFrame = pd.DataFrame(inspect(output), columns = ['Left_Hand_Side', 'Right_Hand_Side', 'Support', 'Confidence', 'Lift'])
#print(output_DataFrame)

# 按Lift列降序排列的结果
Lift = output_DataFrame.nlargest(n = 10, columns = 'Lift')
print(Lift)

结果

未排序结果:

在这里插入图片描述

按Lift列降序排列的结果:
在这里插入图片描述

案例二

通过Apriori算法进行关联规则挖掘,分析出导演一般喜欢哪些演员,哪个演员一般和哪个演员在一块演电影。

相关数据是从豆瓣电影上爬取的,此次我爬取了张艺谋导演和宁浩导演的电影,爬取的电影截图如下:

在这里插入图片描述

在这里插入图片描述

代码

from efficient_apriori import apriori
import csv


director = '宁浩'
file_name = 'C:/Users/我的电脑/OneDrive/桌面/AlgorithmDebugging/FrequentPattern/Apriori/webcrawler/'+director+'.csv'
lists = csv.reader(open(file_name, 'r', encoding='utf-8-sig'))

# 数据加载
data = []
for names in lists:
    name_new = []
    for name in names:
        # 去掉演员数据中的空格
        name_new.append(name.strip())
    data.append(name_new[1:])  # 去掉电影名, 加入列表

# 挖掘频繁项集和关联规则
itemsets, rules = apriori(data, min_support=0.3,  min_confidence=0.8)
print(itemsets)
print(rules)

from efficient_apriori import apriori
import csv


file_name = 'C:/Users/我的电脑/OneDrive/桌面/AlgorithmDebugging/FrequentPattern/Apriori/webcrawler/张艺谋.csv'
lists = csv.reader(open(file_name,'r',encoding='utf-8-sig'))

#数据加载
data = []
for names in lists:
    data.append(names[1:])

#挖掘频繁项集和关联规则
itemesets,rules = apriori(data,min_support=0.1,min_confidence=1)
print(itemesets)
print(rules)


结果
在这里插入图片描述

在我爬取的宁浩导演的数据中,徐峥一共单独出现6次,黄渤一共单独出现7次,(徐峥,黄渤)组合一共出现6次,它认为黄渤对徐峥的出现有帮助,徐峥对黄渤的出现也有帮助。

在这里插入图片描述

在我爬取的张艺谋导演的数据中,巩俐单独出现9次,李雪健单独出现5次。

<think>嗯,用户想了解Apriori算法的原理或实现,涉及数据挖掘和关联规则。首先,我需要回忆Apriori基本概念。记得Apriori是用来发现频繁项集和关联规则的,比如超市购物篮分析。那它的核心思想应该是通过逐层搜索,利用先验性质来减少计算量。 首先,得解释频繁项集和关联规则的定义。频繁项集是出现次数足够的项组合,而关联规则则是这些项之间的相关性,比如支持度和置信度。然后,Apriori的两个步骤:找频繁项集,然后生成规则。这部分需要详细说明,尤其是如何通过候选项集的生成和剪枝来优化效率。 接下来,算法步骤可能包括连接步和剪枝步。连接步是生成候选项集,剪枝步则是利用支持度阈值筛掉不符合的。需要举例子说明,比如从1-项集到2-项集的过程,以及如何计算支持度。同时,要提到Apriori的性质,即如果一个项集是非频繁的,它的超集也一定非频繁,这样可以剪枝。 关于实现部分,用户可能希望看到代码示例。Python的实现需要包括生成候选项集的函数,计算支持度,以及迭代的过程。代码要简洁,可能需要用集合操作或者frozenset来处理项集。此外,生成关联规则的部分,如何从频繁项集计算置信度,筛选出符合要求的规则。 还要考虑用户可能的问题,比如Apriori优缺点。效率问题,多次扫描数据库,候选集过多等。这时候可以提到FP-growth算法作为对比,但用户现在问的是Apriori,所以先不展开。 参考已有的引用内容,引用[1]和[2]提到Apriori的递归迭代和频繁项集生成,引用[4]提到先验性质和逐层搜索。这些需要整合到回答中,确保引用的正确性,比如剪枝策略和生成候选集的方法。 可能用户的实际应用场景是什么?比如市场分析、推荐系统,这些可以举例说明。同时,生成相关问题的时候,要围绕原理、优化、应用、优缺点等,引导用户进一步学习。 检查LaTeX格式是否正确,所有数学表达式用$...$,比如支持度计算$support(X) = \frac{count(X)}{N}$。独立公式如剪枝原理需要用$$...$$单独成段。代码块用三个反引号包裹,并注明语言。 最后,确保回答结构清晰,分点解释原理、步骤、实现,然后代码示例,应用场景,优缺点,相关问题。引用标识自然添加在相关段落末尾,如频繁项集生成部分引用[4],代码部分引用[1][2]。</think>### Apriori算法原理及实现详解 #### 一、Apriori算法基本原理 Apriori算法是关联规则挖掘的核心算法,其核心思想基于**先验性质**:若一个项集是频繁的,则它的所有子集也一定是频繁的;反之,若某个项集是非频繁的,则它的所有超集也一定是非频繁的[^4]。该性质通过逐层搜索(从1-项集到k-项集)生成候选频繁项集,并通过**支持度**(support)和**置信度**(confidence)筛选关联规则。 1. **关键概念** - **频繁项集**:满足最小支持度阈值的项组合,例如购物篮数据中$\{牛奶, 面包\}$的组合频繁出现 - **关联规则**:形如$X \Rightarrow Y$的表达式,需满足最小支持度和最小置信度,例如$\{尿布\} \Rightarrow \{啤酒\}$[^1] 2. **算法步骤** - **步骤1**:生成所有1-项集,筛选出频繁1-项集$L_1$ - **步骤2**:通过$L_{k-1}$生成候选k-项集$C_k$(连接步),并剪枝非频繁项集(剪枝步) - **步骤3**:重复步骤2直至无法生成更高阶项集 - **步骤4**:从频繁项集中提取关联规则,例如: $$ \text{置信度}(X \Rightarrow Y) = \frac{\text{support}(X \cup Y)}{\text{support}(X)} $$[^2] #### 二、Python实现代码 ```python def apriori(data, min_support=0.5): # 生成初始1-项集 C1 = [frozenset([item]) for transaction in data for item in transaction] # 筛选频繁1-项集 L1 = filter_by_support(C1, data, min_support) L = [L1] k = 2 while True: # 生成候选k-项集 Ck = generate_candidates(L[k-2], k) # 计算支持度并筛选 Lk = filter_by_support(Ck, data, min_support) if not Lk: break L.append(Lk) k += 1 return L def generate_candidates(itemsets, k): # 连接步:合并(k-1)-项集生成候选k-项集 return set([i.union(j) for i in itemsets for j in itemsets if len(i.union(j)) == k]) def filter_by_support(candidates, data, min_support): count = {candidate:0 for candidate in candidates} for transaction in data: for candidate in candidates: if candidate.issubset(transaction): count[candidate] += 1 N = len(data) return [candidate for candidate in candidates if count[candidate]/N >= min_support] ``` *代码说明:通过集合操作实现候选项集生成,支持度计算采用遍历计数法[^2]* #### 三、应用场景与优缺点 1. **典型应用** - 零售业购物篮分析(如“啤酒与尿布”经典案例) - 网站页面推荐系统 - 医学症状与疾病关联分析[^3] 2. **局限性** - 需多次扫描数据库,I/O开销大 - 候选集数量随项数指数级增长 - 改进方案:FP-Growth算法(无需生成候选集)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值