1. 程式人生 > >關聯規則,Apriori演算法及python實現

關聯規則,Apriori演算法及python實現

1 關聯規則

關聯分析一個典型的例子是購物籃分析,廣泛應用於零售業,通過檢視那些商品經常在一起購買,可以幫助商店瞭解使用者的購買行為。一個最有名的例子是“尿布與啤酒”,據報道,美國中西部的一家連鎖店發現,男人們會在週四購買尿布和啤酒,這樣商家實際上就可以將尿布和啤酒放在一塊,並確保在週四全價銷售從中獲利。
關聯分析(關聯規則學習):從大規模資料集中尋找物品間的隱含關係
但是一般銷售資料庫巨大,如何快速找到資料庫中物品之間的聯絡成為主要的難題,Apriori演算法在1996年應運而生,改演算法可以高效的找出頻繁項集,並從頻繁項集中抽取除關聯規則。當然,該演算法不僅應用在零售業,在特徵關聯等領域也有廣泛應用。
關聯分析中所需的兩個度量公式:
1. 頻繁項集度量支援度(support)


supportx,y=numberofbuy(x,y)allofbuy
2. 關聯規則度量可信度(confidence)
confidence(x>y)=numberofbuy(x,y)numberofbuy(x)=supportx,ysupportx
可信度的值應接近於1,且顯著大於人們購買Y的支援度,即如果購買X,Y的顧客很少,那麼該條還是沒有價值的,支援度展示了關聯規則的統計顯著性,可信度展示關聯規則的強度。

2 Apriori演算法

1. Apriori演算法原理
頻繁項集:如果某個項集是頻繁的,那麼他的子集也是頻繁的。例如,有四種商品,0,1,2,3,其中{0,1}是頻繁項集,即同時購買商品0和1的購買行為數量在總的購買行為佔比較大(一般會有認為給定的最小支援度的閾值來區分是否是頻繁項集),那麼,{0}和{1}也是頻繁項集。反之,如果如果項集不是頻繁項集,那麼他的超集也不是頻繁項集,例如,如果{0}不是頻繁項集,那麼{0,1},{0,1,2}…也不是頻繁項集。
關聯規則

:從某一頻繁項集中挖掘關聯規則,我們關注的是,某一頻繁項集中是否存在由某個元素或元素集合可能會推匯出另一個或幾個元素,若該關聯關係用”->”表示,則箭頭左側稱為前件,箭頭右側稱為後件,Apriori演算法挖掘關聯規則的做法是,首先從一個頻繁項集出發,穿件一個規則列表,其中右部(後件)只包含一個元素,然後從該組規則中找出可信度大於最小可信度的規則集合,並用該組具有較高可信度的規則合併成新的規則列表,其中右部(後件集合中)包含兩個元素,遞推進行此過程。
Apriori演算法生成頻繁項集及關聯規則挖掘示意圖
apriori

3 python實現Apriori演算法

# -*- coding: utf-8 -*-
""" Created on Sat Jun 03 09:42:41 2017 Apriori @author: jipingliu """ def loadDataSet(): ''' 輸入:無 功能:產生簡單的資料集 輸出:dataset ''' return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]] def createC1(dataset): ''' 輸入:資料集 功能:產生類似[[1], [2], [3], [4], [5]],C1中包含的元素為資料集中出現的元素 輸出:C1 ''' C1 = [] for transction in dataset: #print transction for item in transction: if not [item] in C1: C1.append([item])#使用列表作為C1元素是因為後續需要使用集合操作 C1.sort() return map(frozenset,C1) def scanDataSet(DataSet,Ck,minSupport): ''' 輸入:DataSet應為每條記錄是set型別資料(被用於判斷是否是其子集操作),Ck中的每個項集為frozenset型資料(被用於字典關鍵字) Ck為候選頻繁項集,minSupport為判斷是否為頻繁項集的最小支援度(認為給定) 功能:從候選項集中找出支援度support大於minSupport的頻繁項集 輸出:頻繁項集集合returnList,以及頻繁項集對應的支援度support ''' subSetCount = {} for transction in DataSet:#取出資料集dataset中的每行記錄 for subset in Ck:#取出候選頻繁項集Ck中的每個項集 if subset.issubset(transction):#判斷Ck中項集是否是資料集每條記錄資料集合中的子集 if not subSetCount.has_key(subset):subSetCount[subset] = 1 else: subSetCount[subset] += 1 numItem = float(len(DataSet)) returnList =[] returnSupportData = {} for key in subSetCount: support = subSetCount[key]/numItem if support >= minSupport: returnList.insert(0,key) returnSupportData[key] = support return returnList,returnSupportData def createCk(Lk,k): returnList = [] lenLk = len(Lk) for i in range(lenLk): for j in range(i+1,lenLk): L1 = list(Lk[i])[:k-2];L2 = list(Lk[j])[:k-2] L1.sort();L2.sort() if L1 == L2:#只需取前k-2個元素相等的候選頻繁項集即可組成元素個數為k+1的候選頻繁項集!! returnList.append(Lk[i] | Lk[j]) return returnList def apriori(dataset,minSupport = 0.5): C1 = createC1(dataset) DataSet = map(set,dataset) L1,returnSupportData = scanDataSet(DataSet,C1,minSupport) L = [L1] k = 2 while (len(L[k-2]) > 0): #由上一時刻的頻繁項集Lk-1,兩兩組合形成下一時刻沒有重複的頻繁項集,下一時刻候選頻繁項集中元素個數會比上一時刻的多1 Ck = createCk(L[k-2],k) #從候選頻繁項集中選出支援度大於minsupport的頻繁項集Lk Lk,supportLk = scanDataSet(DataSet,Ck,minSupport) #將該頻繁項集及其支援度新增到returnSupportData字典中記錄,其中頻繁項集為關鍵字,支援度為關鍵字所對應的項 returnSupportData.update(supportLk) #將頻繁項集新增到列表L中記錄 L.append(Lk) #逐一增加頻繁項集中的元素個數 k += 1 return L, returnSupportData #------------------關聯規則生成函式--------------# def generateRules(L,supportData,minConference = 0.7): bigRuleList = [] for i in range(1,len(L)): for subSet in L[i]: H1 = [frozenset([item]) for item in subSet] if (i > 1): rulesFromConseq(subSet, H1, supportData, bigRuleList, minConference) else: calculationConf(subSet, H1, supportData,bigRuleList,minConference) return bigRuleList def calculationConf(subSet, H, supportData,brl,minConference=0.7): prunedH = [] for conseq in H: conf = supportData[subSet]/supportData[subSet - conseq] if conf >= minConference: print subSet-conseq,'-->',conseq,'conf:',conf brl.append((subSet-conseq,conseq,conf)) prunedH.append(conseq) return prunedH def rulesFromConseq(subSet, H, supportData, brl, minConference): m = len(H[0]) #如果頻繁項集中每項元素個數大於買m+1,即,可以分出m+1個元素在規則等式右邊則執行 if (len(subSet) > (m+1)): #利用函式createCk生成包含m+1個元素的候選頻繁項集後件 Hm = createCk(H, (m+1)) #計算前件(subSet - Hm)--> 後件(Hm)的可信度,並返回可信度大於minConference的後件 Hm = calculationConf(subSet,Hm,supportData,brl,minConference) #當候選後件集合中只有一個後件的可信度大於最小可信度,則結束遞迴建立規則 if (len(Hm) > 1): rulesFromConseq(subSet, Hm, supportData, brl, minConference) #------------------關聯規則生成函式end--------------# if __name__ =='__main__': dataset = loadDataSet() L,returnSupportData = apriori(dataset,minSupport=0.5) rule = generateRules(L, returnSupportData, minConference =0.5)