頻繁模式挖掘Apriori演算法詳解

2021-07-04 07:22:52 字數 4125 閱讀 2615

本資料探勘演算法是本人進入研究生學習階段進行的第一項「比較難」的學習,下文除了源**有參考zealseeker博主之外均為原創手打,如有**寫的不嚴謹,望請諒解。

首先頻繁模式(frequent patten)表示頻繁的出現在資料集中的模式,舉個例子,去燒烤攤點串,這種選單上的內容就是一種頻繁模式,因為會有某種串被點了很多根,那麼這就視為是一種「頻繁」的成員,同時還有兩個比較重要的概念是「支援度」和「置信度」,支援度表示表示兩種事務同時發生的概率,舉個例子,這家店今天有一百桌吃飯,其中同時點了羊肉串和牛肉串的有20桌,那麼就認為該事件的支援度為20%;同時,點了牛肉串的有50桌,在這50桌裡有20桌點了羊肉串,那麼支援度為40%。「最小支援度閾值」即我們設定的支援度下限,「最小置信度閾值同理」。

apriori使用一種逐層迭代的方法來搜尋頻繁項集,所謂頻繁項集,即在上文中出現的「牛肉串、羊肉串同時購買」這樣的兩種或多種時間同時發生並且至少達到預設的最小支援度的事件。下面我依據《資料探勘:概念與技術(第三版)》中的某分店實物資料進行詳細闡述。

t100=[i1,i2,i5]

t200=[i2,i4]

t300=[i2,i3]

t400=[i1,i2,i4]

t500=[i1,i3]

t600=[i2,i3]

t700=[i1,i3]

t800=[i1,i2,i3,i5]

t900=[i1,i2,i3]

在這裡我設定最小頻繁度為2,即出現了兩次我就認為它是頻繁的。

如果用傳統的思想解決這個問題,我們會找到滿足最小頻繁度的一成員頻繁項集,隨即根據排列組合用兩個for迴圈遍歷所有的情況,在上面的原始資料中,i1~i5均是頻繁的;在下面的尋找二成員頻繁項集中就會排列組合出所有的情況,在這些情況中進行篩選。例子中的原始資料非常小,看起來不複雜,如果資料量巨大,光排列組合加每個集合對比這兩個工作就會產產生指數倍的複雜度,最可怕的是其中可能會有大量的運算是無效的,因為某集合如果不是頻繁的,那麼更大的集合也一定不頻繁,傳統笨方法會將這種情況也進行運算,因此消耗大量計算及資源。

apriori演算法採用了一種新穎的「先驗性質」,即頻繁項集的所有非空子集也一定是頻繁的。根據這個原則,apriori將運算分為兩步:(1)連線步  (2)剪枝步

(1)連線步:連線步意味著小的頻繁集合如何變成更大的集合,就像原始資料中i1可以跟i2變成['i1', 'i2'],以此類推,再複雜一點比如(1,2),(1,3),(1,5),(2,3),(2,4),(2,5)這樣的集合連線方法是:如果每個集合中有k-1項,前k-2項都相同,那麼就把他們組成更大的k項集合,因此可以組成(1,2,3),(1,2,5),(1,3,5),(2,3,4),(2,4,5),(2,3,5)組成四個成員的集合同理。

下面的**是強化注釋版apriori演算法,親測能執行,注釋非常之詳細,傻瓜級。

#coding:utf-8

import itertools

class apriori:

def __init__(self,min_sup=0.2,datadic={}):

self.data = datadic

self.size = len(datadic) #get the number of events

self.min_sup = min_sup

self.min_sup_val = min_sup * self.size #這個數值是頻繁演算法的分子整數部分

def find_frequent_1_itemsets(self):

freqdic = {} # 不管頻繁度如何,先計算頻繁度,然後裝到這裡面

for event in self.data: #event表示字典裡的鍵值,比如t100

for item in self.data[event]:

if item in freqdic: #該成員是否出現過,出沒出現過都要對它進行賦值

freqdic[item] += 1 #出現過則+1

else:

freqdic[item] = 1 #沒出現過則初始值為1

l1 =

for itemset in freqdic: #遍歷第一輪「頻繁」的成員

if itemset >= self.min_sup_val: #如果頻繁度大於設定值

return l1

def has_infrequent_subset(self,c,l_last,k): #這是乙個進行排列組合的函式

subsets = list(itertools.combinations(c,k-1)) #在列表c中選擇k-1個元素進行無序組合

for each in subsets: #遍歷這些組合的情況

each = list(each) #把元素強制轉換成列表

if each not in l_last: #如果上一輪篩選出的集合中的成員沒有在該組合中出現,則返回乙個true,出現過則繼續遍歷所有組合的情況

return true

return false

def apriori_gen(self,l_last): #l_last means frequent(k-1) itemsets 難點!!!

k = len(l_last[0]) + 1 #len()對於列表,則返回成員的個數 如['i1','i2']就返回2

ck = #候選項集集合

for itemset1 in l_last: #迴圈遍歷l_last中的成員

for itemset2 in l_last:

#join step

flag = 0

for i in range(k-2):

if itemset1[i] != itemset2[i]:

flag = 1 #the two itemset can't join

break

if flag == 1:

continue

if itemset1[k-2] < itemset2[k-2]:

c = itemset1 + [itemset2[k-2]] #例:['i1']<['i2']成立,則推入乙個['i1','i2'],並且先不計算它的頻繁度

else:

continue

#pruning setp

if self.has_infrequent_subset(c,l_last,k):

continue

else:

return ck

def do(self):

l_last = self.find_frequent_1_itemsets()

l = l_last

i = 0

while l_last != : #只要本組頻繁項集不空則繼續迴圈

ck = self.apriori_gen(l_last) #候選項集集合(僅僅是各種排列組合,沒篩選頻繁度)推入ck中

freqdic = {}

for event in self.data: #遍歷原始data資料

#get all suported subsets

for c in ck: #遍歷候選的所有項集集合

if set(c) <= set(self.data[event]):#set()表示無序不重複元素集,如果c元素集是原始資料這個集合的子集

if tuple(c) in freqdic: #如果元組c在字典中

freqdic[tuple(c)]+=1 #這個元組的值+1,即又出現了一次

else:

freqdic[tuple(c)]=1

print freqdic #將候選項集集合,以及出現的次數,以字典的形式列印出來,到這裡時仍然沒計算頻繁度

lk = #滿足頻繁度集合的列表

for c in freqdic: #遍歷字典裡的所有候選集合

if freqdic[c] > self.min_sup_val: #如果大於設定的頻繁度

l_last = lk #將該列表定義為滿足頻繁度的最後一組列表

l += lk #最終結果的列表為l

return l

#******test******

data =

a=apriori(datadic=data)

print a.do()

後面還有對該演算法的優化演算法,能力有限,還沒來得及看,活幾天研究一下,有時間我會放上導師留下的「**延展問題」

頻繁模式挖掘 Apriori演算法

dm實驗,寫的比較二,好多情況還沒有考慮,後續有時間會修改。開始的時候資料結構沒設計好導致寫到後面費了很大的勁 不過還好python的列表有起死回生的功效 資料集 database.txt i1,i2,i5 i2,i4 i2,i3 i1,i2,i4 i1,i3 i2,i3 i1,i3 i1,i2,i...

頻繁模式挖掘Apriori初學詳解

coding utf 8 import itertools class apriori def init self,min sup 0.2,datadic self.data datadic self.size len datadic get the number of events self.mi...

資料探勘 Apriori演算法

今日資料探勘課學習了apriori演算法,特意總結下,因為自己是大三弱雞,很多地方參考了下面dalao的博文 非常感謝!apriori演算法是一種挖掘關聯規則的頻繁項集演算法,其核心思想是通過候選集生成和情節的向下封閉檢測兩個階段來挖掘頻繁項集。而且演算法已經被廣泛的應用到商業 網路安全等各個領域。...