想象你经营着一家小镇杂货店,每天打烊后,收银台下堆满了顾客留下的购物小票。你发现一个有趣的现象:买啤酒的顾客常常会顺手拿一包尿布。如果把啤酒和尿布摆在同一排货架,销售额会不会更高?但要验证这个猜想,你需要从几千张小票中找到确凿证据——什么样的商品组合经常一起出现?这些组合背后藏着怎样的规律?这就是关联规则挖掘解决的问题,而 Apriori 算法正是解决这个问题最经典、最核心的工具。它像一位细心的店员,逐层筛选出“经常一起出现”的商品组合,再帮你提炼成“买了A也会买B”的规则。本文将从零开始,带你完整掌握 Apriori 的每个环节。
关联规则挖掘是数据挖掘工程师的必备技能,Apriori 算法则是该领域的地基。掌握它能让你在电商推荐、用户行为分析、医疗诊断等场景中,从海量数据里自动发现隐藏的“购物默契”。
可视化演示
展示Apriori算法从L1到L3的逐层频繁项集挖掘流程与关联规则生成,含支持度过滤与置信度评估。
本节配有交互动效(进入视口后自动加载,约 3KB)。
频繁项集逐层挖掘 L1:单项扫描统计支持度 L2:候选对组合过滤非频繁 L3:三项集验证向下封闭性 sup(X) >= minsup → frequent Apriori性质:频繁集子集必频繁。
关联规则概述
老王经营杂货店十多年了,收银台下的纸箱每天都会被顾客的小票填满。他隐约觉得“买面包的人总爱顺手拿牛奶”,但从来没认真验证过。直到有一天,他听说了“啤酒与尿布”的故事——国外超市发现周末买啤酒的年轻父亲常会顺手拿尿布,于是把啤酒和尿布摆在一起,销售额大涨。老王心动了:我也能从自己的小票箱里挖出这样的规律吗?
这个“从大量交易记录中发现商品之间联系”的过程,就是关联规则挖掘。它的核心产出是一种形如“如果买了 X,那么也会买 Y”的规则。在技术世界里,一张小票被称为一条事务(Transaction),一件商品被称为一个项(Item),若干个项的集合(比如{面包,牛奶})被称为项集(Itemset)。关联规则用数学符号表示为 $X \Rightarrow Y$,读作“X 蕴含 Y”,其中 $X$ 叫前件,$Y$ 叫后件。
回到老王的杂货店,一条真实规则可能是:{面包} ⇒ {牛奶}——顾客买了面包之后,大概率还会买牛奶。但老王不会轻易下结论,他需要数据来证明这条规则到底有多普遍、多可靠。这就引出了关联规则的两个核心度量指标。
- 左侧前件 $X$规则的条件部分,表示顾客已经购买的商品集合。
- 右侧后件 $Y$规则的结论部分,表示在满足前件条件下,可能被购买的商品集合。
- 不相交约束 $X \cap Y = \emptyset$同一件商品不能同时出现在规则两侧,否则规则就失去了预测意义——“买了苹果就会买苹果”是废话。
支持度与置信度
老王盯着一张小票猛看没意义,他需要全盘数据。于是他决定用两个数字来给每条规则打分:支持度(Support)和置信度(Confidence)。支持度回答的问题是“这条规则覆盖了多少顾客”,置信度回答的则是“这条规则对买前件的顾客有多准”。
支持度的计算很简单:包含某个项集 $X$ 的事务数(小票数)除以总事务数 $N$。比如 5 张小票中有 3 张包含了{面包,牛奶},那这个组合的支持度就是 3/5 = 60%。它衡量的是“普遍性”——支持度太低,说明这个组合太罕见,规则没有商业价值。
光有支持度还不够。老王发现{面包,牛奶}出现在 60% 的小票里,但万一买面包的人特别多、几乎人人都会拿牛奶呢?于是他需要置信度:在所有买了面包的顾客中,有多大比例同时买了牛奶?这个条件概率式的指标,才是规则“可信度”的体现。
在实际应用中,老王会设定两个门槛:最小支持度(minsup)和最小置信度(minconf)。支持度低于 minsup 的项集直接淘汰,置信度低于 minconf 的规则不予采纳。此外还有一个重要指标提升度(Lift):它衡量 X 和 Y 的关联是否只是巧合。如果提升度大于 1,说明 X 的出现确实提升了 Y 的购买概率;等于 1 则说明两者独立。
- 分子 $\sigma(X \cup Y)$同时包含前件和后件的事务数。
- 分母 $\sigma(X)$仅包含前件的事务数,作为“基准群体”。
- 条件的本质置信度实际上是一个条件概率,即 $P(Y | X)$。
Apriori性质
老王明白了支持度和置信度的用法,但新的烦恼来了:店里有几百种商品,商品两两组合就有几万种可能性,三三组合更是天文数字。难道要穷举所有组合吗?幸运的是,Apriori 算法发现了一条至关重要的规律——向下封闭性(也叫 Apriori 性质)。
这条性质用大白话说就是:如果一个项集是频繁的,那么它的所有子集一定是频繁的;反过来,如果一个项集是不频繁的,那么它的所有超集一定也不频繁。这个“反过来”的说法(即反单调性)是剪枝的利器:面包单独卖出率就很低,那“面包 + 鱼子酱”的组合卖得好的概率就更低,根本不用费劲去统计。
这个性质让老王豁然开朗:他只需要先找出那些“单卖得好”的商品,然后用它们两两组合找二项集,再用频繁二项集组合找三项集——每一步都不必重新从全部商品里海选。这就是 Apriori 算法“逐层搜索”的指导思想:从 1 项集开始,一层一层向上构建,同时用向下封闭性砍掉大量无效分支。数据挖掘界把这称为“先验原理”,它让组合爆炸的难题变得清晰可控。
- 包含关系 $Z \subseteq X$$Z$ 是 $X$ 的任意子集,即 $Z$ 中的商品是 $X$ 的一部分。
- 计数单调性 $\sigma(Z) \geq \sigma(X)$包含 $X$ 的小票一定包含 $Z$,反之不成立,所以 $Z$ 的计数只多不少。
- 剪枝推论若 $\sigma(X) < \text{minsup}$,则所有包含 $X$ 的超集 $S \supseteq X$ 都不是频繁项集。
频繁项集挖掘
有了 Apriori 性质这把“剪刀”,老王开始正式实施他的挖掘计划。频繁项集挖掘(Frequent Itemset Mining)的目标是:找出所有支持度不低于 minsup 的项集。Apriori 算法用“迭代 + 剪枝”的方式来完成这件事,整个过程就像盖金字塔,从底层往上逐层搭建。
算法的每一层迭代分成两步:连接步和剪枝步。连接步根据上一层的频繁 $k$-项集,两两连接生成候选 $(k+1)$-项集;剪枝步则用 Apriori 性质剔除掉“自身就包含不频繁子集”的候选。连接步的数学规则是:两个频繁 $k$-项集必须恰好共享 $k-1$ 个项,才能连接成一个新的 $(k+1)$-项集。
完整的迭代流程可以概括如下。首先扫描整个数据库,统计每个单项的出现次数,筛出频繁 1-项集 $L_1$;然后循环执行:用 $L_k$ 连接生成候选集 $C_{k+1}$ → 扫描数据库统计 $C_{k+1}$ 中每个候选的支持度 → 剔除支持度低于 minsup 的候选,得到 $L_{k+1}$。当某轮无法生成任何新的候选集时,算法终止。以老王的 5 张小票为例(设 minsup = 2):第 1 轮找到 {B}、{M}、{P}、{D} 四个频繁单项;第 2 轮生成 6 个候选二项集,其中 {B,P} 和 {M,P} 只出现 1 次,被剪枝;第 3 轮只剩 {B,M,D} 一个候选,恰好出现 2 次,成为唯一的频繁三项集。
- 候选集 $C_{k+1}$第 $k+1$ 轮的所有候选 $(k+1)$-项集。
- 频繁集 $L_k$第 $k$ 轮筛选出的所有频繁 $k$-项集组成的集合。
- 连接条件 $|X \cap Y| = k-1$两个 $k$-项集必须有 $k-1$ 个公共项,拼接后才恰好得到 $k+1$ 个不同的项。
关联规则生成
频繁项集挖掘完成之后,老王手里有了一批“经常一起出现”的商品组合,但这还不够——他需要的是“买了 A 就会买 B”这样可以直接指导货架摆放的规则。关联规则生成阶段,就是把每个频繁项集拆解成若干条候选规则,再逐条验证置信度。
假设老王挖掘出了频繁项集 {B, M, D}(面包、牛奶、尿布经常一起买)。这个三项集可以拆出 6 条候选规则:
- {B} → {M, D},{M} → {B, D},{D} → {B, M}
- {B, M} → {D},{B, D} → {M},{M, D} → {B}
每条规则都需要验证置信度是否达到 minconf 阈值。一般规则:对于一个频繁项集 $L$,它的任意非空真子集 $S$ 都可以作为前件,后件就是 $L - S$。置信度公式与之前讨论的完全一致:$\sigma(L) / \sigma(S)$。
继续算老王的例子:{B, D} → {M} 这条规则中,$\sigma({B,D,M}) = 2$,$\sigma({B,D}) = 3$,置信度为 2/3 ≈ 0.67,若 minconf 设为 0.6,则通过验证。而 {D} → {B, M} 的置信度是 2/4 = 0.5,不达标,被淘汰。最终留下的强规则就是老王能实际运用的“商业情报”。
- 拆解前件 $S$$S$ 取 $L$ 的任意一个真子集(非空且不等于 $L$ 本身)。
- 后件 $L \setminus S$从 $L$ 中减去 $S$ 剩下的商品,构成规则的结论部分。
- 置信度验证当 $\sigma(L) / \sigma(S)$ 不小于最小置信度时,规则 $S \Rightarrow (L \setminus S)$ 就被保留为强规则。
复杂度优化
老王的杂货店越开越大,小票量从每天几十张涨到了上万张,商品种类也翻了好几倍。Apriori 算法虽然巧妙,但它在处理大规模数据时的缺点也暴露了出来——频繁项集挖掘的计算开销不容忽视。
Apriori 最大的瓶颈在于反复扫描数据库。每一轮迭代都要重新遍历全部事务,统计候选集的支持度。如果最大频繁项集的长度为 $k_{\max}$,就需要扫描数据库 $k_{\max}$ 次。对于海量数据,这会产生巨额的 I/O 开销。其次,候选集的数量也可能非常庞大:即使通过剪枝,二项集的候选数量依然可能达到商品数的平方量级。
针对这些瓶颈,数据工程师们提出了多种优化手段。第一是更好的剪枝:充分利用 Apriori 性质,在连接步生成候选时就剔除所有含不频繁子集的候选,大量减少 $|C_k|$。第二是事务压缩:如果一个事务不包含任何频繁 $k$-项集,那么它也不可能包含任何频繁 $(k+1)$-项集,可以直接从后续扫描中剔除,逐步缩小数据库。第三是哈希树索引:将候选集组织成哈希树结构,在扫描事务时能快速定位并更新匹配的候选计数,大大加快支持度统计的速度。这些优化让 Apriori 在处理百万级事务时依然可行。
- 第 $k$ 轮候选数 $|C_k|$每轮生成的候选项集个数,它越大,这一轮的统计工作量越大。
- 事务数 $N$每个候选都要与所有 $N$ 条事务比对,判断是否包含。
- 累加求和把从第 1 轮到最后一轮的开销全部累加起来,就是算法的整体瓶颈。
应用场景
掌握了 Apriori 的全部原理,老王的杂货店彻底升级了。他不仅把面包和牛奶放在相邻的货架,还根据挖掘出的规则调整了促销策略。其实在生活中,Apriori 算法的影子无处不在,它是许多智能系统的幕后功臣。
电商推荐系统是最典型的应用。你会发现购物网站常显示“购买此商品的顾客也购买了……”,这背后正是关联规则在起作用。系统从海量订单中挖掘出“手机壳 → 钢化膜”这样的高频规则,当用户把手机壳加入购物车时,系统立刻推荐钢化膜——支持度保证了这个推荐不是冷门偏方,置信度保证了它足够可靠。医疗诊断中,Apriori 被用来挖掘症状与疾病之间的关联:比如通过分析电子病历,发现“持续咳嗽 + 低烧 + 乏力”组合频繁出现,辅助医生快速初步判断。金融风控领域则用它识别欺诈模式:某些异常交易项组合频繁共现时,可能预示着盗刷行为。
在这些场景中,单靠支持度和置信度还不够,评估规则价值时,提升度(Lift)是很关键的补充指标。它衡量 X 的出现是否真正“提升”了 Y 的购买概率:
从老王的杂货店到大型电商平台,Apriori 的核心思想始终不变:用支持度筛选普遍规律,用置信度验证规则可靠,用提升度排除虚假关联。当你下一次看到“购买此商品的人还买了……”时,你就能意识到,这背后正是一场严谨的“小票寻宝”。
- 分子 $\text{support}(X \cup Y)$X 和 Y 同时出现的实际比例。
- 分母乘积假设 X 和 Y 相互独立时,两者同时出现的期望比例。
- 比值判断实际比例超过期望比例,说明 X 对 Y 有真实的拉动作用,规则不是巧合。
AI 应用场景
电商购物篮推荐
阶段:数据挖掘与模式发现
解决的问题:传统推荐依赖人工经验配置,无法发现长尾商品的潜在关联。Apriori 自动从订单数据中挖掘“频繁共现”的商品组合,为推荐系统提供规则库。例如某零食电商发现“辣条 + 冰红茶”的组合支持度达 12%、置信度达 68%,于是将两件商品捆绑促销,转化率提升 23%。
具体案例:某大型超市在分析年度 POS 数据后,用 Apriori 挖掘出“婴儿纸尿裤 + 湿巾 + 玩具”的强关联规则。运营团队据此在纸尿裤货架旁设置了母婴用品专区,并推出“满减”组合套餐,该品类季度销量环比增长 31%。
医疗症状关联分析
阶段:模式识别与辅助决策
解决的问题:医生靠经验判断症状组合费时费力,且容易遗漏罕见关联。Apriori 可从结构化病历中挖掘“症状项集”与“疾病项集”之间的强规则,辅助早期筛查。例如在某医院呼吸道门诊数据中,发现“持续咳嗽 + 咽痛 + 发热 > 38.5°C”频繁指向流感,规则置信度达 81%。
具体案例:某三甲医院对近三年 10 万份体检报告做关联分析,发现“高血压 + 高血脂 + 超重”三者共现的频繁项集支持度 18.7%。据此建立起三高人群的联合干预方案,将相关并发症的早期发现率提高了 15%。
金融反欺诈特征识别
阶段:异常模式挖掘
解决的问题:欺诈行为往往表现为某些“交易特征组合”的异常共现。Apriori 可以挖掘出欺诈样本中的频繁项集,形成规则库供风控系统实时拦截。例如发现“异地登录 + 大额转账 + 新绑设备”的关联组合在欺诈订单中出现频率是正常订单的 5 倍。
具体案例:某支付平台对历史欺诈订单做关联规则挖掘,提取出“凌晨时段 + 频繁改密 + 短期多笔消费”的高危规则。风控团队将这些规则注入实时决策引擎,在不影响正常用户通过率的前提下,欺诈拦截率提升了 18%。
Python 演示
# -*- coding: utf-8 -*-from itertools import combinationsfrom collections import defaultdict def load_transactions(): # 5 张小票, 每张是一个商品集合 # B=面包 M=牛奶 P=啤酒 D=尿布 return [ {'B', 'M', 'D'}, {'B', 'M'}, {'P', 'D'}, {'B', 'M', 'P', 'D'}, {'B', 'D'}, ] def calc_support(itemset, transactions): # 统计包含 itemset 的事务数占总事务数的比例 count = 0 for txn in transactions: if itemset.issubset(txn): count += 1 return count / len(transactions) def apriori(transactions, min_sup=0.4): # 第一步: 统计所有单个商品的支持度 item_count = defaultdict(int) for txn in transactions: for item in txn: item_count[item] += 1 total = len(transactions) # 筛选出频繁 1 项集 all_freq = [] freq_map = {} for item, cnt in item_count.items(): if cnt / total >= min_sup: all_freq.append({item}) freq_map[(item,)] = cnt / total k = 2 while True: # 连接步: 从上一层的频繁项集生成候选 k 项集 candidates = set() prev = all_freq cur_freq = [] for i in range(len(prev)): for j in range(i + 1, len(prev)): union = prev[i] | prev[j] if len(union) == k: candidates.add(frozenset(union)) # 剪枝步: 凡是含非频繁子集的候选直接剔除 all_freq_sets = [frozenset(s) for s in all_freq] candidates = [ c for c in candidates if all(frozenset(sub) in all_freq_sets for sub in combinations(c, k - 1)) ] if not candidates: break # 扫描数据库, 验证候选支持度 for c in candidates: sup = calc_support(set(c), transactions) if sup >= min_sup: cur_freq.append(set(c)) freq_map[tuple(sorted(c))] = sup if not cur_freq: break all_freq.extend(cur_freq) k += 1 return all_freq, freq_map def generate_rules(freq_items, freq_map, min_conf=0.6): rules = [] for itemset in freq_items: items = tuple(sorted(itemset)) if len(items) < 2: continue # 枚举前件的所有可能大小 for size in range(1, len(items)): for anton_tuple in combinations(items, size): anton = set(anton_tuple) con = set(items) - anton sup_xy = freq_map[tuple(sorted(itemset))] sup_x = freq_map[tuple(sorted(anton))] conf = sup_xy / sup_x if conf >= min_conf: rules.append((anton, con, conf)) return rules if __name__ == '__main__': transactions = load_transactions() freq_items, freq_map = apriori(transactions, min_sup=0.4) print('频繁项集:') for s in sorted(freq_map.keys()): print(' ', set(s), '支持度=%.2f' % freq_map[s]) print('\n强规则 (min_conf=0.6):') rules = generate_rules(freq_items, freq_map, min_conf=0.6) for anton, con, conf in sorted(rules, key=lambda r: -r[2]): print(' %s -> %s 置信度=%.2f' % (set(anton), set(con), conf))
item_count[item] += 1扫描所有事务,统计每个商品的出现次数,这是生成候选 1 项集的基础。if cnt / total >= min_sup:用支持度阈值筛出频繁单项,作为迭代的起点。union = prev[i] | prev[j]连接步的核心:利用集合求并集,把两个 $k$-项集拼接成候选 $(k+1)$-项集。if len(union) == k:只有拼接结果恰好包含 $k$ 个不同项的才保留,避免产生重复项。frozenset(sub) in all_freq_sets剪枝步:检查候选的每个 $k$-项子集是否都在频繁集中,否则剔除。if not candidates: break无法生成任何新候选时,迭代自然终止。calc_support(set(c), transactions)重新扫描数据库,统计候选集的实际支持度。for size in range(1, len(items)):规则生成阶段,枚举前件所有可能的子集大小,保证不拆出空规则。conf = sup_xy / sup_x计算每条候选规则的置信度,并与 minconf 比较。
常见误区
误区我只要找支持度最高的商品组合就行了,支持度 80% 的规则一定比 20% 的更有用。
正解支持度高只说明“组合常见”,未必代表“前件能推动后件”。例如“面包 + 牛奶”支持度很高,但几乎所有顾客都会同时买它们,这并不能指导差异化营销。真正有价值的是高置信度 + 高提升度的规则,比如“啤酒 → 尿布”虽然支持度只有 5%,但置信度和提升度都很高,才是值得采用的商业情报。
为何常见:初学者容易把“出现得多”和“有洞察”混为一谈,因为直觉上高频的东西似乎更重要,却忽略了规则要解决的是“条件与结果之间的推进关系”。
误区{打火机} → {香烟} 置信度有 90%,所以打火机是香烟的原因,只要促销打火机就能带动香烟销量。
正解置信度衡量的只是统计层面的相关性,与因果是两回事。打火机和香烟的高置信度,可能是因为两者都受“吸烟者”这个隐藏因素驱动,即使没有打火机,吸烟者也会买香烟。要推断因果需要随机对照实验或更专业的因果推断方法。
为何常见:人脑天然倾向于为统计相关编造因果故事,尤其是当置信度很高时,这种因果错觉会更加强烈。
误区商品有 100 种,组合就有 2¹⁰⁰ 种,Apriori 肯定要穷举完才能找到频繁项集,所以没法用。
正解Apriori 的核心价值恰恰在于不用穷举。它利用向下封闭性质层层剪枝:先找频繁 1 项集,再用它们生成 2 项集候选,非频繁组无论如何都不会进入下一轮。实际扫描轮次最多等于最长频繁项集的长度,候选数量被压缩到很小的范围。
为何常见:初学者了解组合爆炸理论后容易先入为主,忽视了 Apriori 性质带来的“先验剪枝”是算法设计的灵魂。
误区我把 minsup 设成 0.8、minconf 设成 0.95,这样得到的规则肯定最精准。
正解阈值设得太高会让规则库变得极其贫乏——只有最寻常的组合能通过,真正有业务价值的“长尾规则”会被全部淹没。阈值设得太低又会产出大量噪声规则。通常需要结合提升度、业务目标来综合调参,并且在不同数据集上验证规则稳定性。
为何常见:人总是追求“完美”的结果,但在数据挖掘里,过高的标准往往意味着过少的有效发现,阈值本质上是“覆盖率”与“准确率”的权衡。
误区只要我用 Apriori,几十亿条交易记录也能轻松跑完,毕竟算法是经典算法嘛。
正解经典不代表不存在短板。Apriori 需要反复扫描数据库,候选集也可能指数增长,在超大规模数据上会力不从心。工程实践中,人们会用 FP-Growth(不生成候选直接建频繁模式树)、垂直数据格式(布隆过滤器加速计数)等方法替代或补充它。理解 Apriori 的价值在于掌握关联规则的本质,至于选哪种实现,要视数据规模而定。
为何常见:教材通常强调 Apriori 的历史地位,容易让人忽略它在大数据场景下的性能局限。
面试题
Q1. Apriori算法属于以下哪类机器学习任务?
- A.监督学习
- B.无监督学习← 正确答案
- C.强化学习
- D.迁移学习
答案:B。Apriori 挖掘关联规则时,训练数据只有交易记录,没有预先标注好的“正确答案”,算法自发发现数据中的模式,因此属于无监督学习。监督学习要求有标签,强化学习需要奖励信号,迁移学习涉及跨任务知识迁移,均不符合。
Q2. 项集 X 的支持度(support)定义为:
- A.包含 X 的事务数除以事务总数← 正确答案
- B.包含 X 的事务数乘以事务总数
- C.事务总数除以包含 X 的事务数
- D.包含 X 的事务数除以包含 X 和 Y 的事务数
答案:A。支持度衡量项集的普遍性,等于“包含 X 的小票数 ÷ 全部小票数”。选项 B 和 C 的运算结果会超过合理范围,不具有概率意义;选项 D 实际上是条件概率的变形,不属于支持度定义。
Q3. Apriori 性质(向下封闭性)的核心含义是:
- A.若项集频繁,则其超集必频繁
- B.若项集频繁,则其子集必频繁← 正确答案
- C.若项集不频繁,则其子集必不频繁
- D.项集频不频繁与其子集无关
答案:B。向下封闭性说的是:频繁项集的所有子集都频繁。选项 A 是向上方向的错误猜测,超集不一定频繁;选项 C 反了,不频繁项集的子集可能是频繁的;选项 D 否认了这条性质。正确的剪枝推论是“不频繁项集的超集必不频繁”。
Q4. 规则 {M} → {B} 的置信度如何计算?
- A.support({M,B}) 除以 support({M})← 正确答案
- B.support({M}) 除以 support({M,B})
- C.support({M,B}) 除以 support({B})
- D.support({M}) 乘以 support({B})
答案:A。置信度 = 同时包含前件和后件的事务数 ÷ 包含前件的事务数,即 support(X∪Y) / support(X)。选项 B 把分子分母颠倒,选项 C 用的是后件的支持度做分母,选项 D 是独立假设下的期望共现概率,均非置信度定义。
Q5. 关于提升度(lift)的说法,正确的有:
- A.提升度大于1表示前件与后件正相关← 正确答案
- B.提升度等于1表示两者相互独立← 正确答案
- C.提升度小于1表示前件抑制后件出现← 正确答案
- D.提升度越高规则一定越正确
答案:ABC。提升度衡量实际共现概率与独立假设下期望概率的比值。大于 1 说明前件提升了后件出现概率,等于 1 说明无关,小于 1 说明负相关,因此 A、B、C 都正确。D 错误——提升度高只说明关联强度大,规则是否“正确”还需结合业务场景和因果验证。
Q6. 传统 Apriori 算法最大的性能瓶颈是:
- A.需要反复扫描事务数据库← 正确答案
- B.无法处理数值型连续数据
- C.只能发现单项之间的关联
- D.需要人工标注训练样本
答案:A。Apriori 每一轮迭代都要扫描数据库统计候选支持度,扫描次数等于最大频繁项集层数,I/O 开销巨大。B 属于数据类型限制而非性能瓶颈;C 错误,Apriori 支持多项集;D 错误,它是无监督算法,不需要标注。
Q7. Apriori 剪枝原理的直接应用是:
- A.删除支持度低于阈值的项集及其所有超集← 正确答案
- B.将事务按商品数量降序排列后再挖掘
- C.对每条规则额外计算置信度
- D.将频繁项集转化为用户画像
答案:A。既然非频繁项集的超集必非频繁,那么一旦某个 k-项集不频繁,所有包含它的 (k+1)-项集、 (k+2)-项集都可以直接剪掉,这正是 Apriori 剪枝的直接应用。B、C、D 都是其他环节的技术,不属于剪枝性质。
Q8. 生成候选 3 项集时,两个频繁 2 项集如何连接?
- A.必须恰好共享 1 个公共项才可连接← 正确答案
- B.任意两个 2 项集都可以连接
- C.必须完全相同才可以进行连接
- D.两个 2 项集无法连接成 3 项集
答案:A。连接步要求两个 k-项集共享 k-1 个项。对于 2 项集,只有共享 1 个公共项时,并集大小才会恰好是 3,例如 {B,M} 与 {B,D} 连接得 {B,M,D}。若无公共项,并集是 4 项;若完全相同,并集仍是 2 项,都无法得到合格的 3 项候选。
Q9. 以下哪些方法能够优化 Apriori 算法的性能?
- A.用哈希树组织候选集加速计数← 正确答案
- B.压缩不包含频繁项集的事务← 正确答案
- C.将最小支持度阈值设为 0
- D.用 FP-Growth 算法替代← 正确答案
答案:ABD。哈希树能让事务在扫描时快速定位候选,加速支持度统计;事务压缩剔除不含频繁项集的小票,减少后续扫描规模;FP-Growth 是无需生成候选的替代方案。将最小支持度设为 0 会让所有组合都成为候选,反而导致组合爆炸,属于错误做法。
Q10. 已知交易数据为:T1={B,M,D},T2={B,M},T3={P,D},T4={B,M,P,D},T5={B,D},minsup=2,minconf=0.6,以下哪些规则是有效的强规则?
- A.{B} → {M},置信度 0.75← 正确答案
- B.{M} → {B},置信度 1.0← 正确答案
- C.{D} → {M},置信度 0.5← 正确答案
- D.{P,D} → {B},置信度 0.75
答案:ABC。support({B,M})=3,support({B})=4,所以 B→M 置信度 3/4=0.75,A 正确;support({M})=3,M→B 置信度 1.0,B 正确;support({D})=4,support({D,M})=2,D→M 置信度 2/4=0.5,低于 minconf(0.6),C 不是强规则;support({P,D})=2,support({B,P,D})=1,P,D→B 置信度 0.5,D 错误。