Apriori算法
- 優點:易編碼實現
- 缺點:在大數據集上可能較慢
- 適用數據類型:數值型或者標稱型
算法過程:
關聯分析是一種在大規模數據集中尋找有意思的關系的任務,這里的有意思的關系有兩種:頻繁項集(frequent item sets)或關聯規則(association rules)。
支持度(support):一個項集的支持度被定義為數據集中該項集的記錄所占的比例。
置信度(confidence):關聯規則A->B的置信度表示為support(A,B)/support(A)
單純暴力做的話有2^n-1個組合
Apriori原理:如果某個項集是頻繁的那么它的子項集也是頻繁的。
反過來看就是說一個項如果不是頻繁項的話,那么包含他的項也不是頻繁項
這里主要是兩個過程:
1.生成頻繁項集:
這是一個挺簡單的過程就是兩個集合C、L來回倒,C就是通過初選的集合(像是最原始的啊,組合出來的啊);L是通過支持度篩選的集合。過程大體如下:
1.根據原始數據集構建單個項組成的集合C1
2.根據C1計算L1
3.找出L1中可以的合並的得到C2
4.重復上述C2 -> L2 -> C3 ->.....->Ck -> Lk
2.推導出關聯規則:
通過上一步得到的頻繁項集,我們就只需要吧每個頻繁項集里能夠列出的規則都列出來,然后計算置信度,選出置信度符合要求的就可以了。
函數:
loadDataSet()
導入數據集,數據集包含多條list,每個list是一個項集createC1(dataSet)
創建C1,提取出所有單個的項,這里用frozenset的原因是后面要用這個作為字典的keyscanD(D, Ck, minSupport)
過濾掉Ck中不符合最小支持度的,返回滿足的Lk和最小支持度apprioriGen(Lk, k)
將Lk合並得到Ck+1,這里通過只對前k-1個元素進行比較,可以減少遍歷次數。比如合並{0,1},{0,2},{1,2}合並,只需要判斷一次就行apriori(dataSet, minsupport=0.5)
將上面的幾個函數綜合起來,完成整個過程。結束條件是不再能夠產生新的項集generateRules(L, supportData, minConf=0.7)
生成關聯規則的主函數,這里要從包含兩個項的頻繁項集開始判斷calcConf(freqSet, H, supportData, brl, minConf=0.7)
對於給定的頻繁項集freqSet和可以推斷出來的H計算置信度,得到關聯規則rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7)
這里的不同是H可以變得更復雜,比如說現在有{1,2,3}-->{1}{2},這里我們希望將H進一步合並得到{1,2}從而更加充分的發掘關聯規則。這是一個遞歸的過程知道無法再合並結束。
-
1 #coding=utf-8 2 def loadDataSet(): 3 return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]] 4 def creteC1(dataSet): 5 C1 = [] 6 for transaction in dataSet: 7 for item in transaction: 8 if [item] not in C1: 9 C1.append([item]) 10 C1.sort() 11 return map(frozenset,C1) 12 def scanD(D, Ck, minSupport): 13 ssCnt = {} 14 for tid in D: 15 for can in Ck: 16 if can.issubset(tid): 17 if ssCnt.has_key(can): 18 ssCnt[can] += 1 19 else: 20 ssCnt[can] = 1 21 numItems = float(len(D)) 22 retList = [] 23 supportData = {} 24 for key in ssCnt: 25 supprt = ssCnt[key] / numItems 26 if supprt >= minSupport: 27 retList.append(key) 28 supportData[key] = supprt 29 return retList,supportData 30 def appriGen(Lk,k): 31 retList = [] 32 lenLk = len(Lk) 33 for i in range(lenLk): 34 for j in range(i+1, lenLk): 35 L1 = list(Lk[i])[:k-2]#前k-1個 36 L2 = list(Lk[i])[:k-2] 37 L1.sort() 38 L2.sort() 39 if L1 == L2: 40 retList.append(Lk[i] | Lk[j]) 41 return retList 42 def apriori(dataSet, minSupport=0.5): 43 C1 = creteC1(dataSet) 44 D = map(set, dataSet) 45 L1, supportData = scanD(D,C1,minSupport=0.7) 46 L = [L1] 47 k=2 48 while len(L[k-2]) > 0: 49 Ck = appriGen(L[k-2], k) 50 Lk, supK = scanD(D, Ck, minSupport) 51 supportData.update(supK) 52 L.append(Lk) 53 k += 1 54 return L,supportData 55 def generateRules(L, supportData, minConf=0.7): 56 bigRules = [] 57 for i in range(1,len(L)):#從包含兩個的開始 58 for freqSet in L[i]: 59 H1 = [frozenset([item]) for item in freqSet] 60 if (i>1):#頻繁項集元素數目大於2 61 rulesFormConseq(freqSet,H1,supportData,bigRules,minConf) 62 else: 63 calcConf(freqSet,H1,supportData,bigRules,minConf) 64 return bigRules 65 def calcConf(freqSet, H, supportData,brl,minConf=0.7): 66 prunedH = [] 67 for conseq in H: 68 conf = supportData[freqSet] / supportData[freqSet - conseq] 69 print supportData[freqSet] , supportData[freqSet - conseq] 70 if conf >= minConf: 71 print freqSet-conseq,'-->',conseq,'conf',conf 72 brl.append((freqSet-conseq,conseq,conf)) 73 prunedH.append(conseq) 74 return prunedH 75 def rulesFromConseq(freqSet,H,supportData,brl,minConf=0.7): 76 m = len(H[0]) 77 if len(freqSet) > m+1: 78 Hmp1 = appriGen(H,m+1) 79 Hmp1 = calcConf(freqSet,Hmp1,supportData,brl,minConf) 80 if len(Hmp1)>1: 81 rulesFromConseq(freqSet,Hmp1,supportData,brl,minConf) 82 def main(): 83 dataSet = loadDataSet() 84 L,supportData = apriori(dataSet, minSupport=0.7) 85 print L 86 rules = generateRules(L,supportData,minConf=0.7) 87 print rules 88 89 if __name__ == '__main__': 90 main()
-
機器學習筆記索引
