Apriori算法初使用
来源:互联网 发布:电气控制柜的设计软件 编辑:程序博客网 时间:2024/06/03 16:14
Apriori算法初使用
给定某超市购物篮数据库文件basketdata.xls,里面有18项商品的747条购买记录。取支持度阈值s =185,利用A-Priori算法提取其中的最大频繁项集Lk。
数据如下:
每一行为一个购物篮数据。
1、数据读入
首先我们要定义一个数据集合类,将xls中的数据解析并读入内存
package com.cjq.Apriori;import java.io.File;import java.io.FileInputStream;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;//如下是解析xls文件所用到的一些包import org.apache.poi.hssf.usermodel.HSSFCell;import org.apache.poi.hssf.usermodel.HSSFRow;import org.apache.poi.hssf.usermodel.HSSFSheet;import org.apache.poi.hssf.usermodel.HSSFWorkbook;import org.apache.poi.poifs.filesystem.POIFSFileSystem;public class BasketData extends ArrayList<BasketItems>{ public BasketData(){ super(); initData(); //初始化数据 } /** * 从Excel文件中读取数据 */ private void initData(){ File file = null; POIFSFileSystem poifsFileSystem = null; HSSFWorkbook hssfWorkbook = null; try{ file = new File("...\\basketdata.xls");//文件路径 poifsFileSystem = new POIFSFileSystem(new FileInputStream(file)); hssfWorkbook = new HSSFWorkbook(poifsFileSystem); }catch(Exception ex){ System.err.println("文件读取出错"); System.exit(1); } HSSFSheet hssfSheet = hssfWorkbook.getSheetAt(0); int rowstart = hssfSheet.getFirstRowNum(); int rowEnd = hssfSheet.getLastRowNum(); HSSFRow row; HSSFCell cell; BasketItems temp; for (int i = 2; i <= rowEnd; i++) { row = hssfSheet.getRow(i); if (null == row) continue; int cellStart = row.getFirstCellNum(); int cellEnd = row.getLastCellNum(); temp = new BasketItems(); for (int k = 1; k <= cellEnd; k++) { cell = row.getCell(k); if (null == cell) continue; temp.addCommodityByOrder(cell.getStringCellValue()); } add(temp); } }}/** * @author 15656 * 每条购物篮的信息 */class BasketItems { private boolean[] basketList = new boolean[18]; //每个购物篮最多18中物品 private int index = 0; //购物信息逐个读入 public void addCommodityByOrder(String isExist) { if ("T".equals(isExist)) basketList[index++] = true; else basketList[index++] = false; } public boolean isExist(int index){ return basketList[index]; } public String toString(){ StringBuffer str = new StringBuffer(); for(boolean b:basketList) str.append(b+"\t"); return "\n["+str.toString()+"]"; }}
测试:
import static org.junit.Assert.*;import org.junit.Before;import org.junit.Test;public class BasketDataTest { @Test public void testBasketData() { System.out.println(new BasketData()); }}
现在读入数据已经完成。
2、Apriori算法的编写
(1)apriori算法的流程图
首先生成候选一项集,利用阈值筛选出频繁一项集;将由频繁一项集通过组合生成候选二项集,再利用阈值筛选出频繁二项集;以此类推,直至无候选集产生或者无频繁项集产生,算法结束,最后得到的频繁项集则为最大频繁项集。
apriori算法代码如下:
//阈值 private static int threshold = 185; //购物篮集合 private static BasketData basketData = new BasketData(); /** * 获取最大的频繁项集 * @param _basketData 购物篮集合 * @param itemsCount 购物篮物品种类数 * @return frequesntItems 最大的频繁项集 */ public static List getMaxFrequentItems(BasketData _basketData,int itemsCount){ basketData = _basketData; List<List<Integer>> candidateItems = new ArrayList(); List<List<Integer>> frequesntItems = null; List<Integer> temp; //初始化一项集 for(int i = 1;i<=itemsCount;i++){ temp = new ArrayList(); temp.add(i); candidateItems .add(temp); } //apriori算法开始,最大频繁项集项数不大于物品种类数 for(int i = 1;i<=itemsCount;i++){ frequesntItems = getFrequentItems(candidateItems); //筛选出频繁k项集 if(frequesntItems == null) break; System.out.println("*******生成频繁项集********"); info(frequesntItems); candidateItems = getGroupItems(frequesntItems); //组合成候选k+1项集 if(candidateItems == null) break; System.out.println("*******生成候选集********"); info(candidateItems ); } return frequesntItems; } //控制台打印项集 private static void info(List<List<Integer>> list){ if(list == null) return; for(List<Integer> i:list) System.out.println(i); }
注意:
频繁项集、候选项集的类型。Integer代表物品的序号,用一个list的来放物品的序号代表一个k项,外面的list代表k项集。
getFrequentItems函数,通过阈值从候选k项集中筛选出频繁k项集,代码如下:
/** * 从候选集中生成频繁项集 * @param FrequentItems * @return */ private static List<List<Integer>> getFrequentItems(List<List<Integer>> candidateItems){ if(candidateItems == null) return null; List<List<Integer>> FrequesntItems = new ArrayList(); List<Integer> items; for(int i = 0 ;i<candidateItems.size();i++){ items = candidateItems.get(i); if(isFrequentItems(items)) FrequesntItems.add(items); } return FrequesntItems; } /** * 判断一个项集是否为频繁项集 * @param basketData * @param items * @return */ private static boolean isFrequentItems(List<Integer> items){ int count = itemsAppearCount(items); if(count>=threshold) return true; else return false; } /** * 计算某项集出现的次数 * @param basketData * @param items * @return */ public static int itemsAppearCount(List<Integer> items){ if(basketData==null||items==null) return 0; int count = 0; int size = basketData.size(); int j; BasketItems basketItems; boolean tag = true; for(int i = 0;i<size;i++){ basketItems = basketData.get(i); for(j = 0;j<items.size();j++){ if(!basketItems.isExist(items.get(j)-1)){ tag = false; break; } } if(tag){ count++; }else tag = true; } return count; }
getGroupItems函数,将频繁k项集组合成候选k+1项集,代码如下:
/** * 生成k+1候选集 * @param FrequentItems k项频繁项集 * @return allgroupItems k+1候选集 */ private static List<List<Integer>> getGroupItems(List<List<Integer>> FrequentItems){ if(FrequentItems == null) return null; int size = FrequentItems.size(); if(size < 2) return null; List<List<Integer>> allgroupItems = new ArrayList(); List<Integer> groupItem = null; for(int i = 0;i<size-1;i++){ for(int j = i+1;j<size;j++){ groupItem = combin(FrequentItems.get(i),FrequentItems.get(j)); if(groupItem!=null&&judgeSubsetIsExits(groupItem,FrequentItems)) allgroupItems.add(groupItem); } } if(allgroupItems.size()==0) return null; return allgroupItems; } /** * 两个k项集合并为k+1项集 * @param item1 * @param item2 * @return groupItem */ private static List<Integer> combin(List<Integer> item1,List<Integer> item2){ int size1 = item1.size(); int size2 = item2.size(); if(size1!=size2) return null; List<Integer> groupItem = new ArrayList(); int temp = 0; for(int i = 0;i<size1-1;i++){ temp = item1.get(i); if(temp!=item2.get(i)) return null; else groupItem.add(temp); } groupItem.add(item1.get(size1-1)); groupItem.add(item2.get(size2-1)); return groupItem; } /** * 判断k+1项集的所有k项子集是否存在 * @param groupItem k+1项集 * @param FrequentItems k项集集合 * @return result */ private static boolean judgeSubsetIsExits(List<Integer> groupItem,List<List<Integer>> FrequentItems){ if(groupItem == null) return true; int size = groupItem.size(); List<Integer> subset = null; for(int i = 0;i<size;i++){ subset = new ArrayList(); for(int j = 0;j<size;j++){ if(j!=i) subset.add(groupItem.get(j)); } if(!itemIsExitsInFrequentItems(subset,FrequentItems)) return false; } return true; } /** * 判断一个项集是否在一个项集集合里 * @param groupItem * @param FrequentItems * @return result */ private static boolean itemIsExitsInFrequentItems(List<Integer> groupItem,List<List<Integer>> FrequentItems){ int size = groupItem.size(); int j = 0; List<Integer> temp = null; boolean tag = true; for(int i = 0;i<FrequentItems.size();i++){ temp = FrequentItems.get(i); tag = true; for(j=0;j<size;j++){ if(!temp.get(j).equals(groupItem.get(j))){ tag = false; break; } } if(tag) return true; } return false; }
组合原则:
两个具有相同的k-1项的k项集才能组合成k+1项集,再由定理:频繁k+1项集的所有k项子集都是频繁项集。由这两个原则,先将具有相同的k-1项的k项集组合成k+1项集,再找出这个k+1项集的所有k项子集,判断这些k项子集是否都是频繁项集,如果都是,则将这个k+1项集加入候选集中,如果不是则去掉。
现在,已经完成了一个简单的Apriori算法。
下面进行测试:
package com.cjq.Apriori;import java.util.ArrayList;import java.util.List;import junit.framework.TestCase;public class Test extends TestCase { @org.junit.Test public void testBasketData() { List<List<Integer>> FrequesntItems = APriori.getMaxFrequentItems(new BasketData(),18); System.out.println("\n最大频繁项集"); System.out.println(FrequesntItems); }}
运行结果:
*生成频繁项集**
[1]
[2]
[5]
[9]
[10]
[12]
[13]
[15]
[16]
[17]
*生成候选集**
[1, 2]
[1, 5]
[1, 9]
[1, 10]
[1, 12]
[1, 13]
[1, 15]
[1, 16]
[1, 17]
[2, 5]
[2, 9]
[2, 10]
[2, 12]
[2, 13]
[2, 15]
[2, 16]
[2, 17]
[5, 9]
[5, 10]
[5, 12]
[5, 13]
[5, 15]
[5, 16]
[5, 17]
[9, 10]
[9, 12]
[9, 13]
[9, 15]
[9, 16]
[9, 17]
[10, 12]
[10, 13]
[10, 15]
[10, 16]
[10, 17]
[12, 13]
[12, 15]
[12, 16]
[12, 17]
[13, 15]
[13, 16]
[13, 17]
[15, 16]
[15, 17]
[16, 17]
*生成频繁项集**
[1, 2]
[1, 5]
[1, 9]
[1, 10]
[1, 13]
[1, 15]
[1, 16]
[1, 17]
[5, 16]
[9, 16]
[10, 16]
[15, 16]
*生成候选集**
[1, 5, 16]
[1, 9, 16]
[1, 10, 16]
[1, 15, 16]
*生成频繁项集**
[1, 10, 16]
[1, 15, 16]
最大频繁项集
[[1, 10, 16], [1, 15, 16]]
经校验:结果正确。
- Apriori算法初使用
- 使用Apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- 使用apriori算法进行关联分析
- 使用Apriori算法进行关联分析
- Apriori算法
- Apriori算法
- Apriori算法
- apriori 算法
- Apriori算法
- Apriori算法
- Apriori算法
- Apriori算法
- Git基础操作
- Docker学习笔记 — Docker与LXC的区别
- socket阻塞与非阻塞,同步与异步、I/O模型------非常值得一看!
- ZYNQ系统中实现FAT32文件系统的SD卡读写之四 经验总结
- 最新100个微信小程序
- Apriori算法初使用
- 【大数据部落】用R挖掘Twitter数据
- Android应用程序访问linux驱动第三步:实现并向系统注册Service
- 微信小程序推荐大全之101~200个
- CentOS 7 安装Kubernetes(1)--手动部署节点
- arm汇编程序调用C函数之参数传递
- 一分钟了解“Matlab的squeeze函数”
- Javascript引擎内部的三种抽象操作
- 正向代理与反向代理、负载均衡