package ca.pfv.spmf.algorithms.frequentpatterns.estDec; import java.io.BufferedReader; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.util.Hashtable; /** * This is an implementation of the estDec algorithm (J. Chang, W.S. Lee 2006). * <br/><br/> * * This implementation was made by Azadeh Soltani * <br/><br/> * * Copyright (c) 2008-2014 Azadeh Soltani, Philippe Fournier-Viger * <br/><br/> * * This file is part of the SPMF DATA MINING SOFTWARE * (http://www.philippe-fournier-viger.com/spmf). * <br/><br/> * * SPMF is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * <br/><br/> * * SPMF is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * <br/><br/> * * You should have received a copy of the GNU General Public License along with * SPMF. If not, see <http://www.gnu.org/licenses/>. * @see estNode * @see estTree * @author Azadeh Soltani */ public class Algo_estDec { // the "monitoring lattice" tree estTree tree; // for stats private long miningTime = 0; double sumTransactionInsertionTime = 0; // sum of time for inserting transactions private double maxMemory = 0; /** * Constructor * @param mins minimum support * @param minSigValue the minSig parameter */ public Algo_estDec(double mins, double minSigValue) { // create the "Monitoring Lattice" tree tree = new estTree(mins, minSigValue); } /** * Run the algorithm by loading the transactions from an input file. * @param input the input file path * @param output the output file path for saving the result * @param mins the minsup threshold as a double value in [0, 1] * @throws FileNotFoundException if error opening the input file * @throws IOException if error reading/writing files */ public void processTransactionFromFile(String input) throws FileNotFoundException, IOException { // read the input file BufferedReader reader = new BufferedReader(new FileReader(input)); String line; // int n=0; // for each line (transaction) while (((line = reader.readLine()) != null)) { String[] lineSplited = line.split(" "); // convert the array of strings to an array of integers (items) int[] transaction = new int[lineSplited.length]; for (int i = 0; i < lineSplited.length; i++) { transaction[i] = Integer.parseInt(lineSplited[i]); } // if (transaction.length<80) processTransaction(transaction); // else // n++; }// while reader.close(); // System.out.println(n); } /** * Run the algorithm by loading the transactions from an input file. * @param input the input file path * @param output the output file path for saving the result * @param mins the minsup threshold as a double value in [0, 1] * @param lineCount the number of lines to be read * @throws FileNotFoundException if error opening the input file * @throws IOException if error reading/writing files */ public void processTransactionFromFile(String input, int lineCount) throws FileNotFoundException, IOException { // read the input file BufferedReader reader = new BufferedReader(new FileReader(input)); String line; int n=0; // for each line (transaction) while (((line = reader.readLine()) != null) && n < lineCount) { String[] lineSplited = line.split(" "); // convert the array of strings to an array of integers (items) int[] transaction = new int[lineSplited.length]; for (int i = 0; i < lineSplited.length; i++) { transaction[i] = Integer.parseInt(lineSplited[i]); } processTransaction(transaction); n++; }// while reader.close(); // System.out.println("Transaction read from file:" + n); } /** * Mine recent frequent itemsets from the current tree and * save the result to a file * @throws IOException * @param outputPath the output file path */ public void performMining_saveResultToFile(String outputPath) throws IOException { // Perform mining long startMiningTimeStamp = System.currentTimeMillis(); tree.patternMining_saveToFile(outputPath); miningTime = System.currentTimeMillis() - startMiningTimeStamp; System.gc(); checkMemory(); } /** * Mine recent frequent itemsets from the current tree and * save the result to memory * @throws IOException * @param outputPath the output file path * @return */ public Hashtable<int[], Double> performMining_saveResultToMemory() throws IOException { // Perform mining long startMiningTimeStamp = System.currentTimeMillis(); Hashtable<int[], Double> patterns = tree.patternMining_saveToMemory(); checkMemory(); miningTime = System.currentTimeMillis() - startMiningTimeStamp; return patterns; } /** * Process a transaction (add it to the tree and update itemsets * @param transaction an array of integers */ public void processTransaction(int[] transaction) { double startCTimestamp = System.currentTimeMillis(); // process the transaction tree.updateParams(transaction); tree.insertItemset(transaction); // force pruning every 1000 transactions if (tree.getK() % 10000 == 0) tree.forcePruning(tree.root); sumTransactionInsertionTime += (System.currentTimeMillis() - startCTimestamp); } /** * Check the current memory consumption to record the maximum memory usage. */ private void checkMemory() { // Runtime.getRuntime().gc(); double currentMemory = (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024d / 1024d; if (currentMemory > maxMemory) { maxMemory = currentMemory; } } /** * Set the decay rate * @param b decay base * @param h decay-base life */ public void setDecayRate(double b, double h) { tree.setDecayRate(b,h); } /** * Print statistics about the algorithm execution to the console. */ public void printStats() { System.out.println("============= ESTDEC - STATS ============="); System.out.println(" Number of nodes : " + tree.nodeCount(tree.root)); System.out.println(" Frequent itemsets count : " + tree.patternCount); System.out.println(" Maximum memory usage : " + maxMemory + " mb"); System.out.println(" Number of transactions: " + tree.getK()); System.out.println(" Total insertion time ~ " + sumTransactionInsertionTime + " ms"); System.out.println(" Insertion time per transaction ~ " + sumTransactionInsertionTime / tree.getK() + " ms"); System.out.println(" Mining time ~ " + miningTime + " ms"); System.out.println("==================================================="); } }