資料探勘系列(2) 關聯規則FpGrowth演算法

2021-09-30 12:35:32 字數 3181 閱讀 7138

介紹了關聯規則挖掘的一些基本概念和經典的apriori演算法,aprori演算法利用頻繁集的兩個特性,過濾了很多無關的集合,效率提高不少,但是我們發現apriori演算法是乙個候選消除演算法,每一次消除都需要掃瞄一次所有資料記錄,造成整個演算法在面臨大資料集時顯得無能為力。今天我們介紹乙個新的演算法挖掘頻繁項集,效率比aprori演算法高很多。

tiditems

t1t2

t3t4t5

一、構造fptree

fptree是一種樹結構,樹結構定義如下: 

public

class

fpnode

樹的每乙個結點代表乙個項,這裡我們先不著急看樹的結構,我們演示一下fptree的構造過程,fptree構造好後自然明白了樹的結構。假設我們的最小絕對支援度是3。

step 1:掃瞄資料記錄,生成一級頻繁項集,並按出現次數由多到少排序,如下所示:

item

count牛奶4

麵包4尿布4

啤酒3可以看到,雞蛋和可樂沒有出現在上表中,因為可樂只出現2次,雞蛋只出現1次,小於最小支援度,因此不是頻繁項集,根據apriori定理,非頻繁項集的超集一定不是頻繁項集,所以可樂和雞蛋不需要再考慮。

step 2:再次掃瞄資料記錄,對每條記錄**現在step 1產生的表中的項,按表中的順序排序。初始時,新建乙個根結點,標記為null;

1)第一條記錄:,按step 1表過濾排序得到依然為,新建乙個結點,idname為,將其插入到根節點下,並設定count為1,然後新建乙個結點,插入到結點下面,插入後如下所示:

2)第二條記錄:,過濾並排序後為:,發現根結點沒有包含的兒子(有乙個孫子但不是兒子),因此新建乙個結點,插在根結點下面,這樣根結點就有了兩個孩子,隨後新建結點插在結點下面,新建結點插在下面,插入後如下所示:

3)第三條記錄:,過濾並排序後為:,這時候發現根結點有兒子,因此不需要新建結點,只需將原來的結點的count加1即可,往下發現結點有乙個兒子,於是新建結點,並插入到結點下面,隨後新建結點插入到結點後面。插入後如下圖所示:

4)第四條記錄:,過濾並排序後為:,這時候發現根結點有兒子,因此不需要新建結點,只需將原來的結點的count加1即可,往下發現結點有乙個兒子,於是也不需要新建結點,只需將原來結點的count加1,由於這個結點沒有兒子,此時需新建結點,插在結點下面,隨後新建結點,插在結點下面,插入後如下圖所示:

5)第五條記錄:,過濾並排序後為:,檢查發現根結點有兒子,結點有兒子,結點有兒子,本次插入不需要新建結點只需更新count即可,示意圖如下:

按照上面的步驟,我們已經基本構造了一棵fptree(frequent pattern tree),樹中每天路徑代表乙個項集,因為許多項集有公共項,而且出現次數越多的項越可能是公公項,因此按出現次數由多到少的順序可以節省空間,實現壓縮儲存,另外我們需要乙個表頭和對每乙個idname相同的結點做乙個線索,方便後面使用,線索的構造也是在建樹過程形成的,但為了簡化fptree的生成過程,我沒有在上面提到,這個在**有體現的,新增線索和表頭的fptree如下:

至此,整個fptree就構造好了,在下面的挖掘過程中我們會看到表頭和線索的作用。

二、利用fptree挖掘頻繁項集

fptree建好後,就可以進行頻繁項集的挖掘,挖掘演算法稱為fpgrowth(frequent pattern growth)演算法,挖掘從表頭header的最後乙個項開始。

1)此處即從開始,根據的線索鏈找到所有結點,然後找出每個結點的分支:,,,其中的「1」表示出現1次,注意,雖然出現4次,但只同時出現1次,因此分支的count是由字尾結點的count決定的,除去,我們得到對應的字首路徑,,,根據字首路徑我們可以生成一顆條件fptree,構造方式跟之前一樣,此處的資料記錄變為:

tiditems

t1t2t3

絕對支援度依然是3,構造得到的fptree為:

構造好條件樹後,對條件樹進行遞迴挖掘,當條件樹只有一條路徑時,路徑的所有組合即為條件頻繁集,假設的條件頻繁集為,則的頻繁集為,s2+,s3+},即的頻繁集一定有相同的字尾,此處的條件頻繁集為:,},於是的頻繁集為}。

2)接下來找header表頭的倒數第二個項的頻繁集,同上可以得到的字首路徑為:,,,條件fptree的資料集為:

tiditems

t1t2

t3t4

注意,即的count為2,所以在重複了兩次,這樣做的目的是可以利用之前構造fptree的演算法來構造條件fptree,不過這樣效率會降低,試想如果的count為20000,那麼就需要展開成20000條記錄,然後進行20000次count更新,而事實上只需要對count更新一次到20000即可。這是實現上的優化細節,實踐中當注意。構造的條件fptree為:

這顆條件樹已經是單一路徑,路徑上的所有組合即為條件頻繁集:,,,},加上後,又得到一組頻繁項集,,,},這組頻繁項集一定包含乙個相同的字尾:,並且不包含,因此這一組頻繁項集與上一組不會重複。

重複以上步驟,對header表頭的每個項進行挖掘,即可得到整個頻繁項集,可以證明(嚴謹的演算法和證明可見參考文獻[1]),頻繁項集即不重複也不遺漏。

程式的實現**還是放在我的github上,這裡看一下執行結果:

絕對支援度: 3頻繁項集: 

麵包 尿布 3尿布 牛奶 3牛奶 4麵包 牛奶 3尿布 啤酒 3麵包 4

參考文獻:

資料探勘系列(2) 關聯規則FpGrowth演算法

介紹了關聯規則挖掘的一些基本概念和經典的apriori演算法,aprori演算法利用頻繁集的兩個特性,過濾了很多無關的集合,效率提高不少,但是我們發現apriori演算法是乙個候選消除演算法,每一次消除都需要掃瞄一次所有資料記錄,造成整個演算法在面臨大資料集時顯得無能為力。今天我們介紹乙個新的演算法...

資料探勘系列(2) 關聯規則FpGrowth演算法

資料探勘系列 2 關聯規則fpgrowth演算法 介紹了關聯規則挖掘的一些基本概念和經典的apriori演算法,aprori演算法利用頻繁集的兩個特性,過濾了很多無關的集合,效率提高不少,但是我們發現apriori演算法是乙個候選消除演算法,每一次消除都需要掃瞄一次所有資料記錄,造成整個演算法在面臨...

資料探勘系列(2) 關聯規則FpGrowth演算法

介紹了關聯規則挖掘的一些基本概念和經典的apriori演算法,aprori演算法利用頻繁集的兩個特性,過濾了很多無關的集合,效率提高不少,但是我們發現apriori演算法是乙個候選消除演算法,每一次消除都需要掃瞄一次所有資料記錄,造成整個演算法在面臨大資料集時顯得無能為力。今天我們介紹乙個新的演算法...