java实现频繁集_数据挖掘--频繁集测试--Apriori算法--java实现
[ 關聯規則挖掘用于尋找給定數據集中項之間的有趣的關聯或相關關系。 關聯規則揭示了數據項間的未知的依賴關系,根據所挖掘的關聯關系,可以從� ...]
2013年11月19日注:以下算法中,combine算法實現不正確,應該是從已有的頻繁中來產生。需要進一步修改
=================================================================================
Apriori算法原理:
如果某個項集是頻繁的,那么它所有的子集也是頻繁的。如果一個項集是非頻繁的,那么它所有的超集也是非頻繁的。
示意圖
圖一:[頻繁模式是頻繁地出現在數據集中的模式(如項集、子序列或者子結構)。例如,頻繁地同時出現在交易數據集中的商品(如牛奶和面包)的集合是頻繁項集。]
圖二:
package cn.ffr.frequent.apriori;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Apriori的核心代碼實現
* @author neu_fufengrui@163.com
*/
public class Apriori {
public static final String STRING_SPLIT = ",";
/**
* 主要的計算方法
* @param data 數據集
* @param minSupport 最小支持度
* @param maxLoop 最大執行次數,設NULL為獲取最終結果
* @param containSet 結果中必須包含的子集
* @return
*/
public Map compute(List data, Double minSupport, Integer maxLoop, String[] containSet){
//校驗
if(data == null || data.size() <= 0){
return null;
}
//初始化
Map result = new HashMap();
Object[] itemSet = getDataUnitSet(data);
int loop = 0;
//核心循環處理過程
while(true){
//重要步驟一:合并,產生新的頻繁集
Set keys = combine(result.keySet(), itemSet);
result.clear();//移除之前的結果
for(String key : keys){
result.put(key, computeSupport(data, key.split(STRING_SPLIT)));
}
//重要步驟二:修剪,去除支持度小于條件的。
cut(result, minSupport, containSet);
loop++;
//輸出計算過程
System.out.println("loop ["+loop+"], result : "+result);
//循環結束條件
if(result.size() <= 0){
break;
}
if(maxLoop != null && maxLoop > 0 && loop >= maxLoop){//可控制循環執行次數
break;
}
}
return result;
}
/**
* 計算子集的支持度
*
* 支持度 = 子集在數據集中的數據項 / 總的數據集的數據項
*
* 數據項的意思是一條數據。
* @param data 數據集
* @param subSet 子集
* @return
*/
public Double computeSupport(List data, String[] subSet){
Integer value = 0;
for(int i = 0; i < data.size(); i++){
if(contain(data.get(i), subSet)){
value ++;
}
}
return value*1.0/data.size();
}
/**
* 獲得初始化唯一的數據集,用于初始化
* @param data
* @return
*/
public Object[] getDataUnitSet(List data){
List uniqueKeys = new ArrayList();
for(String[] dat : data){
for(String da : dat){
if(!uniqueKeys.contains(da)){
uniqueKeys.add(da);
}
}
}
return uniqueKeys.toArray();
}
/**
* 合并src和target來獲取頻繁集
* 增加頻繁集的計算維度
* @param src
* @param target
* @return
*/
public Set combine(Set src, Object[] target){
Set dest = new HashSet();
if(src == null || src.size() <= 0){
for(Object t : target){
dest.add(t.toString());
}
return dest;
}
for(String s : src){
for(Object t : target){
if(s.indexOf(t.toString())<0){
String key = s+STRING_SPLIT+t;
if(!contain(dest, key)){
dest.add(key);
}
}
}
}
return dest;
}
/**
* dest集中是否包含了key
* @param dest
* @param key
* @return
*/
public boolean contain(Set dest, String key){
for(String d : dest){
if(equal(d.split(STRING_SPLIT), key.split(STRING_SPLIT))){
return true;
}
}
return false;
}
/**
* 移除結果中,支持度小于所需要的支持度的結果。
* @param result
* @param minSupport
* @return
*/
public Map cut(Map result, Double minSupport, String[] containSet){
for(Object key : result.keySet().toArray()){//防止 java.util.ConcurrentModificationException,使用keySet().toArray()
if(minSupport != null && minSupport > 0 && minSupport < 1 && result.get(key) < minSupport){//比較支持度
result.remove(key);
}
if(containSet != null && containSet.length > 0 && !contain(key.toString().split(STRING_SPLIT), containSet)){
result.remove(key);
}
}
return result;
}
/**
* src中是否包含dest,需要循環遍歷查詢
* @param src
* @param dest
* @return
*/
public static boolean contain(String[] src, String[] dest){
for(int i = 0; i < dest.length; i++){
int j = 0;
for(; j < src.length; j++){
if(src[j].equals(dest[i])){
break;
}
}
if(j == src.length){
return false;//can not find
}
}
return true;
}
/**
* src是否與dest相等
* @param src
* @param dest
* @return
*/
public boolean equal(String[] src, String[] dest){
if(src.length == dest.length && contain(src, dest)){
return true;
}
return false;
}
/**
* 主測試方法
* 測試方法,挨個去掉注釋,進行測試。
*/
public static void main(String[] args) throws Exception{
//test 1
//List data = loadSmallData();
//Long start = System.currentTimeMillis();
//Map result = new Apriori().compute(data, 0.5, 3, null);//求支持度大于指定值
//Long end = System.currentTimeMillis();
//System.out.println("Apriori Result [costs:"+(end-start)+"ms]: ");
//for(String key : result.keySet()){
//System.out.println("\tFrequent Set=["+key+"] & Support=["+result.get(key)+"];");
//}
//test 2
//List data = loadMushRoomData();
//Long start = System.currentTimeMillis();
//Map result = new Apriori().compute(data, 0.3, 4, new String[]{"2"});//求支持度大于指定值
//Long end = System.currentTimeMillis();
//System.out.println("Apriori Result [costs:"+(end-start)+"ms]: ");
//for(String key : result.keySet()){
//System.out.println("\tFrequent Set=["+key+"] & Support=["+result.get(key)+"];");
//}
//test 3
List data = loadChessData();
Long start = System.currentTimeMillis();
Map result = new Apriori().compute(data, 0.95, 3, null);//求支持度大于指定值
Long end = System.currentTimeMillis();
System.out.println("Apriori Result [costs:"+(end-start)+"ms]: ");
for(String key : result.keySet()){
System.out.println("\tFrequent Set=["+key+"] & Support=["+result.get(key)+"];");
}
}
/*
*SmallData: minSupport 0.5, maxLoop 3, containSet null, [costs: 16ms]
*MushRoomData: minSupport 0.3, maxLoop 4, containSet {"2"}, [costs: 103250ms]
*ChessData: minSupport 0.95, maxLoop 34, containSet {null, [costs: 9718ms]
*/
//測試數據集-1
public static List loadSmallData() throws Exception{
List data = new ArrayList();
data.add(new String[]{"d1","d3","d4"});
data.add(new String[]{"d2","d3","d5"});
data.add(new String[]{"d1","d2","d3","d5"});
data.add(new String[]{"d2","d5"});
return data;
}
//測試數據集-2
public static List loadMushRoomData() throws Exception{
String link = "http://fimi.ua.ac.be/data/mushroom.dat";
URL url = new URL(link);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String temp = reader.readLine();
List result = new ArrayList();
int lineNumber = 0;
while(temp != null){
System.out.println("reading data... [No."+(++lineNumber)+"]");
String[] item = temp.split(" ");
result.add(item);
temp = reader.readLine();
}
reader.close();
return result;
}
//測試數據集-3
public static List loadChessData() throws Exception{
String link = "http://fimi.ua.ac.be/data/chess.dat";
URL url = new URL(link);
BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()));
String temp = reader.readLine();
List result = new ArrayList();
int lineNumber = 0;
while(temp != null){
System.out.println("reading data... [No."+(++lineNumber)+"]");
String[] item = temp.split(" ");
result.add(item);
temp = reader.readLine();
}
reader.close();
return result;
}
}
算法原理:
總結
以上是生活随笔為你收集整理的java实现频繁集_数据挖掘--频繁集测试--Apriori算法--java实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mysql server 5.6root
- 下一篇: oracle 同步 部份表,Oracle