算法描述

(1)扫描全部数据,产生候选1-项集的集合C1;
(2)根据最小支持度,由候选1-项集的集合C1产生频繁1-项集的集合L1;
(3)对k>1,重复执行步骤(4)、(5)、(6);
(4)由Lk执行连接和剪枝操作,产生候选(k+l)-项集的集合Ck+1;
(5)根据最小支持度,由候选(k+l)-项集的集合Ck+1,产生频繁(k+1)-项集的集合Lk+1;
(6)若L≠Φ,则k=k+1,跳往步骤(4);否则,跳往步骤(7);
(7)根据最小置信度,由频繁项集产生强关联规则,结束。

代码

public class Apriori2
{private final static int SUPPORT = 8; // 支持度阈值private final static double CONFIDENCE = 0.6; // 置信度阈值private final static String ITEM_SPLIT = " "; // 项之间的分隔符private final static String CON = "->"; // 项之间的分隔符/*** 算法主程序* @param dataList* @return Map<String, Integer>*/public Map<String, Integer> apriori(ArrayList<String> dataList){Map<String, Integer> stepFrequentSetMap = new HashMap<>(findFrequentOneSets(dataList));//找出候选// 1-项集//频繁项集Map<String, Integer> frequentSetMap = new HashMap<String, Integer>(stepFrequentSetMap);while(stepFrequentSetMap.size() > 0)//上一步的频繁项集不为空{Map<String, Integer> candidateSetMap = aprioriGen(stepFrequentSetMap);//生成候选集Set<String> candidateKeySet = candidateSetMap.keySet();//扫描D,进行计数,计算候选集的支持度计数for(String data:dataList){for(String candidate:candidateKeySet){boolean flag = true;String[] strings = candidate.split(ITEM_SPLIT);for(String string:strings){if(!data.contains(string + ITEM_SPLIT))//找不出候选项集中的元素,退出{flag = false;break;}}if(flag)candidateSetMap.put(candidate, candidateSetMap.get(candidate)+1);//支持度加一}}//从候选集中找到符合支持度的频繁项集stepFrequentSetMap.clear();for(String candidate:candidateKeySet){Integer count = candidateSetMap.get(candidate);if(count>=SUPPORT)stepFrequentSetMap.put(candidate, count);}// 合并所有频繁集frequentSetMap.putAll(stepFrequentSetMap);}return frequentSetMap;}/*** 找出候选K-项集* @param dataList* @return Map<String, Integer>*/private Map<String, Integer> findFrequentOneSets(ArrayList<String> dataList){Map<String, Integer> resultSetMap = new HashMap<>();for(String data:dataList){String[] strings = data.split(ITEM_SPLIT);for(String string:strings){string += ITEM_SPLIT;if(resultSetMap.get(string)==null){resultSetMap.put(string, 1);}else {resultSetMap.put(string, resultSetMap.get(string)+1);}}}return resultSetMap;}/*** 根据上一步的频繁项集的集合选出候选集* @param setMap* @return*/private Map<String, Integer> aprioriGen(Map<String, Integer> setMap){Map<String, Integer> candidateSetMap = new HashMap<>();Set<String> candidateSet = setMap.keySet();for(String s1:candidateSet){String[] strings1 = s1.split(ITEM_SPLIT);String s1String = "";for(String temp:strings1)s1String += temp+ITEM_SPLIT;for(String s2:candidateSet){String[] strings2 = s2.split(ITEM_SPLIT);boolean flag = true;for(int i=0;i<strings1.length-1;i++){if(strings1[i].compareTo(strings2[i])!=0)//存在不同元素,不能连接{flag = false;break;}}if(flag && strings1[strings1.length-1].compareTo(strings2[strings1.length-1])<0){//连接步:产生候选String c = s1String+strings2[strings2.length-1]+ITEM_SPLIT;if(hasInfrequentSubset(c, setMap)){//剪枝步:删除非频繁的候选}else {candidateSetMap.put(c, 0);}}}}return candidateSetMap;}/*** 使用先验知识,判断候选集是否是频繁项集* @param candidateSet* @param setMap* @return boolean*/private boolean hasInfrequentSubset(String candidateSet, Map<String, Integer> setMap){String[] strings = candidateSet.split(ITEM_SPLIT);//候选集//找出候选集所有的子集,并判断每个子集是否属于频繁子集for(int i=0;i<strings.length;i++){String subString = "";for(int j=0;j<strings.length;j++)//遍历所有子集{if(j!=i){subString += strings[j]+ITEM_SPLIT;}}if(setMap.get(subString)==null)return true;}return false;}/*** 由频繁项集产生关联规则* @param frequentSetMap* @return*/public Map<String, Double> getRelationRules(Map<String, Integer> frequentSetMap){Map<String, Double> relationsMap = new HashMap<>();Set<String> keySet = frequentSetMap.keySet();for(String key:keySet)//遍历所有频繁项集{List<String> keySubset = subset(key);//频繁项的所有子集for(String keySubsetItem:keySubset)//遍历所有子集{//子集keySubsetItem也是频繁项Integer count = frequentSetMap.get(keySubsetItem);if(count!=null)//计算置信度{Double confidence = (1.0*frequentSetMap.get(key))/(1.0*frequentSetMap.get(keySubsetItem));if(confidence>CONFIDENCE)relationsMap.put(keySubsetItem+CON+expect(key, keySubsetItem), confidence);}}}return relationsMap;}/*** 求一个集合所有的非空真子集** @param sourceSet* @return* 为了以后可以用在其他地方,这里我们不是用递归的方法** 参考:http://blog.163.com/xiaohui_1123@126/blog/static/3980524020109784356915/* 思路:假设集合S(A,B,C,D),其大小为4,拥有2的4次方个子集,即0-15,二进制表示为0000,0001,...,1111。* 对应的子集为空集,{D},...,{A,B,C,D}。*/private List<String> subset(String sourceSet){List<String> result = new ArrayList<>();String[] strings = sourceSet.split(ITEM_SPLIT);//非空真子集for(int i=1;i<(int)(Math.pow(2, strings.length))-1;i++){String item = "";String flag = "";int ii=i;do{flag += ""+ii%2;ii = ii/2;} while (ii>0);for(int j=flag.length()-1;j>=0;j--){if(flag.charAt(j)=='1'){item = strings[j]+ITEM_SPLIT+item;}}result.add(item);}return result;}/*** 集合运算,A/B* @param A* @param B* @return*/private String expect(String stringA,String stringB){String result = "";String[] stringAs = stringA.split(ITEM_SPLIT);String[] stringBs = stringB.split(ITEM_SPLIT);for(int i=0;i<stringAs.length;i++){boolean flag = true;for(int j=0;j<stringBs.length;j++){if(stringAs[i].compareTo(stringBs[j])==0){flag = false;break;}}if(flag)result += stringAs[i]+ITEM_SPLIT;}return result;}public static void readTxt(String fileName){try { // 防止文件建立或读取失败,用catch捕捉错误并打印,也可以throw/* 读入TXT文件 */File filename = new File(fileName); // 要读取以上路径的input。txt文件InputStreamReader reader = new InputStreamReader(new FileInputStream(filename)); // 建立一个输入流对象readerBufferedReader br = new BufferedReader(reader); // 建立一个对象,它把文件内容转成计算机能读懂的语言String line = "";line = br.readLine();while (line != null) {dataList.add(line);line = br.readLine();}} catch (Exception e) {e.printStackTrace();}}public static ArrayList<String> dataList = new ArrayList<>();public static void main(String[] args){readTxt("test.txt");System.out.println("=数据集合==========");for(String string:dataList){System.out.println(string);}Apriori2 apriori2 = new Apriori2();System.out.println("=频繁项集==========");Map<String, Integer> frequentSetMap = apriori2.apriori(dataList);Set<String> keySet = frequentSetMap.keySet();for(String key:keySet){System.out.println(key+" : "+frequentSetMap.get(key));}System.out.println("=关联规则==========");Map<String, Double> relationRulesMap = apriori2.getRelationRules(frequentSetMap);Set<String> rrKeySet = relationRulesMap.keySet();for (String rrKey : rrKeySet){System.out.println(rrKey + "  :  " + relationRulesMap.get(rrKey));}}
}

数据挖掘—Apriori算法(Java实现)相关推荐

  1. 数据挖掘Apriori算法

    数据挖掘Apriori算法 数据挖掘(Data Mining)就是从大量的.不完全的.有噪声的.模糊的.随机的实际应用数据中,提取隐含在其中的.人们事先不知道的.但又是潜在有用的信息和知识的过程.挖掘 ...

  2. java实现频繁集_数据挖掘--频繁集测试--Apriori算法--java实现

    [ 关联规则挖掘用于寻找给定数据集中项之间的有趣的关联或相关关系. 关联规则揭示了数据项间的未知的依赖关系,根据所挖掘的关联关系,可以从� ...] 2013年11月19日注:以下算法中,combin ...

  3. java实现数据挖掘_数据挖掘Apriori算法的java实现

    对于Apriori算法,Apriori算法是一种挖掘关联规则的频繁项集算法,在很多领域中应用广泛. 它的算法思想是: 1先找到所有的小频繁项集, 2然后做连接步骤,将小频繁项集拼接作为候选集, 3然后 ...

  4. java数据挖掘算法_[转载]干货,基于Java和C++的数据挖掘Apriori算法实现

    Apriori算法实现 Apriori算法的思想还是很容易理解的,实现起来虽然麻烦,但是还是比较容易的.下面是我使用Java语言实现的Apriori算法,实现了AprioriAlgorithm 类,包 ...

  5. 低版本的Hadoop实现 Apriori 算法Java代码

    Apriori 关联规则挖掘的一种算法,其逻辑简单,网上有很多关于算法逻辑的介绍,在此不再赘述.使用hadoop实现Apriori算法的核心在于,循环计算,在Map过程对候选项进行识别,Combine ...

  6. 数据挖掘各种算法JAVA的实现方法

    数据挖掘-关联分析频繁模式挖掘Apriori.FP-Growth及Eclat算法的JAVA及C++实现: 网址:http://blog.csdn.net/yangliuy/article/detail ...

  7. Apriori算法-java

    package com.yang; import java.util.*; public class Apriori { private double minsup = 0.2;// 最小支持度    ...

  8. Apriori算法整理

    实践课题报告: Apriori算法 学 校:xxx大学 学 院:大数据与智能工程学院 专 业:信息工程(数据科学与大数据技术) 年 级:2017级 姓 名:xxx 指导老师:xxx 日 期:2019 ...

  9. apriori java_频繁模式挖掘apriori算法介绍及Java实现

    频繁模式是频繁地出如今数据集中的模式(如项集.子序列或者子结构).比如.频繁地同一时候出如今交易数据集中的商品(如牛奶和面包)的集合是频繁项集. 一些基本概念 支持度:support(A=>B) ...

最新文章

  1. android web3j 代币查询_wallet-eth 以太坊代币钱包 助记词 私钥 keystore 转账
  2. 读博难,大神来支招:DeepMind科学家Sebastian Ruder提出十条实用建议
  3. JAX-RS开发 hello world
  4. It's highly recommended that you fix the library with 'execstack -c libfile', or link it with '-z
  5. iptables_ftp
  6. 使用OctreeQuantizer提高gdi+绘图质量
  7. SCCM 2012 简体中文正式版 部署文档 01 环境说明
  8. iClock时间菜单功能设置
  9. Oracle 逗号分割的字符串转换为可放入in的语句
  10. 电子基础知识:常用电子元器件和基本工具
  11. SVN 回退到某一个版本
  12. 【BMC】Redfish简述
  13. 【C++学习笔记】标准库类型vector
  14. pc端1号店项目用JQ实现二级菜单和轮播图
  15. 小何~初次认识PIL
  16. 简易聊天室代码分享 js+socket.io
  17. Cover Letter 写作技巧
  18. 浅谈Flutter跨平台调用方式MethodChannel
  19. Lightroom 与 Lightroom Classic 的区别,有什么不同之处
  20. 干掉iTerm,号称下一代 Terminal 终端神器,用完爱不释手

热门文章

  1. STM32时钟树解析
  2. Visual Studio 编译优化选项:Debug与Release、禁止优化与O1、O2、Ox优化
  3. 深挖“窄带高清”的实现原理
  4. React JS 组件间沟通的一些方法
  5. JavaScript变量和作用域
  6. 基础拾遗------webservice详解
  7. UNIX网络编程——套接字选项(SO_RCVBUF和SO_SNDBUF)
  8. poj 2507Crossed ladders 计算几何
  9. C#编号的ActiveX控件采用CAB的布署方式实例
  10. [LeetCode]最长公共前缀(Longest Common Prefix)