Coverage Report - weka.associations.AprioriItemSet
 
Classes in this File Line Coverage Branch Coverage Complexity
AprioriItemSet
0%
0/232
0%
0/86
4.615
 
 1  
 /*
 2  
  *   This program is free software: you can redistribute it and/or modify
 3  
  *   it under the terms of the GNU General Public License as published by
 4  
  *   the Free Software Foundation, either version 3 of the License, or
 5  
  *   (at your option) any later version.
 6  
  *
 7  
  *   This program is distributed in the hope that it will be useful,
 8  
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 9  
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 10  
  *   GNU General Public License for more details.
 11  
  *
 12  
  *   You should have received a copy of the GNU General Public License
 13  
  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 14  
  */
 15  
 
 16  
 /*
 17  
  *    AprioriItemSet.java
 18  
  *    Copyright (C) 2004-2012 University of Waikato, Hamilton, New Zealand
 19  
  *
 20  
  */
 21  
 
 22  
 package weka.associations;
 23  
 
 24  
 import java.io.Serializable;
 25  
 import java.util.Enumeration;
 26  
 import java.util.Hashtable;
 27  
 
 28  
 import weka.core.ContingencyTables;
 29  
 import weka.core.FastVector;
 30  
 import weka.core.Instances;
 31  
 import weka.core.RevisionHandler;
 32  
 import weka.core.RevisionUtils;
 33  
 
 34  
 
 35  
 /**
 36  
  * Class for storing a set of items. Item sets are stored in a lexicographic
 37  
  * order, which is determined by the header information of the set of instances
 38  
  * used for generating the set of items. All methods in this class assume that
 39  
  * item sets are stored in lexicographic order.
 40  
  * The class provides methods that are used in the Apriori algorithm to construct
 41  
  * association rules.
 42  
  *
 43  
  * @author Eibe Frank (eibe@cs.waikato.ac.nz)
 44  
  * @author Stefan Mutter (mutter@cs.waikato.ac.nz)
 45  
  * @version $Revision: 8034 $
 46  
  */
 47  
 public class AprioriItemSet 
 48  
   extends ItemSet 
 49  
   implements Serializable, RevisionHandler {
 50  
   
 51  
   /** for serialization */
 52  
   static final long serialVersionUID = 7684467755712672058L;
 53  
 
 54  
   /**
 55  
    * Constructor
 56  
    * 
 57  
    * @param totalTrans the total number of transactions in the data
 58  
    */
 59  
   public AprioriItemSet(int totalTrans) {
 60  0
     super(totalTrans);
 61  0
   }
 62  
 
 63  
   
 64  
   /**
 65  
    * Outputs the confidence for a rule.
 66  
    *
 67  
    * @param premise the premise of the rule
 68  
    * @param consequence the consequence of the rule
 69  
    * @return the confidence on the training data
 70  
    */
 71  
   public static double confidenceForRule(AprioriItemSet premise, 
 72  
                                          AprioriItemSet consequence) {
 73  
 
 74  0
     return (double)consequence.m_counter/(double)premise.m_counter;
 75  
   }
 76  
 
 77  
   /**
 78  
    * Outputs the lift for a rule. Lift is defined as:<br>
 79  
    * confidence / prob(consequence)
 80  
    *
 81  
    * @param premise the premise of the rule
 82  
    * @param consequence the consequence of the rule
 83  
    * @param consequenceCount how many times the consequence occurs independent
 84  
    * of the premise
 85  
    * @return the lift on the training data
 86  
    */
 87  
   public double liftForRule(AprioriItemSet premise, 
 88  
                             AprioriItemSet consequence,
 89  
                             int consequenceCount) {
 90  0
     double confidence = confidenceForRule(premise, consequence);
 91  
 
 92  0
    return confidence / ((double)consequenceCount / 
 93  
           (double)m_totalTransactions);
 94  
   }
 95  
 
 96  
   /**
 97  
    * Outputs the leverage for a rule. Leverage is defined as: <br>
 98  
    * prob(premise & consequence) - (prob(premise) * prob(consequence))
 99  
    *
 100  
    * @param premise the premise of the rule
 101  
    * @param consequence the consequence of the rule
 102  
    * @param premiseCount how many times the premise occurs independent
 103  
    * of the consequent
 104  
    * @param consequenceCount how many times the consequence occurs independent
 105  
    * of the premise
 106  
    * @return the leverage on the training data
 107  
    */
 108  
   public double leverageForRule(AprioriItemSet premise,
 109  
                                 AprioriItemSet consequence,
 110  
                                 int premiseCount,
 111  
                                 int consequenceCount) {
 112  0
     double coverageForItemSet = (double)consequence.m_counter / 
 113  
       (double)m_totalTransactions;
 114  0
     double expectedCoverageIfIndependent = 
 115  
       ((double)premiseCount / (double)m_totalTransactions) * 
 116  
       ((double)consequenceCount / (double)m_totalTransactions);
 117  0
     double lev = coverageForItemSet - expectedCoverageIfIndependent;
 118  0
     return lev;
 119  
   }
 120  
 
 121  
   /**
 122  
    * Outputs the conviction for a rule. Conviction is defined as: <br>
 123  
    * prob(premise) * prob(!consequence) / prob(premise & !consequence)
 124  
    *
 125  
    * @param premise the premise of the rule
 126  
    * @param consequence the consequence of the rule
 127  
    * @param premiseCount how many times the premise occurs independent
 128  
    * of the consequent
 129  
    * @param consequenceCount how many times the consequence occurs independent
 130  
    * of the premise
 131  
    * @return the conviction on the training data
 132  
    */
 133  
   public double convictionForRule(AprioriItemSet premise,
 134  
                                    AprioriItemSet consequence,
 135  
                                    int premiseCount,
 136  
                                    int consequenceCount) {
 137  0
     double num = 
 138  
       (double)premiseCount * (double)(m_totalTransactions - consequenceCount) /
 139  
        (double)m_totalTransactions;
 140  0
     double denom = 
 141  
       ((premiseCount - consequence.m_counter)+1);
 142  
     
 143  0
     if (num < 0 || denom < 0) {
 144  0
       System.err.println("*** "+num+" "+denom);
 145  0
       System.err.println("premis count: "+premiseCount+" consequence count "+consequenceCount+" total trans "+m_totalTransactions);
 146  
     }
 147  0
     return num / denom;
 148  
   }
 149  
 
 150  
   
 151  
   
 152  
   /**
 153  
    * Generates all rules for an item set.
 154  
    *
 155  
    * @param minConfidence the minimum confidence the rules have to have
 156  
    * @param hashtables containing all(!) previously generated
 157  
    * item sets
 158  
    * @param numItemsInSet the size of the item set for which the rules
 159  
    * are to be generated
 160  
    * @return all the rules with minimum confidence for the given item set
 161  
    */
 162  
   public FastVector[] generateRules(double minConfidence, 
 163  
                                           FastVector hashtables,
 164  
                                           int numItemsInSet) {
 165  
 
 166  0
     FastVector premises = new FastVector(),consequences = new FastVector(),
 167  0
       conf = new FastVector();
 168  
     // TODO
 169  0
     FastVector lift = new FastVector(), lev = new FastVector(),
 170  0
     conv = new FastVector();
 171  
     //TODO
 172  0
     FastVector[] rules = new FastVector[6], moreResults;
 173  
     AprioriItemSet premise, consequence;
 174  0
     Hashtable hashtable = (Hashtable)hashtables.elementAt(numItemsInSet - 2);
 175  
 
 176  
     // Generate all rules with one item in the consequence.
 177  0
     for (int i = 0; i < m_items.length; i++) 
 178  0
       if (m_items[i] != -1) {
 179  0
         premise = new AprioriItemSet(m_totalTransactions);
 180  0
         consequence = new AprioriItemSet(m_totalTransactions);
 181  0
         premise.m_items = new int[m_items.length];
 182  0
         consequence.m_items = new int[m_items.length];
 183  0
         consequence.m_counter = m_counter;
 184  
 
 185  0
         for (int j = 0; j < m_items.length; j++) 
 186  0
           consequence.m_items[j] = -1;
 187  0
         System.arraycopy(m_items, 0, premise.m_items, 0, m_items.length);
 188  0
         premise.m_items[i] = -1;
 189  
 
 190  0
         consequence.m_items[i] = m_items[i];
 191  0
         premise.m_counter = ((Integer)hashtable.get(premise)).intValue();
 192  
 
 193  0
         Hashtable hashtableForConsequence = 
 194  
           (Hashtable)hashtables.elementAt(0);
 195  0
         int consequenceUnconditionedCounter =
 196  
           ((Integer)hashtableForConsequence.get(consequence)).intValue();
 197  
         
 198  0
         premises.addElement(premise);
 199  0
         consequences.addElement(consequence);
 200  0
         conf.addElement(new Double(confidenceForRule(premise, consequence)));
 201  
         
 202  
 
 203  0
         double tempLift = liftForRule(premise, consequence, 
 204  
             consequenceUnconditionedCounter);
 205  0
         double tempLev = leverageForRule(premise, consequence,
 206  
             premise.m_counter,
 207  
             consequenceUnconditionedCounter);
 208  0
         double tempConv = convictionForRule(premise, consequence,
 209  
             premise.m_counter,
 210  
             consequenceUnconditionedCounter);
 211  0
         lift.addElement(new Double(tempLift));
 212  0
         lev.addElement(new Double(tempLev));
 213  0
         conv.addElement(new Double(tempConv));
 214  
       }
 215  0
     rules[0] = premises;
 216  0
     rules[1] = consequences;
 217  0
     rules[2] = conf;
 218  
 
 219  0
     rules[3] = lift;
 220  0
     rules[4] = lev;
 221  0
     rules[5] = conv;
 222  
 
 223  0
     pruneRules(rules, minConfidence);
 224  
 
 225  
     // Generate all the other rules
 226  0
     moreResults = moreComplexRules(rules, numItemsInSet, 1, minConfidence,
 227  
                                    hashtables);
 228  0
     if (moreResults != null) 
 229  0
       for (int i = 0; i < moreResults[0].size(); i++) {
 230  0
         rules[0].addElement(moreResults[0].elementAt(i));
 231  0
         rules[1].addElement(moreResults[1].elementAt(i));
 232  0
         rules[2].addElement(moreResults[2].elementAt(i));
 233  
         
 234  
         // TODO
 235  0
         rules[3].addElement(moreResults[3].elementAt(i));
 236  0
         rules[4].addElement(moreResults[4].elementAt(i));
 237  0
         rules[5].addElement(moreResults[5].elementAt(i));
 238  
       }
 239  0
     return rules;
 240  
   }
 241  
 
 242  
 
 243  
   
 244  
   /**
 245  
    * Generates all significant rules for an item set.
 246  
    *
 247  
    * @param minMetric the minimum metric (confidence, lift, leverage, 
 248  
    * improvement) the rules have to have
 249  
    * @param metricType (confidence=0, lift, leverage, improvement)
 250  
    * @param hashtables containing all(!) previously generated
 251  
    * item sets
 252  
    * @param numItemsInSet the size of the item set for which the rules
 253  
    * are to be generated
 254  
    * @param numTransactions
 255  
    * @param significanceLevel the significance level for testing the rules
 256  
    * @return all the rules with minimum metric for the given item set
 257  
    * @exception Exception if something goes wrong
 258  
    */
 259  
   public final FastVector[] generateRulesBruteForce(double minMetric,
 260  
                                                     int metricType,
 261  
                                                 FastVector hashtables,
 262  
                                                 int numItemsInSet,
 263  
                                                 int numTransactions,
 264  
                                                 double significanceLevel) 
 265  
   throws Exception {
 266  
 
 267  0
     FastVector premises = new FastVector(),consequences = new FastVector(),
 268  0
       conf = new FastVector(), lift = new FastVector(), lev = new FastVector(),
 269  0
       conv = new FastVector(); 
 270  0
     FastVector[] rules = new FastVector[6];
 271  
     AprioriItemSet premise, consequence;
 272  
     Hashtable hashtableForPremise, hashtableForConsequence;
 273  
     int numItemsInPremise, help, max, consequenceUnconditionedCounter;
 274  0
     double[][] contingencyTable = new double[2][2];
 275  
     double metric, chiSquared;
 276  
 
 277  
     // Generate all possible rules for this item set and test their
 278  
     // significance.
 279  0
     max = (int)Math.pow(2, numItemsInSet);
 280  0
     for (int j = 1; j < max; j++) {
 281  0
       numItemsInPremise = 0;
 282  0
       help = j;
 283  0
       while (help > 0) {
 284  0
         if (help % 2 == 1)
 285  0
           numItemsInPremise++;
 286  0
         help /= 2;
 287  
       }
 288  0
       if (numItemsInPremise < numItemsInSet) {
 289  0
         hashtableForPremise = 
 290  
           (Hashtable)hashtables.elementAt(numItemsInPremise-1);
 291  0
         hashtableForConsequence = 
 292  
           (Hashtable)hashtables.elementAt(numItemsInSet-numItemsInPremise-1);
 293  0
         premise = new AprioriItemSet(m_totalTransactions);
 294  0
         consequence = new AprioriItemSet(m_totalTransactions);
 295  0
         premise.m_items = new int[m_items.length];
 296  
         
 297  0
         consequence.m_items = new int[m_items.length];
 298  0
         consequence.m_counter = m_counter;
 299  0
         help = j;
 300  0
         for (int i = 0; i < m_items.length; i++) 
 301  0
           if (m_items[i] != -1) {
 302  0
             if (help % 2 == 1) {          
 303  0
               premise.m_items[i] = m_items[i];
 304  0
               consequence.m_items[i] = -1;
 305  
             } else {
 306  0
               premise.m_items[i] = -1;
 307  0
               consequence.m_items[i] = m_items[i];
 308  
             }
 309  0
             help /= 2;
 310  
           } else {
 311  0
             premise.m_items[i] = -1;
 312  0
             consequence.m_items[i] = -1;
 313  
           }
 314  0
         premise.m_counter = ((Integer)hashtableForPremise.get(premise)).intValue();
 315  0
         consequenceUnconditionedCounter =
 316  
           ((Integer)hashtableForConsequence.get(consequence)).intValue();
 317  
 
 318  0
         if (metricType == 0) {
 319  0
           contingencyTable[0][0] = (double)(consequence.m_counter);
 320  0
           contingencyTable[0][1] = (double)(premise.m_counter - consequence.m_counter);
 321  0
           contingencyTable[1][0] = (double)(consequenceUnconditionedCounter -
 322  
                                             consequence.m_counter);
 323  0
           contingencyTable[1][1] = (double)(numTransactions - premise.m_counter -
 324  
                                             consequenceUnconditionedCounter +
 325  
                                             consequence.m_counter);
 326  0
           chiSquared = ContingencyTables.chiSquared(contingencyTable, false);
 327  
         
 328  0
           metric = confidenceForRule(premise, consequence);
 329  
         
 330  0
           if ((!(metric < minMetric)) &&
 331  
               (!(chiSquared > significanceLevel))) {
 332  0
             premises.addElement(premise);
 333  0
             consequences.addElement(consequence);
 334  0
             conf.addElement(new Double(metric));
 335  0
             lift.addElement(new Double(liftForRule(premise, consequence, 
 336  
                                        consequenceUnconditionedCounter)));
 337  0
             lev.addElement(new Double(leverageForRule(premise, consequence,
 338  
                                      premise.m_counter,
 339  
                                      consequenceUnconditionedCounter)));
 340  0
             conv.addElement(new Double(convictionForRule(premise, consequence,
 341  
                                        premise.m_counter,
 342  
                                        consequenceUnconditionedCounter)));
 343  
           }
 344  
         } else {
 345  0
           double tempConf = confidenceForRule(premise, consequence);
 346  0
           double tempLift = liftForRule(premise, consequence, 
 347  
                                         consequenceUnconditionedCounter);
 348  0
           double tempLev = leverageForRule(premise, consequence,
 349  
                                            premise.m_counter,
 350  
                                            consequenceUnconditionedCounter);
 351  0
           double tempConv = convictionForRule(premise, consequence,
 352  
                                               premise.m_counter,
 353  
                                               consequenceUnconditionedCounter);
 354  0
           switch(metricType) {
 355  
           case 1: 
 356  0
             metric = tempLift;
 357  0
             break;
 358  
           case 2:
 359  0
             metric = tempLev;
 360  0
             break;
 361  
           case 3: 
 362  0
             metric = tempConv;
 363  0
             break;
 364  
           default:
 365  0
             throw new Exception("ItemSet: Unknown metric type!");
 366  
           }
 367  0
           if (!(metric < minMetric)) {
 368  0
             premises.addElement(premise);
 369  0
             consequences.addElement(consequence);
 370  0
             conf.addElement(new Double(tempConf));
 371  0
             lift.addElement(new Double(tempLift));
 372  0
             lev.addElement(new Double(tempLev));
 373  0
             conv.addElement(new Double(tempConv));
 374  
           }
 375  
         }
 376  
       }
 377  
     }
 378  0
     rules[0] = premises;
 379  0
     rules[1] = consequences;
 380  0
     rules[2] = conf;
 381  0
     rules[3] = lift;
 382  0
     rules[4] = lev;
 383  0
     rules[5] = conv;
 384  0
     return rules;
 385  
   }
 386  
 
 387  
   /**
 388  
    * Subtracts an item set from another one.
 389  
    *
 390  
    * @param toSubtract the item set to be subtracted from this one.
 391  
    * @return an item set that only contains items form this item sets that
 392  
    * are not contained by toSubtract
 393  
    */
 394  
   public final AprioriItemSet subtract(AprioriItemSet toSubtract) {
 395  
 
 396  0
     AprioriItemSet result = new AprioriItemSet(m_totalTransactions);
 397  
     
 398  0
     result.m_items = new int[m_items.length];
 399  
    
 400  0
     for (int i = 0; i < m_items.length; i++) 
 401  0
       if (toSubtract.m_items[i] == -1)
 402  0
         result.m_items[i] = m_items[i];
 403  
       else
 404  0
         result.m_items[i] = -1;
 405  0
     result.m_counter = 0;
 406  0
     return result;
 407  
   }
 408  
 
 409  
 
 410  
   /**
 411  
    * Generates rules with more than one item in the consequence.
 412  
    *
 413  
    * @param rules all the rules having (k-1)-item sets as consequences
 414  
    * @param numItemsInSet the size of the item set for which the rules
 415  
    * are to be generated
 416  
    * @param numItemsInConsequence the value of (k-1)
 417  
    * @param minConfidence the minimum confidence a rule has to have
 418  
    * @param hashtables the hashtables containing all(!) previously generated
 419  
    * item sets
 420  
    * @return all the rules having (k)-item sets as consequences
 421  
    */
 422  
   private final FastVector[] moreComplexRules(FastVector[] rules, 
 423  
                                               int numItemsInSet, 
 424  
                                               int numItemsInConsequence,
 425  
                                               double minConfidence, 
 426  
                                               FastVector hashtables) {
 427  
 
 428  
     AprioriItemSet newPremise;
 429  
     FastVector[] result, moreResults;
 430  0
     FastVector newConsequences, newPremises = new FastVector(), 
 431  0
       newConf = new FastVector();
 432  
     Hashtable hashtable;
 433  
     
 434  0
     FastVector newLift = null, newLev = null, newConv = null;
 435  
 //    if (rules.length > 3) {
 436  0
       newLift = new FastVector(); newLev = new FastVector(); newConv = new FastVector();
 437  
 //    }
 438  
 
 439  0
     if (numItemsInSet > numItemsInConsequence + 1) {
 440  0
       hashtable =
 441  
         (Hashtable)hashtables.elementAt(numItemsInSet - numItemsInConsequence - 2);
 442  0
       newConsequences = mergeAllItemSets(rules[1], 
 443  
                                          numItemsInConsequence - 1,
 444  
                                          m_totalTransactions);
 445  0
       int newNumInConsequence = numItemsInConsequence + 1;
 446  
 
 447  0
       Hashtable hashtableForConsequence = (Hashtable)hashtables.elementAt(newNumInConsequence-1);
 448  
       
 449  0
       Enumeration enu = newConsequences.elements();
 450  0
       while (enu.hasMoreElements()) {
 451  0
         AprioriItemSet current = (AprioriItemSet)enu.nextElement();
 452  0
         int z =0;
 453  0
         for (int jj = 0; jj < current.m_items.length; jj++) {
 454  0
           if (current.m_items[jj] != -1) {
 455  0
             z++;
 456  
           }
 457  
         }
 458  
         
 459  0
         current.m_counter = m_counter;
 460  0
         newPremise = subtract(current);
 461  0
         newPremise.m_counter = ((Integer)hashtable.get(newPremise)).intValue();
 462  0
         newPremises.addElement(newPremise);
 463  0
         newConf.addElement(new Double(confidenceForRule(newPremise, current)));
 464  
         
 465  
 //        if (rules.length > 3) {
 466  0
           int consequenceUnconditionedCounter =
 467  
             ((Integer)hashtableForConsequence.get(current)).intValue();
 468  
 
 469  0
           double tempLift = liftForRule(newPremise, current, 
 470  
               consequenceUnconditionedCounter);
 471  0
           double tempLev = leverageForRule(newPremise, current,
 472  
               newPremise.m_counter,
 473  
               consequenceUnconditionedCounter);
 474  0
           double tempConv = convictionForRule(newPremise, current,
 475  
               newPremise.m_counter,
 476  
               consequenceUnconditionedCounter);
 477  
 
 478  0
           newLift.addElement(new Double(tempLift));
 479  0
           newLev.addElement(new Double(tempLev));
 480  0
           newConv.addElement(new Double(tempConv));
 481  
 //        }
 482  0
       }
 483  0
       result = new FastVector[rules.length];
 484  0
       result[0] = newPremises;
 485  0
       result[1] = newConsequences;
 486  0
       result[2] = newConf;
 487  
       
 488  
   //    if (rules.length > 3) {
 489  0
         result[3] = newLift; result[4] = newLev; result[5] = newConv;
 490  
 //      }
 491  0
       pruneRules(result, minConfidence);
 492  0
       moreResults = moreComplexRules(result,numItemsInSet,numItemsInConsequence+1,
 493  
                                      minConfidence, hashtables);
 494  0
       if (moreResults != null) 
 495  0
         for (int i = 0; i < moreResults[0].size(); i++) {
 496  0
           result[0].addElement(moreResults[0].elementAt(i));
 497  0
           result[1].addElement(moreResults[1].elementAt(i));
 498  0
           result[2].addElement(moreResults[2].elementAt(i));
 499  
           //
 500  0
           result[3].addElement(moreResults[3].elementAt(i));
 501  0
           result[4].addElement(moreResults[4].elementAt(i));
 502  0
           result[5].addElement(moreResults[5].elementAt(i));
 503  
         }
 504  0
       return result;
 505  
     } else
 506  0
       return null;
 507  
   }
 508  
   
 509  
   
 510  
    /**
 511  
    * Returns the contents of an item set as a string.
 512  
    *
 513  
    * @param instances contains the relevant header information
 514  
    * @return string describing the item set
 515  
    */
 516  
   public final String toString(Instances instances) {
 517  
    
 518  0
       return super.toString(instances);
 519  
   }
 520  
   
 521  
   /**
 522  
    * Converts the header info of the given set of instances into a set 
 523  
    * of item sets (singletons). The ordering of values in the header file 
 524  
    * determines the lexicographic order.
 525  
    *
 526  
    * @param instances the set of instances whose header info is to be used
 527  
    * @return a set of item sets, each containing a single item
 528  
    * @exception Exception if singletons can't be generated successfully
 529  
    */
 530  
   public static FastVector singletons(Instances instances,
 531  
       boolean treatZeroAsMissing) throws Exception {
 532  
 
 533  0
     FastVector setOfItemSets = new FastVector();
 534  
     ItemSet current;
 535  
 
 536  0
     for (int i = 0; i < instances.numAttributes(); i++) {
 537  0
       if (instances.attribute(i).isNumeric())
 538  0
         throw new Exception("Can't handle numeric attributes!");
 539  0
       int j = (treatZeroAsMissing) ? 1 : 0;
 540  0
       for (; j < instances.attribute(i).numValues(); j++) {
 541  0
         current = new AprioriItemSet(instances.numInstances());
 542  0
         current.setTreatZeroAsMissing(treatZeroAsMissing);
 543  0
         current.m_items = new int[instances.numAttributes()];
 544  0
         for (int k = 0; k < instances.numAttributes(); k++)
 545  0
           current.m_items[k] = -1;
 546  0
         current.m_items[i] = j;
 547  0
         setOfItemSets.addElement(current);
 548  
       }
 549  
     }
 550  0
     return setOfItemSets;
 551  
   }
 552  
   
 553  
   /**
 554  
    * Merges all item sets in the set of (k-1)-item sets 
 555  
    * to create the (k)-item sets and updates the counters.
 556  
    *
 557  
    * @param itemSets the set of (k-1)-item sets
 558  
    * @param size the value of (k-1)
 559  
    * @param totalTrans the total number of transactions in the data
 560  
    * @return the generated (k)-item sets
 561  
    */
 562  
   public static FastVector mergeAllItemSets(FastVector itemSets, int size, 
 563  
                                             int totalTrans) {
 564  
 
 565  0
     FastVector newVector = new FastVector();
 566  
     ItemSet result;
 567  
     int numFound, k;
 568  
 
 569  0
     for (int i = 0; i < itemSets.size(); i++) {
 570  0
       ItemSet first = (ItemSet)itemSets.elementAt(i);
 571  
     out:
 572  0
       for (int j = i+1; j < itemSets.size(); j++) {
 573  0
         ItemSet second = (ItemSet)itemSets.elementAt(j);
 574  0
         result = new AprioriItemSet(totalTrans);
 575  0
         result.m_items = new int[first.m_items.length];
 576  
 
 577  
         // Find and copy common prefix of size 'size'
 578  0
         numFound = 0;
 579  0
         k = 0;
 580  0
         while (numFound < size) {
 581  0
           if (first.m_items[k] == second.m_items[k]) {
 582  0
             if (first.m_items[k] != -1) 
 583  0
               numFound++;
 584  0
             result.m_items[k] = first.m_items[k];
 585  
           } else 
 586  
             break out;
 587  0
           k++;
 588  
         }
 589  
         
 590  
         // Check difference
 591  0
         while (k < first.m_items.length) {
 592  0
           if ((first.m_items[k] != -1) && (second.m_items[k] != -1))
 593  0
             break;
 594  
           else {
 595  0
             if (first.m_items[k] != -1)
 596  0
               result.m_items[k] = first.m_items[k];
 597  
             else
 598  0
               result.m_items[k] = second.m_items[k];
 599  
           }
 600  0
           k++;
 601  
         }
 602  0
         if (k == first.m_items.length) {
 603  0
           result.m_counter = 0;
 604  0
           newVector.addElement(result);
 605  
         }
 606  
       }
 607  
     }
 608  0
     return newVector;
 609  
   }
 610  
   
 611  
   /**
 612  
    * Returns the revision string.
 613  
    * 
 614  
    * @return                the revision
 615  
    */
 616  
   public String getRevision() {
 617  0
     return RevisionUtils.extract("$Revision: 8034 $");
 618  
   }
 619  
 }