使用Apriori算法进行关联分析

目录

1.名词概念
2.频繁项集发现
3.Apriori算法关联分析
4.代码实现
5.参考文章

  通过组合交叉变量制定风控策略时有两种方法:一是通过决策树分箱进行变量交叉,可以见文章一个函数实现自动化风控策略挖掘;二是通过apriori算法进行关联分析。
  关联分析是从大规模数据集中寻找物品间的隐含关系,比如著名的例子“啤酒和尿布”,即发现买啤酒的顾客同时也会买尿布,商店通过挖掘这些规则更加了解客户的购买行为。但是,关联分析需要从大量数据集中寻找组合关系,计算代价很高,于是Aprior算法就应用于用合理的算法高效发掘组合规则(又叫频繁项集)。

  假设一个简单的交易清单如下,分别代表5笔交易情况。

  下面是关联分析中用到的一些名词概念。
1.项与项集
  项,指我们分析数据中的一个对象,如豆奶;项集,就是若干项的项构成的集合,如集合{豆奶,莴苣}是一个2项集。

2.支持度
  某项集在数据集中出现的概率。即项集在记录中出现的次数,除以数据集中所有记录的数量。如豆奶的支持度为4/5,{豆奶,尿布}的支持度为3/5。
  支持度体现的是某项集的频繁程度,只有某项集的支持度达到一定程度,我们才有研究该项集的必要。

3.置信度
  又叫可信度,是针对一条关联规则定义的。关联规则{A->B}的置信度为A与B同时出现的次数,除以A出现的次数。即在A发生的条件下,B发生的概率。
  比如{尿布->葡萄酒}=支持度(尿布->葡萄酒)/支持度(尿布)=3/5除以4/5=0.75。即在购买尿布的情况下,有75%的概率会购买葡萄酒。

4.提升度
  关联规则{A->B}中,提升度是指{A->B}的置信度,除以B的支持度。提升度体现的是组合(应用关联规则)相对不组合(不应用关联规则)的比值,如果提升度大于1,则说明应用该关联规则是有价值的。如果提升度小于1,说明应用该关联规则起到了负面影响。
  比如{尿布->葡萄酒}=置信度(尿布->葡萄酒)/支持度(葡萄酒)=0.75/0.6=1.25

寻找频繁项集

  一般支持度和置信度是用来量化关联分析是否成功的方法。比如对只有4个物品的集合{0,1,2,3},想要获得每种可能集合的支持度。首先,需要列出4个物品可能的组合数,一共有15种组合方法。

  比如需要计算{0,3}项集的支持度,就需要遍历每条记录,检查记录是否包含0和3,如果包含则计数值加1。如此便可以得到{0,3}项集的支持度,要获得每种可能集合的支持度需要重复上述过程。
  对于N种物品的数据集一共有 2 N − 1 2^N-1 2N1种项集组合,计算量巨大。为了降低计算所需的时间,可以采用Apriori来发现频繁项集。

Apriori算法原理

  Apriori在拉丁语中指“来自以前”,即先验知识或者假设条件。它的原理是如果某个项集是频繁的,那么它的所有子集也是频繁的。
  如上图中,如果{0,1}是频繁的,那么{0}、{1}也一定是频繁的。因为{0}、{1}的支持度一定大于或等于{0,1}。反过来,如果某一个项集是非频繁项集,那么它的所有超集也是非频繁的。如下图:

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Apriori算法是一种基于频繁项集的关联规则挖掘算法,它可以用来发现事物之间的相关性,并且在市场营销、销售预测、商品推荐等领域都有广泛的应用。 Java中实现Apriori算法主要分为以下步骤: 1. 数据预处理:将原始数据转化为事务集合形式,每个事务包含多个项,项之间用逗号或其他符号分隔。 2. 建立候选项集:根据用户设定的最小支持度阈值,生成大小为1的候选项集。 3. 频繁项集生成:根据候选项集和事务数据集,计算每个项集的支持度,并根据最小支持度阈值筛选出频繁项集。 4. 关联规则挖掘:根据频繁项集,生成关联规则,并计算每个规则的置信度和支持度。 以下是一个简单的Java代码实现: ``` public class Apriori { // 计算候选项集 public static List<Set<String>> candidateSet(List<Set<String>> frequentItemSets) { List<Set<String>> candidateSets = new ArrayList<>(); for (int i = 0; i < frequentItemSets.size(); i++) { for (int j = i + 1; j < frequentItemSets.size(); j++) { Set<String> set1 = frequentItemSets.get(i); Set<String> set2 = frequentItemSets.get(j); // 求并集 Set<String> candidateSet = new HashSet<>(set1); candidateSet.addAll(set2); if (candidateSet.size() == set1.size() + 1) { candidateSets.add(candidateSet); } } } return candidateSets; } // 计算支持度 public static int supportCount(List<Set<String>> transactions, Set<String> itemSet) { int count = 0; for (Set<String> transaction : transactions) { if (transaction.containsAll(itemSet)) { count++; } } return count; } // 计算频繁项集 public static List<Set<String>> frequentItemSet(List<Set<String>> transactions, double minSupport) { List<Set<String>> frequentItemSets = new ArrayList<>(); Map<Set<String>, Integer> itemSetCount = new HashMap<>(); // 统计每个项集的支持度计数 for (Set<String> transaction : transactions) { for (String item : transaction) { Set<String> itemSet = new HashSet<>(); itemSet.add(item); if (itemSetCount.containsKey(itemSet)) { itemSetCount.put(itemSet, itemSetCount.get(itemSet) + 1); } else { itemSetCount.put(itemSet, 1); } } } // 获得频繁项集 for (Set<String> itemSet : itemSetCount.keySet()) { double support = (double) itemSetCount.get(itemSet) / transactions.size(); if (support >= minSupport) { frequentItemSets.add(itemSet); } } // 迭代计算频繁项集 List<Set<String>> lastItemSets = frequentItemSets; while (!lastItemSets.isEmpty()) { List<Set<String>> candidateSets = candidateSet(lastItemSets); itemSetCount.clear(); for (Set<String> transaction : transactions) { for (Set<String> candidateSet : candidateSets) { if (transaction.containsAll(candidateSet)) { if (itemSetCount.containsKey(candidateSet)) { itemSetCount.put(candidateSet, itemSetCount.get(candidateSet) + 1); } else { itemSetCount.put(candidateSet, 1); } } } } lastItemSets = new ArrayList<>(); for (Set<String> itemSet : itemSetCount.keySet()) { double support = (double) itemSetCount.get(itemSet) / transactions.size(); if (support >= minSupport) { frequentItemSets.add(itemSet); lastItemSets.add(itemSet); } } } return frequentItemSets; } // 计算关联规则 public static List<Rule> associationRules(List<Set<String>> transactions, double minSupport, double minConfidence) { List<Rule> rules = new ArrayList<>(); List<Set<String>> frequentItemSets = frequentItemSet(transactions, minSupport); for (Set<String> frequentItemSet : frequentItemSets) { if (frequentItemSet.size() > 1) { List<Set<String>> subSets = getSubSets(frequentItemSet); for (Set<String> subSet : subSets) { Set<String> complementSet = new HashSet<>(frequentItemSet); complementSet.removeAll(subSet); double confidence = (double) supportCount(transactions, frequentItemSet) / supportCount(transactions, subSet); if (confidence >= minConfidence) { rules.add(new Rule(subSet, complementSet, confidence)); } } } } return rules; } // 获取所有子集 public static List<Set<String>> getSubSets(Set<String> itemSet) { List<Set<String>> subSets = new ArrayList<>(); if (itemSet.isEmpty()) { subSets.add(itemSet); } else { List<Set<String>> subSetsWithoutFirst = getSubSets(itemSet.stream().skip(1).collect(Collectors.toSet())); subSets.addAll(subSetsWithoutFirst); subSetsWithoutFirst.forEach(subSet -> { Set<String> subSetWithFirst = new HashSet<>(subSet); subSetWithFirst.add(itemSet.iterator().next()); subSets.add(subSetWithFirst); }); } return subSets; } // 关联规则类 public static class Rule { private Set<String> antecedent; private Set<String> consequent; private double confidence; public Rule(Set<String> antecedent, Set<String> consequent, double confidence) { this.antecedent = antecedent; this.consequent = consequent; this.confidence = confidence; } public Set<String> getAntecedent() { return antecedent; } public Set<String> getConsequent() { return consequent; } public double getConfidence() { return confidence; } @Override public String toString() { return antecedent + " => " + consequent + " (confidence: " + confidence + ")"; } } public static void main(String[] args) { List<Set<String>> transactions = new ArrayList<>(); transactions.add(new HashSet<>(Arrays.asList("A", "B", "C"))); transactions.add(new HashSet<>(Arrays.asList("A", "C", "D", "E"))); transactions.add(new HashSet<>(Arrays.asList("A", "C", "E", "F"))); transactions.add(new HashSet<>(Arrays.asList("B", "C", "E"))); transactions.add(new HashSet<>(Arrays.asList("B", "D", "E", "F"))); double minSupport = 0.4; double minConfidence = 0.7; List<Rule> rules = associationRules(transactions, minSupport, minConfidence); rules.forEach(System.out::println); } } ``` 以上代码实现了Apriori算法中的候选项集计算、支持度计算、频繁项集计算和关联规则挖掘等步骤。你可以根据自己的需求进行调整和修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值