1基本概念
購物籃事務(market basket transaction),如下表,表中每一行對應一個事務,包含唯一標識TID,和購買的商品集合。本文介紹一種成為關聯分析(association analysis)的方法,這種方法,可以從下表可以提取出,{尿布}—>牛奶.
兩個關鍵問題:1大型數據計算量很大。2發現的某種模式可能是虛假,偶然發生的。
2問題定義
把數據可以轉換為如下表的二元表示,非二元不在本文討論范圍
項集
項集的支持度計數:
關聯規則:
我們要發現,滿足最小支持度與最小置信度的規則。
l 頻繁項集(frequent itemset):發現滿足最小支持度閾值的所有項集,這些項集成為頻繁項集。
l 規則的產生:從上一步發現的頻繁項集中提取所有高置信度的規則,這些規則成為強規則(strong rule)
頻繁項集的產生
窮舉法:
利用格結構(lattice structure)產生所有候選項集(candidate itemset).
利用窮舉法,計算每個候選項集的支持度計數。但是該方法計算量太大。
先驗(apriori)原理:
如果一個項集是頻繁的,則的所有子集一定是頻繁的。若某項集是非頻繁的,則其所有的超級也一定是非頻繁的。
如下圖,若{c,d,e}是頻繁項集,則它的子集一定是頻繁項集。
項集{a,b}是非頻繁的,則其所有的超級也一定是非頻繁的,如下圖。
Aprior算法的頻繁項集產生
1. 確定每個1-項集的支持度計數,刪除不滿足最小支持度的1-項集。(步驟1,2)
2. 迭代:使用頻繁(k-1)項集,產生新的候選k項集(步驟5)
3. 為了對候選k項集計算支持度計數,再次掃描數據(6-10)
4. 刪去支持度小於最小支持度(minsup)的候選集
5. 當Fk=NULL,結束。
6. 候選集是所有頻繁i項集的交際。i=1,2…
方法:產生
(頻繁k-項集)。(step5)
函數aprior-gen的候選產生過程,合並一對頻繁k-1項集,僅當他們前k-2個項都相同時,即
Python代碼:
def aprioriGen(Lk,k):#create ck(k項集) retList=[] 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:#比較i,j前k-1個項若相同,和合並它倆 retList.append(Lk[i] | Lk[j])#加入新的k項集 | stanf for union return retList
支持度計數:算法(6-12)代碼
Python代碼:
def scanD(D,ck,minSupport):#dataset,a list of candidate set,最小支持率 ssCnt={} for tid in D: for can in ck: if can.issubset(tid): if not ssCnt.has_key(can): ssCnt[can]=1 else: ssCnt[can]+=1 numItem=float(len(D)) retList=[] supportData={} for key in ssCnt: support=ssCnt[key]/numItem if support>=minSupport: retList.insert(0,key) supportData[key]=support return retList,supportData#返回頻繁k項集,相應支持度
頻繁項集的產生:
def apriori(dataSet,minSupport=0.5): C1=createC1(dataSet) D=map(set,dataSet) L1,supportData=scanD(D,C1,minSupport)#利用k項集生成頻繁k項集(即滿足最小支持率的k項集) L=[L1]#L保存所有頻繁項集 k=2 while(len(L[k-2])>0):#直到頻繁k-1項集為空 Ck=aprioriGen(L[k-2],k)#利用頻繁k-1項集 生成k項集 Lk,supK= scanD(D,Ck,minSupport) supportData.update(supK)#保存新的頻繁項集與其支持度 L.append(Lk)#保存頻繁k項集 k+=1 return L,supportData#返回所有頻繁項集,與其相應的支持率
規則產生(mining rules)
定理:
例如下:若bcd ->a是低置信度的,則它的子代都是低置信度的。利用此定理可以避免不必要的計算,減少運算復雜度。
python代碼:
def calcConf(freqSet,H,supportData,brl,minConf=0.7): prunedH=[] for conseq in H:#后件中的每個元素 conf=supportData[freqSet]/supportData[freqSet-conseq] if conf>=minConf: print freqSet-conseq,'-->',conseq,'conf:',conf brl.append((freqSet-conseq,conseq,conf))#添加入規則集中 prunedH.append(conseq)#添加入被修剪過的H中 return prunedH def rulesFromConseq(freqSet,H,supportData,brl,minConf=0.7): m=len(H[0])#H是一系列后件長度相同的規則,所以取H0的長度即可 if (len(freqSet)>m+1): Hmp1=aprioriGen(H,m+1) Hmp1=calcConf(freqSet,Hmp1,supportData,brl,minConf) if (len(Hmp1)>1): rulesFromConseq(freqSet,Hmp1,supportData,brl,minConf) def generateRules(L,supportData,minConf=0.7): import pdb pdb.set_trace() bigRuleList=[]#存儲規則 for i in range(1,len(L)): for freqSet in L[i]: H1=[frozenset([item]) for item in freqSet] if(i>1): rulesFromConseq(freqSet,H1,supportData,bigRuleList,minConf) else: calcConf(freqSet,H1,supportData,bigRuleList,minConf) return bigRuleList
整個prior算法的python代碼
算法函數:
# -*- coding: utf-8 -*- """ Created on Wed Dec 04 22:25:57 2013 @author: Administrator """ def loadDataSet(): return [[1,3,4],[2,3,5],[1,2,3,5],[2,5]] def createC1(dataSet):#產生單個item的集合 C1=[] for transaction in dataSet: for item in transaction: if not [item] in C1: C1.append([item]) C1.sort() return map(frozenset,C1)#給C1.list每個元素執行函數 def scanD(D,ck,minSupport):#dataset,a list of candidate set,最小支持率 ssCnt={} for tid in D: for can in ck: if can.issubset(tid): if not ssCnt.has_key(can): ssCnt[can]=1 else: ssCnt[can]+=1 numItem=float(len(D)) retList=[] supportData={} for key in ssCnt: support=ssCnt[key]/numItem if support>=minSupport: retList.insert(0,key) supportData[key]=support return retList,supportData#返回頻繁k項集,相應支持度 def aprioriGen(Lk,k):#create ck(k項集) retList=[] 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:#比較i,j前k-1個項若相同,和合並它倆 retList.append(Lk[i] | Lk[j])#加入新的k項集 | stanf for union return retList def apriori(dataSet,minSupport=0.5): C1=createC1(dataSet) D=map(set,dataSet) L1,supportData=scanD(D,C1,minSupport)#利用k項集生成頻繁k項集(即滿足最小支持率的k項集) L=[L1]#L保存所有頻繁項集 k=2 while(len(L[k-2])>0):#直到頻繁k-1項集為空 Ck=aprioriGen(L[k-2],k)#利用頻繁k-1項集 生成k項集 Lk,supK= scanD(D,Ck,minSupport) supportData.update(supK)#保存新的頻繁項集與其支持度 L.append(Lk)#保存頻繁k項集 k+=1 return L,supportData#返回所有頻繁項集,與其相應的支持率 def calcConf(freqSet,H,supportData,brl,minConf=0.7): prunedH=[] for conseq in H:#后件中的每個元素 conf=supportData[freqSet]/supportData[freqSet-conseq] if conf>=minConf: print freqSet-conseq,'-->',conseq,'conf:',conf brl.append((freqSet-conseq,conseq,conf))#添加入規則集中 prunedH.append(conseq)#添加入被修剪過的H中 return prunedH def rulesFromConseq(freqSet,H,supportData,brl,minConf=0.7): m=len(H[0])#H是一系列后件長度相同的規則,所以取H0的長度即可 if (len(freqSet)>m+1): Hmp1=aprioriGen(H,m+1) Hmp1=calcConf(freqSet,Hmp1,supportData,brl,minConf) if (len(Hmp1)>1): rulesFromConseq(freqSet,Hmp1,supportData,brl,minConf) def generateRules(L,supportData,minConf=0.7): bigRuleList=[]#存儲規則 for i in range(1,len(L)): for freqSet in L[i]: H1=[frozenset([item]) for item in freqSet] if(i>1): rulesFromConseq(freqSet,H1,supportData,bigRuleList,minConf) else: calcConf(freqSet,H1,supportData,bigRuleList,minConf) return bigRuleList
測試代碼:
import apriori dataSet=apriori.loadDataSet() C1=apriori.createC1(dataSet) D=map(set,dataSet) L1,suppData0=apriori.scanD(D,C1,0.5) L,suppData=apriori.apriori(dataSet) print L rules=apriori.generateRules(L,suppData,minConf=0.5)
參數文獻:
1數據挖掘導論
2machine learning in action













![clip_image004[4] clip_image004[4]](/image/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNTUwMDQzLzIwMTMxMi8wOTExMjU1My1jNDc2NTNlNTQxNjQ0N2Q3OWM0MWMzNWQzMWRlZWZkZC5qcGc=.png)
![clip_image006[4] clip_image006[4]](/image/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNTUwMDQzLzIwMTMxMi8wOTExMjU1Ni05YzI1OTU0MmNkYmY0NzBlODMyYjE1OTkyMmQ5NGExYy5qcGc=.png)
![clip_image008[4] clip_image008[4]](/image/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvNTUwMDQzLzIwMTMxMi8wOTExMjYwMS00NTg0N2FlYjhmYWM0YzJiODdmZTMxMjQ2YzEyMjlmMy5qcGc=.png)