数据挖掘-关联分析频繁模式挖掘Apriori、FP-Growth及Eclat算法的JAVA及C++实现

本文介绍了数据挖掘中的关联分析,重点讲解了Apriori、FP-Growth和Eclat三种频繁模式挖掘算法,并提供了这些算法在Java和C++语言中的实现。Apriori算法虽然效率较低,但作为入门算法,有助于理解关联分析的基本原理。
摘要由CSDN通过智能技术生成

(update 2012.12.28 关于本项目下载及运行的常见问题 FAQ见 newsgroup18828文本分类器、文本聚类器、关联分析频繁模式挖掘算法的Java实现工程下载及运行FAQ )

一、Apriori算法

       Apriori是非常经典的关联分析频繁模式挖掘算法,其思想简明,实现方便,只是效率很低,可以作为频繁模式挖掘的入门算法。其主要特点是

       1、k-1项集连接规律:若有两个k-1项集,每个项集保证有序,如果两个k-1项集的前k- 2个项相同,而最后一个项不同,则证明它们是可连接的,可连接生成k项集。
       2、反单调性。如果一个项集是频繁的,那么它的所有子集都是频繁的。即若一个项集的 子集不是频繁项集,则该项集肯定也不是频繁项集。
       主要算法流程:
      1. 扫描数据库,生成候选1项集和频繁1项集。
      2. 从2项集开始循环,由频繁k-1项集生成频繁频繁k项集。
      2.1  频繁k-1项集两两组合,判定是否可以连接,若能则连接生成k项集。
      2.2  对k项集中的每个项集检测其子集是否频繁,舍弃掉子集不是频繁项集即   不在频繁k-1项集中的项集。
      2.3  扫描数据库,计算2.3步中过滤后的k项集的支持度,舍弃掉支持度小于阈值的项集,生成频繁k项集。
      3.  若当前k项集中只有一个项集时循环结束。
      伪代码如下:

    JAVA实现代码
package com.pku.yangliu;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

/**频繁模式挖掘算法Apriori实现
 *
 */

public class AprioriFPMining {
	private int minSup;//最小支持度
	private static List<Set<String>> dataTrans;//以List<Set<String>>格式保存的事物数据库,利用Set的有序性
	
	public int getMinSup() {
		return minSup;
	}
	
	public void setMinSup(int minSup) {
		this.minSup = minSup;
	}
	
	/**
	 * @param args
	 */
	 public static void main(String[] args) throws IOException { 
		AprioriFPMining apriori = new AprioriFPMining();
		double [] threshold = {0.25, 0.20, 0.15, 0.10, 0.05};
		String srcFile = "F:/DataMiningSample/FPmining/Mushroom.dat";
		String shortFileName = srcFile.split("/")[3];
        String targetFile = "F:/DataMiningSample/FPmining/" + shortFileName.substring(0, shortFileName.indexOf("."))+"_fp_threshold";
		dataTrans = apriori.readTrans(srcFile);
		for(int k = 0; k < threshold.length; k++){
			System.out.println(srcFile + " threshold: " + threshold[k]);
			long totalItem = 0;
			long totalTime = 0;
			FileWriter tgFileWriter = new FileWriter(targetFile + (threshold[k]*100));
			apriori.setMinSup((int)(dataTrans.size() * threshold[k]));//原始蘑菇的数据0.25只需要67秒跑出结果
			long startTime = System.currentTimeMillis();
			Map<String, Integer> f1Set = apriori.findFP1Items(dataTrans);
			long endTime = System.currentTimeMillis();
			totalTime += endTime - startTime;
			//频繁1项集信息得加入支持度
			Map<Set<String>, Integer> f1Map = new HashMap<Set<String>, Integer>();
			for(Map.Entry<String, Integer> f1Item : f1Set.entrySet()){
				Set<String> fs = new HashSet<String>();
				fs.add(f1Item.getKey());
				f1Map.put(fs, f1Item.getValue());
			}
			
			totalItem += apriori.printMap(f1Map, tgFileWriter);
			Map<Set<String>, Integer> result = f1Map;
			do {	
				startTime = System.currentTimeMillis();
				result = apriori.genNextKItem(result);
				endTime = System.currentTimeMillis();
				totalTime += endTime - startTime;
				totalItem += apriori.printMap(result, tgFileWriter);
			} while(result.size() != 0);
			tgFileWriter.close();
			System.out.println("共用时:" + totalTime + "ms");
			System.out.println("共有" + totalItem + "项频繁模式");
		}
	}

	 /**由频繁K-1项集生成频繁K项集
	 * @param preMap 保存频繁K项集的map
	 * @param tgFileWriter 输出文件句柄
	 * @return int 频繁i项集的数目
	 * @throws IOException 
	 */
	private Map<Set<String>, Integer> genNextKItem(Map<Set<String>, Integer> preMap) {
		// TODO Auto-generated method stub
		Map<Set<String>, Integer> result = new HashMap<Set<String>, Integer>();
		//遍历两个k-1项集生成k项集
		List<Set<String>> preSetArray = new ArrayList<Set<String>>();
		for(Map.Entry<Set<String>, Integer> preMapItem : preMap.entrySet()){
			preSetArray.add(preMapItem.getKey());
		}
		int preSetLength = preSetArray.size();
		for (int i = 0; i < preSetLength - 1; i++) {
			for (int j = i + 1; j < preSetLength; j++) {
				String[] strA1 = preSetArray.get(i).toArray(new String[0]);
				String[] strA2 = preSetArray.get(j).toArray(new String[0]);
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值