FP-Growth的C++演算法實現
阿新 • • 發佈:2018-12-05
FP-tree演算法比Apriori演算法更難實現,主要是其中用的一些特殊的資料結構,對我來說都不太熟,不像Apriori只用一些陣列就能簡單得實現。
失敗的例子
和Apriori一樣,我第一次實現的時候,也是想著用的vector的儲存結構來實現樹,定義了一個如下的結構體
struct TreeNode { int Id; int Co; TreeNode *Parent; TreeNode *HeadNext; vector<TreeNode*> Children; }; int InitTree(TreeNode &T) { TreeNode temp; temp.Id=0; temp.Co=0; temp.Parent=NULL; temp.HeadNext=NULL; temp.Children.clear(); T=temp; return 0; }
但是在掃描資料庫建樹的時候,效率極其低下,掃描8萬行的資料集大概需要20個小時。可能是對樹的構造還是不太熟,雖然這樣子能夠應該能夠實現建成一棵FPTree,但是不實用,所以就沒繼續照著這個思路尋找條件模式基。
int AddTree(TreeNode &T,int a,int next,vector<vector<int> > sim)//sim為去除了非頻繁一項集且排序好的全體資料集 { if(next>=sim[a].size()) return next; else{ int locate=0; TreeNode *NewNode; NewNode=new(TreeNode); int to=-1; if(T.Children.size()==0) { NewNode->Id=sim[a][next]; next++; NewNode->Co=1; NewNode->Parent=&T; NewNode->Children.clear(); T.Children.push_back(NewNode); locate=T.Children.size()-1; //delete NewNode; AddTree(*T.Children[locate],a,next,sim); } else{ for(int i=0;i<T.Children.size();i++) { if(T.Children[i]->Id==sim[a][next]) { next++; to=i; T.Children[i]->Co++; //delete NewNode; AddTree(*T.Children[i],a,next,sim); //break; } } if(to==-1) { NewNode->Id=sim[a][next]; next++; NewNode->Co=1; NewNode->Parent=&T; NewNode->Children.clear(); T.Children.push_back(NewNode); locate=T.Children.size()-1; //delete NewNode; AddTree(*T.Children[locate],a,next,sim); } } } } void CreateTree(TreeNode &T,vector<vector<int> > sim) { int i=0; while(i<10) { if(AddTree(T,i,0,sim)>=sim[i].size()) { i++; } //cout<<i<<endl; } }
第二次嘗試
沒辦法只能去網上找找如何建FP-Tree,結果大部分都是用Python,Java實現,只找到了一篇資料探勘作業——FP Tree演算法之C++實現,不過裡面出現了map、Tire樹等我不會的結構,接下來打算參照該演算法,然後使用我唯一會一點的vector來重新實現一遍。
佔坑。