1. 程式人生 > 實用技巧 >Django框架之drf 之一 [restful規範 APIview原始碼分析 Request類分析 序列化元件 ]

Django框架之drf 之一 [restful規範 APIview原始碼分析 Request類分析 序列化元件 ]

#請從最後的main方法開始看起
Apriori演算法,頻繁項集演算法
A 1,   B 2,   C 3,   D 4,   E 5
1 [A C D]       1 3 4
2 [B C E]       2 3 5
3 [A B C E]     1 2 3 5
4 [B E]         2 5

min_support = 2  或  = 2/4
'''

def item(dataset):      #求第一次掃描資料庫後的 候選集,(它沒法加入迴圈)
    c1 = []     #存放候選集元素

    for x in dataset:       #就是求這個資料庫中出現了幾個元素,然後返回
        for y in x:
            if [y] not in c1:
                c1.append( [y] )
    c1.sort()
    #print(c1)
    return c1

def get_frequent_item(dataset, c, min_support):
    cut_branch = {}     #用來存放所有項集的支援度的字典
    for x in c:
        for y in dataset:
            if set(x).issubset(set(y)):     #如果 x 在 y中,就把對應元素後面加 1
                cut_branch[tuple(x)] = cut_branch.get(tuple(x), 0) + 1     #cut_branch[y] = new_cand.get(y, 0)表示如果字典裡面沒有想要的關鍵詞,就返回0
    #print(cut_branch)

    Fk = []       #支援度大於最小支援度的項集,  即頻繁項集
    sup_dataK = {}  #用來存放所有 頻繁 項集的支援度的字典

    for i in cut_branch:
        if cut_branch[i] >= min_support:    #Apriori定律1  小於支援度,則就將它捨去,它的超集必然不是頻繁項集
            Fk.append( list(i))
            sup_dataK[i] = cut_branch[i]
    #print(Fk)
    return Fk, sup_dataK

def get_candidate(Fk, K):       #求第k次候選集
    ck = []    #存放產生候選集

    for i in range(len(Fk)):
        for j in range(i+1, len(Fk)):
            L1 = list(Fk[i])[:K-2]
            L2 = list(Fk[j])[:K-2]
            L1.sort()
            L2.sort() #先排序,在進行組合

            if L1 == L2:
                if K > 2:       #第二次求候選集,不需要進行減枝,因為第一次候選集都是單元素,且已經減枝了,組合為雙元素肯定不會出現不滿足支援度的元素
                    new = list(set(Fk[i]) ^ set(Fk[j]) ) #集合運算 對稱差集 ^ (含義,集合的元素在t或s中,但不會同時出現在二者中)
                    #new表示,這兩個記錄中,不同的元素集合
                    # 為什麼要用new? 比如 1,2     1,3  兩個合併成 1,2,3   我們知道1,2 和 1,3 一定是頻繁項集,但 2,3呢,我們要判斷2,3是否為頻繁項集
                    #Apriori定律1 如果一個集合不是頻繁項集,則它的所有超集都不是頻繁項集
                else:
                    new = set()
                for x in Fk:
                    if set(new).issubset(set(x)) and list(set(Fk[i]) | set(Fk[j])) not in ck:  #減枝 new是 x 的子集,並且 還沒有加入 ck 中
                        ck.append( list(set(Fk[i]) | set(Fk[j])) )
    #print(ck)
    return ck

def Apriori(dataset, min_support = 2):
    c1 = item (dataset) #返回一個二維列表,裡面的每一個一維列表,都是第一次候選集的元素
    f1, sup_1 = get_frequent_item(dataset, c1, min_support)       #求第一次候選集

    F = [f1]      #將第一次候選集產生的頻繁項集放入 F ,以後每次掃描產生的所有頻繁項集都放入裡面
    sup_data = sup_1       #一個字典,裡面存放所有產生的候選集,及其支援度

    K = 2 #從第二個開始迴圈求解,先求候選集,在求頻繁項集

    while (len(F[K-2]) > 1):  #k-2是因為F是從0開始數的     #前一個的頻繁項集個數在2個或2個以上,才繼續迴圈,否則退出
        ck = get_candidate(F[K-2], K)  #求第k次候選集
        fk, sup_k = get_frequent_item(dataset, ck, min_support)     #求第k次頻繁項集

        F.append(fk)    #把新產生的候選集假如F
        sup_data.update(sup_k)  #字典更新,加入新得出的資料
        K+=1
    return F, sup_data    #返回所有頻繁項集, 以及存放頻繁項集支援度的字典

if __name__ == '__main__':
    dataset = [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]       #裝入資料 二維列表
    F, sup_data = Apriori(dataset, min_support = 2)   #最小支援度設定為2

    print("具有關聯的商品是{}".format(F))   #帶變數的字串輸出,必須為字典符號表示
    print('------------------')
    print("對應的支援度為{}".format(sup_data))
    ```