00001 #ifndef InfreqRemover_AssocRuleGen_HPP
00002 #define InfreqRemover_AssocRuleGen_HPP
00003
00004 #include "common.hpp"
00005 #include "common/Edge.hpp"
00006 #include "apriori/bodon/inhomogeneous_trie/trie_manipulators/InfreqRemover.hpp"
00007 #include <vector>
00008
00009
00010
00011
00012
00013
00014 namespace Bodon
00015 {
00016 namespace inhomogeneous_trie
00017 {
00018 template <class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR,
00019 NEELevel NEE, bool DEADENDPRUNE = true>
00020 class InfreqRemover_AssocRuleGen : public InfreqRemover
00021 <DF_D, TRIE, LEAF, LEAF_ALLOCATOR, NEE, DEADENDPRUNE>
00022 {
00023 protected:
00024 typedef InfreqRemover
00025 <DF_D, TRIE, LEAF, LEAF_ALLOCATOR, NEE, DEADENDPRUNE> PARENT;
00026 float min_conf;
00027 float min_lift;
00028 counter_t nr_of_transaction;
00029
00030
00031 public:
00032 InfreqRemover_AssocRuleGen(
00033 TRIE& main_trie, DF_D& df_decoder, LEAF_ALLOCATOR& s_alloc,
00034 float min_conf, float min_intr, counter_t nr_of_transaction) :
00035 PARENT(main_trie, df_decoder, s_alloc),
00036 min_conf(min_conf), min_lift(min_lift),
00037 nr_of_transaction(nr_of_transaction){}
00038
00039 void afterWorkDel();
00040
00041 protected:
00042 void generateUnions( TRIE* subtrie, std::vector<item_t>& union_set);
00043 void generateAssocRules(
00044 std::vector<item_t>& antecedent_set, std::set<item_t>& conseq_set,
00045 const counter_t union_support);
00046
00047 bool generateAnAssociationRule(
00048 std::vector<item_t>& antecedent_set,
00049 std::set<item_t>& conseq_set, const counter_t union_support);
00050 };
00051
00052
00053 template <class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR,
00054 NEELevel NEE, bool DEADENDPRUNE> inline
00055 void InfreqRemover_AssocRuleGen<DF_D, TRIE, LEAF, LEAF_ALLOCATOR,
00056 NEE, DEADENDPRUNE>::
00057 afterWorkDel()
00058 {
00059 if(!DEADENDPRUNE)
00060 if(NEE > NEE_Off)
00061 {
00062 std::vector<item_t> NEEsum;
00063 PARENT::destroyAndWriteNEE(&this->main_trie, NEEsum);
00064 }
00065 else
00066 {
00067 log_status(0,"Generating association rules.");
00068 std::vector<item_t> union_set;
00069 generateUnions(&this->main_trie, union_set);
00070 PARENT::destroy(&this->main_trie);
00071 }
00072 }
00073
00074 template <class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR,
00075 NEELevel NEE, bool DEADENDPRUNE>
00076 void InfreqRemover_AssocRuleGen<DF_D, TRIE, LEAF, LEAF_ALLOCATOR,
00077 NEE, DEADENDPRUNE>::
00078 generateUnions( TRIE* subtrie, std::vector<item_t>& union_set)
00079 {
00080 for(typename TRIE::iterator itEdge( subtrie->edgelist.begin() );
00081 itEdge != subtrie->edgelist.end(); ++itEdge)
00082 {
00083 union_set.push_back((*itEdge).first);
00084 std::set<item_t> conseq_set;
00085 generateAssocRules(union_set, conseq_set, this->main_trie.isIncluded
00086 ( union_set, union_set.begin() )->getCounter());
00087 generateUnions( static_cast<TRIE*>((*itEdge).second), union_set );
00088 union_set.pop_back();
00089 }
00090 }
00091 template <class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR,
00092 NEELevel NEE, bool DEADENDPRUNE>
00093 void InfreqRemover_AssocRuleGen<DF_D, TRIE, LEAF, LEAF_ALLOCATOR,
00094 NEE, DEADENDPRUNE>::
00095 generateAssocRules(
00096 std::vector<item_t>& antecedent_set, std::set<item_t>& conseq_set,
00097 const counter_t union_support)
00098 {
00099 if(antecedent_set.size() > 1)
00100 {
00101 std::vector<item_t>::iterator it = antecedent_set.begin();
00102 register item_t replaced_item = *it, temp_item;
00103 antecedent_set.erase(it);
00104 conseq_set.insert(replaced_item);
00105 if( generateAnAssociationRule(
00106 antecedent_set, conseq_set, union_support) )
00107 generateAssocRules(antecedent_set, conseq_set, union_support);
00108 conseq_set.erase(replaced_item);
00109 while (it != antecedent_set.end() )
00110 {
00111 temp_item = *it;
00112 *it = replaced_item;
00113 ++it;
00114 replaced_item = temp_item;
00115 conseq_set.insert(replaced_item);
00116 if( generateAnAssociationRule(antecedent_set, conseq_set, union_support) )
00117 generateAssocRules(antecedent_set, conseq_set, union_support);
00118 conseq_set.erase(replaced_item);
00119 }
00120 antecedent_set.push_back( replaced_item );
00121 }
00122 }
00123
00124 template <class DF_D, class TRIE, class LEAF, class LEAF_ALLOCATOR,
00125 NEELevel NEE, bool DEADENDPRUNE> inline
00126 bool InfreqRemover_AssocRuleGen<DF_D, TRIE, LEAF, LEAF_ALLOCATOR,
00127 NEE, DEADENDPRUNE>::
00128 generateAnAssociationRule(
00129 std::vector<item_t>& antecedent_set,
00130 std::set<item_t>& conseq_set, const counter_t union_support)
00131 {
00132 counter_t antec_supp = this->main_trie.isIncluded(
00133 antecedent_set, antecedent_set.begin())->getCounter();
00134 counter_t conseq_supp = this->main_trie.isIncluded(
00135 conseq_set, conseq_set.begin())->getCounter();
00136 float confidence = static_cast<float>(union_support) / antec_supp;
00137 if(confidence >= min_conf)
00138 {
00139 float lift = confidence * (static_cast<float>(nr_of_transaction) /
00140 conseq_supp);
00141 if(lift >= min_lift)
00142 PARENT::df_decoder.writeAssocRule(
00143 antecedent_set.begin(), antecedent_set.end(),
00144 conseq_set.begin(), conseq_set.end(),
00145 union_support, confidence, lift);
00146 return true;
00147 }
00148 else
00149 return false;
00150
00151 }
00152 }
00153 }
00154 #endif