/** * Places all rules that satisfy the given record in a CMAR rule linked list pointed at by * startCMARrulelist field, in the order that rules are presented. * * <p>Used in Weighted Chi-Squared classification (CMAR) algorithm. * * @param linkref The reference to the start of the existing list of rules. * @param itemset the record to be classified. */ private void obtainallRulesForRecord(RuleNodeCMAR linkRef, short[] itemSet) { RuleNodeCMAR newStartRef = null; RuleNodeCMAR markerRef = null; // Loop through linked list of existing rules while (linkRef != null) { // If rule satisfies record add to new rule list if (isSubset(linkRef.antecedent, itemSet)) { RuleNodeCMAR newNode = new RuleNodeCMAR( linkRef.antecedent, linkRef.consequent, linkRef.supportForRule, linkRef.suppAntecedent, linkRef.suppConsequent, linkRef.confidenceForRule); if (newStartRef == null) newStartRef = newNode; else markerRef.next = newNode; markerRef = newNode; /*if (newStartRef==null) newStartRef=linkRef; else markerRef.next=linkRef; markerRef=linkRef; */ } linkRef = linkRef.next; } // Set rule list startCMARrulelist = newStartRef; }
/** * Groups rules contained in a linked list of rules pointed at by <TT>startCMARrulelist</TT> * according to their consequent. * * @return an array of rule groups. */ private RuleNodeCMAR[] groupRules() { // Initialise rule groups data structure RuleNodeCMAR[] ruleGroups = new RuleNodeCMAR[numClasses]; for (int index = 0; index < ruleGroups.length; index++) ruleGroups[index] = null; // Loop through rule list RuleNodeCMAR linkRef = startCMARrulelist; while (linkRef != null) { // Identify index for consequent int index = numOneItemSets - linkRef.consequent[0]; // Add to rule group RuleNodeCMAR ruleCopy = new RuleNodeCMAR( linkRef.antecedent, linkRef.consequent, linkRef.supportForRule, linkRef.suppAntecedent, linkRef.suppConsequent, linkRef.confidenceForRule); ruleCopy.next = ruleGroups[index]; ruleGroups[index] = ruleCopy; // Increment link reference linkRef = linkRef.next; } // Return return (ruleGroups); }
/** * Prunes the current CMAR list of rules according to the "cover" principle. * * @param trainingSet the input data set. */ protected void pruneUsingCover(short[][] trainingSet) { // Initialise cover array int[] cover = new int[trainingSet.length]; // Define rule list references RuleNodeCMAR newStartRef = null; RuleNodeCMAR markerRef = null; RuleNodeCMAR linkRef = startCMARrulelist; // Loop through rule list while (linkRef != null) { // If no more training records end if (emptyDataSet(trainingSet)) break; // Set cover flag to false, will be set to true of a rule matches // a record. boolean coverFlag = false; // Loop through training set for (int index = 0; index < trainingSet.length; index++) { // If record satisfies a rule increment cover element for // record and set cover flag to true to indicate that rule // is required by at least one record if (isSubset(linkRef.antecedent, trainingSet[index])) { cover[index]++; coverFlag = true; } } // If current rule is required by at least one record (cover flag // set to true) add to new rule list if (coverFlag) { if (newStartRef == null) newStartRef = linkRef; else markerRef.next = linkRef; markerRef = linkRef; linkRef = linkRef.next; markerRef.next = null; } else linkRef = linkRef.next; // Remove records from training set if adequately covered for (int index = 0; index < cover.length; index++) { if (cover[index] > MIN_COVER) trainingSet[index] = null; } } // Set rule list startCMARrulelist = newStartRef; }
/** * Inserts an (association/classification) rule into the linkedlist of rules pointed at by * <TT>startRulelist</TT>. * * <p>List is ordered according to "CMAR" ranking. * * @param antecedent the antecedent (LHS) of the rule. * @param consequent the consequent (RHS) of the rule. * @param supportForAntecedent the associated support for the antecedent. * @param supportForConsequent the associated support for the consequent. * @param supportForRule the associated support value. * @param confidenceForRule the associated confidence value. */ protected void insertRinRlistCMARranking( short[] antecedent, short[] consequent, double supportForAntecedent, double supportForConsequent, double supportForRule, double confidenceForRule) { // Test rule using Chi-Squared testing if (!testRuleUsingChiSquaredTesting( supportForAntecedent, supportForConsequent, supportForRule, numRows)) return; // Create new node RuleNodeCMAR newNode = new RuleNodeCMAR( antecedent, consequent, supportForRule, supportForAntecedent, supportForConsequent, confidenceForRule); // Empty rule list situation if (startCMARrulelist == null) { startCMARrulelist = newNode; return; } // Check if more general rule with higher ranking exists. if (moreGeneralRuleExists(newNode)) return; // Add new node to start if (ruleIsCMARgreater(newNode, startCMARrulelist)) { newNode.next = startCMARrulelist; startCMARrulelist = newNode; return; } // Add new node to middle RuleNodeCMAR markerNode = startCMARrulelist; RuleNodeCMAR linkRuleNode = startCMARrulelist.next; while (linkRuleNode != null) { if (ruleIsCMARgreater(newNode, linkRuleNode)) { markerNode.next = newNode; newNode.next = linkRuleNode; return; } markerNode = linkRuleNode; linkRuleNode = linkRuleNode.next; } // Add new node to end markerNode.next = newNode; }