基於python 的Apriori演算法,pythonApriori演算法

來源:互聯網
上載者:User

基於python 的Apriori演算法,pythonApriori演算法

 Apriori algorithm是關聯規則裡一項基本演算法。是由Rakesh Agrawal和Ramakrishnan Srikant兩位博士在1994年提出的關聯規則挖掘演算法。關聯規則的目的就是在一個資料集中找出項與項之間的關係,也被稱為購物藍分析 (Market Basket analysis),因為“購物藍分析”很貼切的表達了適用該演算法情景中的一個子集。
 該演算法的具體思想可以參考這個網址瞭解:
 Apriori演算法詳解
 接下來,我向分享如何用代碼實現Apriori演算法,步驟如下:
 1.建立apriori類
 

class Apriori:    def __init__(self,min_sup=0.2,dataDic={}):        self.data = dataDic  ##構建資料記錄詞典,形如{'T800': ['I1', 'I2', 'I3', 'I5'],...}        self.size = len(dataDic) #統計資料記錄的個數        self.min_sup = min_sup  ##最小支援度的閾值        self.min_sup_val = min_sup * self.size ##最小支援度計數

2.過濾掉小於最小支援度閾值的物品

 def find_frequent_1_itemsets(self):        FreqDic = {} #{itemset1:freq1,itemsets2:freq2},用於統計物品的支援度計數        for event in self.data:  ##event為每一條記錄,如T800            for item in self.data[event]: ##item就是I1,I2,I3,I4,I5                if item in FreqDic:                    FreqDic[item] += 1                else:                    FreqDic[item] = 1        L1 = []        for itemset in FreqDic:            if FreqDic[itemset] >= self.min_sup_val: ##過濾掉小於最小支援度閾值的物品                L1.append([itemset])        return L1

3.過濾掉非頻繁項集

  def has_infrequent_subset(self,c,L_last,k):        ## c為當前集合,L_last為上一個頻繁項集的集合,k為當前頻繁項集內的元素個數,        ## 該函數用於檢查當前集合的子集是否 都為頻繁項集        subsets = list(itertools.combinations(c,k-1)) #itertools是排列組合模組,目的就c分解,如[1,2,3]將分成[(1,2),(1,3),(2,3)]        for each in subsets:            each = list(each) #將元組轉化為列表            if each not in L_last:  ##子集是否 都為頻繁項集                return True        return False

補充說明:
itertools是排列組合模組,例如 list(itertools.combinations([1,2,3],2))就能分解成[(1,2),(1,3),(2,3)]
具體使用可以參考:http://www.jb51.net/article/34921.htm

4.合并形成新的頻繁項集

  def apriori_gen(self,L_last): #L_last means frequent(k-1) itemsets        k = len(L_last[0]) + 1        Ck = []        ##        for itemset1 in L_last:            for itemset2 in L_last:                #join step                flag = 0                for i in range(k-2):                    print k-2                    if itemset1[i] != itemset2[i]:                        flag = 1 ##若前k-2項中如果有一個項是不相等,新合并的集合是不可能是頻繁項集                        break;                if flag == 1:continue                if itemset1[k-2] < itemset2[k-2]:                    c = itemset1 + [itemset2[k-2]]                else:                    continue                #pruning setp                if self.has_infrequen`t`_subset(c,L_last,k):##判斷子集是否為頻繁項集                    continue                else:                    Ck.append(c)        return Ck

5.關聯分析迭代形成頻繁項集

 def do(self):        L_last = self.find_frequent_1_itemsets() ##過濾掉小於最小支援度閾值的物品        L = L_last        i = 0        while L_last != []:            Ck = self.apriori_gen(L_last) ##合并形成新的頻繁項集            FreqDic = {}            for event in self.data:                #get all suported subsets                for c in Ck: ##統計新形成的頻繁項集的個數                    if set(c) <= set(self.data[event]):#判斷新合成的頻繁項目是否為資料記錄的子集                        if tuple(c) in FreqDic:                            FreqDic[tuple(c)]+=1                        else:                            FreqDic[tuple(c)]=1            print FreqDic            Lk = []            for c in FreqDic:                print c                print '------'                if FreqDic[c] > self.min_sup_val:##判斷新形成的頻繁項集是否大於最小支援度的閾值                    Lk.append(list(c))            L_last = Lk            L += Lk        return L  ## L就是新形成的頻繁項集的集合

測試範例
Data = {'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']}

完整代碼:

#! -*- coding:utf-8 -*-import itertoolsclass Apriori:    def __init__(self,min_sup=0.2,dataDic={}):        self.data = dataDic  ##構建資料記錄詞典,形如{'T800': ['I1', 'I2', 'I3', 'I5'],...}        self.size = len(dataDic) #統計資料記錄的個數        self.min_sup = min_sup  ##最小支援度的閾值        self.min_sup_val = min_sup * self.size ##最小支援度計數    def find_frequent_1_itemsets(self):        FreqDic = {} #{itemset1:freq1,itemsets2:freq2},用於統計物品的支援度計數        for event in self.data:  ##event為每一條記錄,如T800            for item in self.data[event]: ##item就是I1,I2,I3,I4,I5                if item in FreqDic:                    FreqDic[item] += 1                else:                    FreqDic[item] = 1        L1 = []        for itemset in FreqDic:            if FreqDic[itemset] >= self.min_sup_val: ##過濾掉小於最小支援度閾值的物品                L1.append([itemset])        return L1    def has_infrequent_subset(self,c,L_last,k):        ## c為當前集合,L_last為上一個頻繁項集的集合,k為當前頻繁項集內的元素個數,        ## 該函數用於檢查當前集合的子集是否 都為頻繁項集        subsets = list(itertools.combinations(c,k-1)) #itertools是排列組合模組,目的就c分解,如[1,2,3]將分成[(1,2),(1,3),(2,3)]        for each in subsets:            each = list(each) #將元組轉化為列表            if each not in L_last:  ##子集是否 都為頻繁項集                return True        return False    def apriori_gen(self,L_last): #L_last means frequent(k-1) itemsets        k = len(L_last[0]) + 1        Ck = []        ##        for itemset1 in L_last:            for itemset2 in L_last:                #join step                flag = 0                for i in range(k-2):                    print k-2                    if itemset1[i] != itemset2[i]:                        flag = 1 ##若前k-2項中如果有一個項是不相等,新合并的集合是不可能是頻繁項集                        break;                if flag == 1:continue                if itemset1[k-2] < itemset2[k-2]:                    c = itemset1 + [itemset2[k-2]]                else:                    continue                #pruning setp                if self.has_infrequent_subset(c,L_last,k):##判斷子集是否為頻繁項集                    continue                else:                    Ck.append(c)        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) ##合并形成新的頻繁項集            FreqDic = {}            for event in self.data:                #get all suported subsets                for c in Ck: ##統計新形成的頻繁項集的個數                    if set(c) <= set(self.data[event]):#判斷新合成的頻繁項目是否為資料記錄的子集                        if tuple(c) in FreqDic:                            FreqDic[tuple(c)]+=1                        else:                            FreqDic[tuple(c)]=1            print FreqDic            Lk = []            for c in FreqDic:                print c                print '------'                if FreqDic[c] > self.min_sup_val:##判斷新形成的頻繁項集是否大於最小支援度的閾值                    Lk.append(list(c))            L_last = Lk            L += Lk        return L  ## L就是新形成的頻繁項集的集合#******Test******Data = {'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']}a=Apriori(dataDic=Data)# print a.do()a.do()

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.