SMILE 关联规则挖掘实战指南:基于 FP-Growth 的频繁项集与 ARM 关联规则评估

发布时间:2026/10/9 4:53:25
SMILE 关联规则挖掘实战指南:基于 FP-Growth 的频繁项集与 ARM 关联规则评估 人工智能机器学习深度学习NLP大模型模型推理服务数据可视化【免费下载链接】smileStatistical Machine Intelligence Learning Engine项目地址https://gitcode.com/gh_mirrors/smi/smile点击查看免费下载本篇技术指南聚焦 SMILEStatistical Machine Intelligence Learning Engine中smile.association包提供的关联规则挖掘Association Rule Mining能力完整覆盖 FP-Growth 频繁项集挖掘、FP-Tree 构建、关联规则生成以及支持度support、置信度confidence、提升度lift、杠杆率leverage四大指标的解释与过滤。读完本文你将掌握如何在内存与超大文件两种场景下构建 FP-Tree、挖掘频繁项集、生成并筛选高质量关联规则并理解这些 API 在 SMILE 源码中的底层实现原理。1) 概览smile.association包的核心类与工作流SMILE 在 core/src/main/java/smile/association 下提供了一整套高效关联规则挖掘实现。包中共有六个类分工如下类角色FPTree紧凑的事务索引前缀树 头表 header table压缩存储整个事务库FPGrowth基于 FP-Growth 算法的频繁项集挖掘器ItemSet频繁项集携带原始支持度计数recordTotalSupportTree总支持度树T-tree压缩的集枚举树用于规则生成的存储高效中间结构ARM从 T-tree 生成关联规则AssociationRule规则对象含前件antecedent、后件consequent及各项指标record挖掘流水线十分简洁核心调用链如下transactions → FPTree.of(minSupport, ...) → FPGrowth.apply(tree) // StreamItemSet → ARM.apply(confidence, tree) // StreamAssociationRule从源码看FPGrowth.apply与ARM.apply均通过StreamSupport.stream(..., false)返回惰性、顺序的流见 FPGrowth.java 与 ARM.java结果按需生成不会一次性把所有结果加载进内存。2) 核心概念从事务到规则在深入代码之前先明确关联规则挖掘的五个基础概念Transaction事务一组 item ID 的集合代表一次购物篮、一笔订单或一篇文档。Item set项集在同一组事务中共同出现的条目子集。Support支持度supp(X)包含项集X的事务占全部事务的比例。在ItemSet中为原始计数在AssociationRule中为比例分数。Rule规则X ⇒ YX前件/antecedent与Y后件/consequent是不相交的项集。Confidence置信度conf(X ⇒ Y) supp(X ∪ Y) / supp(X)估计条件概率P(Y | X)。Lift提升度lift(X ⇒ Y) supp(X ∪ Y) / (supp(X) · supp(Y))与统计独立性假设相比的比值。Leverage杠杆率lev(X ⇒ Y) supp(X ∪ Y) − supp(X) · supp(Y)相对独立性的绝对偏差。AssociationRule的 Javadoc 对 lift 给出了直观解释lift 1 表示 X 与 Y 独立大于 1 表示正相关小于 1 表示负相关见 AssociationRule.java。这也正是后续用它过滤有意义的关联的理论依据。3) 数据格式事务如何表示smile.association的事务交易以int[]数组表示数组元素是非负整数 item IDint[][] transactions { {1, 3}, {2}, {4}, {2, 3, 4}, {2, 3}, {2, 3}, {1, 2, 3, 4}, {1, 3}, {1, 2, 3}, {1, 2, 3} };数据格式规则Item ID 必须是非负整数每行长度可以不同各事务包含的条目数不同同一事务内的重复条目会被容忍并折叠支持度按每条事务中的出现与否计数而不是按出现次数计数。这一点在FPTree.freq()的实现中体现得很清楚——首遍扫描会先对每个事务排序然后用prev变量跳过重复元素见 FPTree.java。另外从源码可推断item ID 的取值应当尽量紧凑freq()用数组而非散列表统计频次初始容量由系统属性smile.arm.items控制默认 65536稀疏的大 ID 会浪费数组空间——这与后文性能建议相互印证。4) 构建 FP-Tree内存版与流式版类smile.association.FPTree4.1 内存内构建FPTree.of提供两种最小支持度形式// 绝对最小支持度频次计数 FPTree tree FPTree.of(3, transactions); // minSupport 3 // 相对最小支持度事务比例 FPTree tree FPTree.of(0.3, transactions); // 30% of 10 3两种形式在百分比折算为相同整数计数时产生的树完全一致。源码中百分比形式通过Math.round(minSupport * numTransactions)折算为绝对支持度见 FPTree.java测试 FPGrowthTest.java 与 ARMTest.java 都验证了两种形式挖掘结果一致。构建完成后可查询树的元信息int n tree.size(); // 事务总数 int s tree.minSupport(); // 生效的整数支持度阈值4.2 流式构建大文件场景对于无法整体放入内存的大型数据集使用SupplierStreamint[]。注意supplier 会被调用两次——第一次用于统计单项频次第二次用于构建前缀树两遍扫描设计见 FPTree.java因此 supplier 必须是可重复调用、可重新读取数据源的。import java.util.stream.Stream; import java.util.function.Supplier; // 示例从文件读取事务 SupplierStreamint[] supplier () - { return java.nio.file.Files.lines(java.nio.file.Path.of(transactions.txt)) .map(line - Arrays.stream(line.split(,)) .mapToInt(Integer::parseInt).toArray()); }; FPTree tree FPTree.of(1500, supplier); // 绝对支持度 FPTree tree FPTree.of(0.003, supplier); // 相对支持度0.3%4.3 输入校验FPTree.of强制校验前置条件违规时抛出IllegalArgumentException变体校验条件of(int, ...)minSupport 1of(double, ...)minSupport在(0, 1]区间两种变体事务流不能为空FPTree.of(0, transactions); // 抛出 — minSupport 必须 1 FPTree.of(0.0, transactions); // 抛出 — 百分比必须 0 FPTree.of(1.1, transactions); // 抛出 — 百分比必须 1校验逻辑位于 FPTree.java 的各个of重载中空流校验在freq()中numTransactions 0时抛异常见 FPTree.java。测试 ARMTest.java 对 0、-1、0.0、1.1 等非法值均有断言。空树处理当minSupport大于事务总数时没有任何条目是频繁的。FPGrowth.apply与ARM.apply都会无报错地返回空流——这是经过测试验证的正确行为见 ARMTest.java。5) 挖掘频繁项集FP-Growth类smile.association.FPGrowthFPTree tree FPTree.of(3, transactions); // 返回 StreamItemSet — 惰性、顺序 StreamItemSet stream FPGrowth.apply(tree); // 物化并查看 stream.forEach(set - System.out.printf(%s (support%d)%n, Arrays.toString(set.items()), set.support()) );ItemSet是一个不可变的record见 ItemSet.javarecord ItemSet(int[] items, int support) { ... }字段类型含义items()int[]按频次降序排列的 item IDsupport()int原始事务计数ItemSet.equals/hashCode同时包含items与support两个字段。toString输出形如ItemSet([3, 2], support6)底层原理补充FP-Growth 算法在源码层面采用模式片段增长pattern fragment growth的递归消除策略跳过 Apriori 式的候选生成与测试因而在频繁项集挖掘上非常快见 FPGrowth.java 的类注释算法参考 Han 等 2004、Grahne 与 Zhu 2005、Borgelt 2005 的三篇文献。挖掘从 header table 底部向上逐项进行每遇到一个节点就计数支持度、构造前缀项集、构建局部条件 FP-Tree 并递归挖掘对应grow系列方法。测试 FPGrowthTest.java 验证了 10 事务数据集在minSupport 3时恰好得到 8 个频繁项集且各结果的支持度与项集大小均符合预期单路径树单条 4 项事务时得到 2⁴−1 15 个频繁项集见 FPGrowthTest.java。6) 挖掘关联规则ARM类smile.association.ARM6.1 置信度阈值FPTree tree FPTree.of(3, transactions); // 所有 confidence 0.5 的规则 StreamAssociationRule rules ARM.apply(0.5, tree); rules.forEach(System.out::println); // AssociationRule([3] [2], support60.0%, confidence75.0%, lift1.07, leverage0.040)AssociationRule是不可变record见 AssociationRule.javarecord AssociationRule(int[] antecedent, int[] consequent, double support, double confidence, double lift, double leverage) { ... }常用的挖掘后过滤组合// Confidence 1.0确定性规则 ARM.apply(1.0, tree) // 生成全部规则confidence 0.0 ARM.apply(0.0, tree) // 过滤出正相关且有意义的规则 ARM.apply(0.5, tree) .filter(r - r.lift() 1.1 r.leverage() 0.01) .forEach(System.out::println);底层原理补充ARM.apply首先基于 FP-Tree 构建一棵TotalSupportTreeT-tree参考 Coenen、Leng 与 Ahmed 2004 的 T-Trees and P-Trees 论文T-tree 是一种压缩的集枚举树能以节省存储的方式支持规则生成中的支持度查询见 TotalSupportTree.java。随后规则生成对每个频繁项集枚举其幂集的非平凡子集作为前件剩余部分作为后件再依据置信度阈值过滤见 ARM.java 的generate方法。lift 与 leverage 在 ARM.java 中按公式实时计算lift support / (antecedentSupport * consequentSupport / size)leverage supp − (antecedentSupport/size) × (consequentSupport/size)。测试 ARMTest.java 验证了minSupport3, confidence0.5时共生成 9 条规则首条即{3} ⇒ {2}confidence1.0时返回的每条规则置信度都严格等于 1.0见 ARMTest.javaconfidence0生成的规则数不少于任何更高阈值见 ARMTest.java。6.2 输入校验ARM.apply校验confidence必须在[0, 1]ARM.apply(-0.1, tree); // 抛出 IllegalArgumentException ARM.apply(1.1, tree); // 抛出 IllegalArgumentException校验代码位于 ARM.java测试见 ARMTest.java。7) 解读规则指标给定事务库N条事务上的规则X ⇒ Y四大指标的定义与含义如下指标公式解读supportcount(X ∪ Y) / N同时包含 X 与 Y 的事务占比confidencecount(X ∪ Y) / count(X)对P(Y | X)的估计liftsupport / (supp(X) · supp(Y)) 1正相关 1独立 1负相关leveragesupport − supp(X) · supp(Y)相对独立性的绝对增益示例—— 10 条事务数据集上的规则{3} ⇒ {2}量值count({3})8 →supp({3}) 0.8count({2})7 →supp({2}) 0.7count({3,2})6 →support 0.6confidence6/8 0.75lift0.6 / (0.8 × 0.7) ≈ 1.071leverage0.6 − 0.8 × 0.7 0.04该数值组合lift ≈ 1.071 1、leverage 0.04 0说明{3}与{2}存在轻微的正相关。测试 ARMTest.java 对这套手算数值做了逐一断言。关于equals/hashCode的说明两个AssociationRule对象在前件、后件、support、confidence 相同时判等。lift与leverage是派生指标有意被排除在相等性比较之外见 AssociationRule.java因此两条代表同一统计关系的规则无论派生指标浮点舍入如何都判等。测试 ARMTest.java 验证了 lift、leverage 不同而其余字段相同的规则equals为真confidence 不同的规则判等为假。8) 端到端示例8.1 内存事务import smile.association.*; import java.util.Arrays; public class AssociationExample { public static void main(String[] args) { int[][] tx { {1, 3}, {2}, {4}, {2, 3, 4}, {2, 3}, {2, 3}, {1, 2, 3, 4}, {1, 3}, {1, 2, 3}, {1, 2, 3} }; // 以 30% 最小支持度构建 FP-Tree FPTree tree FPTree.of(0.3, tx); System.out.println(Transactions: tree.size()); System.out.println(Min support: tree.minSupport()); // 频繁项集 System.out.println(\nFrequent item sets:); FPGrowth.apply(tree).forEach(set - System.out.printf( %s support%d%n, Arrays.toString(set.items()), set.support()) ); // 关联规则 System.out.println(\nAssociation rules (conf 0.5):); ARM.apply(0.5, tree).forEach(rule - System.out.printf( %s %s supp%.2f conf%.2f lift%.3f lev%.3f%n, Arrays.toString(rule.antecedent()), Arrays.toString(rule.consequent()), rule.support(), rule.confidence(), rule.lift(), rule.leverage()) ); } }预期输出节选Frequent item sets: [4] support3 [1] support5 [1, 3] support5 ... [3, 2] support6 [3] support8 Association rules (conf 0.5): [3] [2] supp0.60 conf0.75 lift1.071 lev0.040 [3] [1] supp0.50 conf0.63 lift1.250 lev0.100 ...8.2 Supplier 大文件挖掘当数据集放不进内存时使用SupplierStreamint[]APIimport smile.association.*; import java.nio.file.Files; import java.nio.file.Path; SupplierStreamint[] data () - Files.lines(Path.of(transactions.dat)) .map(line - Arrays.stream(line.split(\\s)) .mapToInt(Integer::parseInt) .toArray()); // supplier 内部会被调用两次 FPTree tree FPTree.of(0.003, data); // 0.3% of transactions long nSets FPGrowth.apply(tree).count(); long nRules ARM.apply(0.5, tree).count(); System.out.printf(Frequent sets: %d, Rules: %d%n, nSets, nRules);仓库测试 ItemSetTestData.java 正是以这种 supplier 方式读取测试数据文件。集成测试展示了真实规模数据上的表现pima.D38.N768.C2在minSupport20时挖出 1803 个频繁项集、ARM.apply(0.9, ...)得到 6803 条规则kosarak.dat在minSupport1500时挖出 219725 个频繁项集、在minSupport0.003且confidence0.5时得到 17954 条规则见 FPGrowthTest.java 与 ARMTest.java。8.3 按 Lift 过滤一次挖掘可能产生成千上万条规则用流操作快速收窄范围FPTree tree FPTree.of(3, transactions); ARM.apply(0.5, tree) .filter(r - r.lift() 1.1) // 只留有意义的正相关 .filter(r - r.leverage() 0.01) // 只留非平凡增益 .sorted(Comparator.comparingDouble(AssociationRule::lift).reversed()) .limit(20) .forEach(System.out::println);9) 校验与边界情况空树minSupport 过高当minSupport超过事务总数时任何条目都不频繁。FPGrowth.apply与ARM.apply均优雅地返回空流FPTree tree FPTree.of(11, tx); // 只有 10 条事务 assertEquals(0, FPGrowth.apply(tree).count()); // 正常 assertEquals(0, ARM.apply(0.5, tree).count()); // 正常对应测试见 ARMTest.java。单事务内的重复条目一条事务中多次出现的条目在索引前会被折叠支持度不会被夸大int[][] dup {{1, 1, 2}, {1, 2}, {1, 1, 1, 2}}; FPTree tree FPTree.of(2, dup); // {1} 的支持度 3{2} 3{1, 2} 3未被夸大这源于FPTree.add(int[])在排序后去重、只保留唯一条目见 FPTree.java对应测试 FPGrowthTest.java。迭代器契约FPGrowth、TotalSupportTree、ARM三个迭代器在耗尽后调用next()都会抛出NoSuchElementException与 JavaIterator契约一致实现见 FPGrowth.java、TotalSupportTree.java、ARM.java。两个对应测试 FPGrowthTest.java 与 ARMTest.java 均验证了这一行为。AssociationRule相等性equals与hashCode仅使用前件、后件、support、confidence。lift与leverage是派生值并被排除因此两条代表相同统计关系的规则不受派生指标浮点舍入影响而判等详见第 7 节。10) 性能建议建议理由使用[0, N)内的紧凑整数 ID避免头表header table中的稀疏数组开销freq()以数组计数初始容量默认 65536可由系统属性smile.arm.items调整大文件使用 supplier API两遍扫描设计避免了将全部数据载入内存优先调节minSupport支持度剪枝主导运行时间阈值越低工作量呈指数级增长立即流式过滤避免把数百万条规则物化成List百分比支持度便于移植0.01对任意规模数据集都成立绝对计数阈值与具体数据集绑定其中两遍扫描的直接证据是FPTree.of(int, Supplier)中new FPTree(minSupport, supplier.get())与tree.add(supplier.get())两次调用 supplier见 FPTree.java首遍统计单项频次并排序得到频次降序的 header table第二遍按该顺序插入前缀树add中对事务排序后调用QuickSort.sort见 FPTree.java该降序排列正是 FP-Tree 高压缩率的关键。11) API 快速参考// ── FP-Tree 构建 ────────────────────────────────────────────────────────────── FPTree.of(int minSupport, int[][] itemsets) FPTree.of(double minSupport, int[][] itemsets) // minSupport 在 (0, 1] FPTree.of(int minSupport, SupplierStreamint[] supplier) FPTree.of(double minSupport, SupplierStreamint[] supplier) int tree.size() // 事务数量 int tree.minSupport() // 生效的整数支持度阈值 // ── 频繁项集 ────────────────────────────────────────────────────────────────── StreamItemSet FPGrowth.apply(FPTree tree) // ItemSet (record) int[] items() // item ID按频次降序 int support() // 原始计数 // ── 关联规则 ────────────────────────────────────────────────────────────────── StreamAssociationRule ARM.apply(double confidence, FPTree tree) // confidence 必须在 [0, 1] // AssociationRule (record) int[] antecedent() // 前件LHSitem ID int[] consequent() // 后件RHSitem ID double support() // P(X ∪ Y) — 比例 double confidence() // P(Y | X) double lift() // 相对独立性的相关性1 为正相关 double leverage() // 相对独立性的绝对增益通过FPTree→FPGrowth→ARM三步流水线SMILE 将频繁项集挖掘与关联规则生成封装为高度可组合的 Java Stream APIminSupport控制挖掘粒度confidence控制规则强度而lift/leverage可以作为流式过滤器进一步收窄结果。无论是内存中的小型购物篮数据还是需要两遍流式扫描的千万级事务文件smile.association都提供了对应的构建入口仓库中的 测试目录 同时是验证这些 API 语义与边界行为的最佳参考。本文内容基于当前仓库 core/ASSOCIATION_RULE_MINING.md 及smile.association包源码整理SMILE 遵循 GNU GPL 协议开源。赞分享人工智能机器学习深度学习NLP大模型模型推理服务数据可视化【免费下载链接】smileStatistical Machine Intelligence Learning Engine项目地址https://gitcode.com/gh_mirrors/smi/smile点击查看免费下载相关推荐SMILE关联规则挖掘终极指南FP-growth算法与频繁项集发现技巧SMILE关联规则挖掘终极指南FP growth算法与频繁项集发现技巧 关联规则挖掘是数据挖掘领域最强大的技术之一能够从海量数据中发现隐藏的规律和模式。SM人工智能机器学习深度学习NLP大模型模型推理服务数据可视化Apache Spark 频繁模式挖掘实战指南FP-Growth 关联规则与 PrefixSpan 序列模式Apache Spark 频繁模式挖掘实战指南FP Growth 关联规则与 PrefixSpan 序列模式 频繁模式挖掘Frequent Pattern大数据数据分析批处理流处理机器学习图计算抖音无水印批量下载实操教程douyin-downloader 完整上手指南抖音无水印批量下载实操教程douyin downloader 完整上手指南 想把某个博主的主页作品无水印全部存下来还能一条命令搞定douyin downl网页爬虫CLI上一篇使用React签名画布库react-signature-canvas完全指南下一篇sig与stern集成Kubernetes日志实时搜索的终极工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询