最近看了關聯算法中的Apriori沒看懂,這次看了一些論文總算看懂了,不過還是沒能夠自己實現。在github搜到一些代碼看,看的不很懂,這里先貼上(當中有自己加的注釋),有時間再補充研究。
# -*- coding: utf-8 -*- """ Created on Wed Nov 30 10:05:42 2016 @author: Administrator """ from numpy import * import itertools support_dic = {} #生成原始數據,用於測試 def loadDataSet(): return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]] #獲取整個數據庫中的一階元素 # C1 = {1, 2, 3, 4, 5} def createC1(dataSet): C1 = set([]) for item in dataSet: C1 = C1.union(set(item)) return [frozenset([i]) for i in C1] #輸入數據庫(dataset) 和 由第K-1層數據融合后得到的第K層數據集(Ck), #用最小支持度(minSupport)對 Ck 過濾,得到第k層剩下的數據集合(Lk) def getLk(dataset, Ck, minSupport): global support_dic Lk = {} #計算Ck中每個元素在數據庫中出現次數 for item in dataset: for Ci in Ck: if Ci.issubset(item): if not Ci in Lk: Lk[Ci] = 1 else: Lk[Ci] += 1 #用最小支持度過濾 Lk_return = [] for Li in Lk: support_Li = Lk[Li] / float(len(dataSet)) if support_Li >= minSupport: Lk_return.append(Li) support_dic[Li] = support_Li return Lk_return #將經過支持度過濾后的第K層數據集合(Lk)融合 #得到第k+1層原始數據Ck1 '''連接步''' def genLk1(Lk): Ck1 = [] for i in range(len(Lk) - 1): for j in range(i + 1, len(Lk)): if sorted(list(Lk[i]))[0:-1] == sorted(list(Lk[j]))[0:-1]: Ck1.append(Lk[i] | Lk[j]) return Ck1 #遍歷所有二階及以上的頻繁項集合 def genItem(freqSet, support_dic): for i in range(1, len(freqSet)): for freItem in freqSet[i]: genRule(freItem) #輸入一個頻繁項,根據“置信度”生成規則 #采用了遞歸,對規則樹進行剪枝 def genRule(Item, minConf=0.7): if len(Item) >= 2: for element in itertools.combinations(list(Item), 1): if support_dic[Item] / float(support_dic[Item - frozenset(element)]) >= minConf: print(str([Item - frozenset(element)]) + "----->" + str(element)) print (support_dic[Item] / float(support_dic[Item - frozenset(element)])) genRule(Item - frozenset(element)) #輸出結果 if __name__ == '__main__': dataSet = loadDataSet() result_list = [] Ck = createC1(dataSet) #循環生成頻繁項集合,直至產生空集 while True: Lk = getLk(dataSet, Ck, 0.5) if not Lk: break result_list.append(Lk) Ck = genLk1(Lk) if not Ck: break #輸出頻繁項及其“支持度” print(support_dic) #輸出規則 genItem(result_list, support_dic)
輸出: