/// <summary> /// Generate rules from an item set where the rules have a size 1 consequent. /// Only rules with confidence at least MinConfidence will be returned. /// </summary> /// <param name="bElem">The frequent item set to generate rules from</param> /// <param name="size">The size of the frequent item set.</param> /// <returns>Rules of the form Y-X -> X where Y is the item set, |X|=1, and confidence(Y-X -> X) >= MinConfidence.</returns> private IList<AssociationRule> generateSingleConsequentRulesFromItemSet(uint bElem, int size) { var rules = new List<AssociationRule>(); for (int i = 0; i < 32; i++) //32 bits in uint { uint mask = 1U << i; if ((bElem & mask) != 0) { var rule = new AssociationRule(bElem & ~mask, size - 1, mask, 1, DataSet); if (rule.Confidence >= MinConfidence) rules.Add(rule); } } return rules; }
/// <summary> /// Generate all rules from frequent itemsets with at least the minimum required confidence. /// </summary> /// <param name="freqItemSets">The frequent item sets to generate rules from.</param> /// <returns>All rules from frequent itemsets with at least the minimum required confidence.</returns> private IList<AssociationRule> generateRules(Dictionary<int, IList<uint>> freqItemSets) { var rules = new List<AssociationRule>(); foreach (int size in freqItemSets.Keys.OrderBy(n => n).Where(n => n >= 2)) { foreach (uint bElem in freqItemSets[size]) { //Get rules with size 1 consequents var startRules = generateSingleConsequentRulesFromItemSet(bElem, size); rules.AddRange(startRules); //Genereate rules with larger consequents for (int conqSize = 2; conqSize < size && startRules.Count > 1; conqSize++) { var newRules = new List<AssociationRule>(); //Iterate over pairs of rules with conqSize-1 size consequents. for (int i = 0; i < startRules.Count - 1; i++) for (int j = i + 1; j < startRules.Count; j++) { AssociationRule rule1 = startRules[i], rule2 = startRules[j]; if (shouldCombine(rule1.Consequent, rule2.Consequent, conqSize - 2)) //Should we combine the consequents? { uint conq = rule1.Consequent | rule2.Consequent; //Form new merged consequent. var rule = new AssociationRule(bElem & ~conq, size - conqSize, conq, conqSize, DataSet); if (rule.Confidence >= MinConfidence) //Accept the rule if it meets required threshold. newRules.Add(rule); } } rules.AddRange(newRules); startRules = newRules; //We will generate the next round of rules from the rules generated this round. } } } return rules; }