Apriori算法的缺陷
雖然Apriori算法使用先驗性質去除了很多的候選項集,但Apriori算法還是有兩個大問題:
1.可能產生大量的候選項集。例如,當頻繁1項集的個數達到1000個時,產生的候選2項集的個數達到C(2,1000)。C(2,1000) = 1000! / (2! * 9998!) = (1000 * 999 * 998!) / (2 * 998!) = (1000 * 999) / 2 = 499500。這還只是由頻繁1項集獲取候選2項集產生的項集個數。
2.可能需要多次迭代數據庫。在每次獲取候選項集後都需要迭代數據庫,獲取支持度計數。
FP-Growth
為此,Han JiaWei 提出了一個不需要產生候選項集的算法:FP-Growth。
FP-Growth算法主要分2步:先將所有數據庫事務壓縮到一個樹結構(FP-Tree)中,該結構保留了項與項之間的關聯信息;然後對樹結構進行挖掘。
以下是詳細過程:
1.創建FP-Tree
1.1遍歷數據庫(第1次),獲取所有頻繁1項集及其支持度計數,將頻繁1項集按遞減支持度計數排列。
1.2首先創建值為null的根節點,然後遍歷數據庫(第2次),將每個事務中的項集按頻繁1項集的順序排列(按遞減支持度計數排列),將排序後的最大支持度的項作為null根節點的子節點,將第2項作為第1項的子節點,以此類推。如果是創建新節點則設置新節點的SupportCount等於1,同時讓項頭表(ItemHeaderTable)記住該節點的地址;如果路徑中的節點已經存在,則讓該節點的SupportCount遞增1。最終形成具有項關聯信息的FP-Tree和完整的項頭表。
2.挖掘FP-Tree
2.1挖掘FP-Tree的主要思想就是讓項頭表中的每一個項與後綴模式合併形成新的模式,創建該項的子樹和與子樹對應的子項頭表,然後讓子項頭表中的每一個項與後綴模式(即上層遞歸形成的新模式)合併形成新的模式,創建該項的子子樹和與子子樹對應的子子項頭表。如此遞歸下去,直到無法形成樹為止。每層遞歸都會讓項頭表中的項與後綴模式(suffixpattern)合併成新的模式,新的模式將作為下層遞歸的後綴模式,這就是算法名稱中的“Growth”。針對只有單一路徑的樹,則可以對樹中的所有節點進行組合形成新的模式,提升算法性能。
代碼實現
以下是FP-Growth的C++實現,只貼出FP-Growth算法的核心部分:
FPGrowth.h:
<code>#ifndef ILANEVER_PATTERN_FPGROWTH_H
#define ILANEVER_PATTERN_FPGROWTH_H
#include <iostream>
#include <memory>
#include /<memory>/<iostream>/<code>
FPGrowth.cpp:
<code>#include "FPGrowth.h"
#include <memory>
#include /<memory>/<code>
閱讀更多 老李頭的小研究
的文章
關鍵字:
算法
步步為營
牆棋