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