機器學習實戰2:關聯規則:議會投票+毒蘑菇


  本人看過的關聯規則博文,很少有清晰的把關聯規則的算法說很明白的,希望讀者讀完本文可以有新的收獲。本文是在默認讀者有相關機器學習算法基礎的,總結和提升對關聯規則代碼實現的理解,並介紹相關案例。語言:python

  一 引言

  關聯規則起初是在購物籃分析中發現的,沃爾瑪超市在美國某地區啤酒和尿布放在一起賣,這種關聯規則有利於市場營銷決策的制定。

  關聯規則是非監督學習的一種。

  

  二 兩個重要的概念

  我們認定滿足支持度置信度的規則是有趣的,

    支持度:P(A),及項集A出現的概率(頻數);

    置信度:P(B / A), 條件概率; P(B / A)= P(AB)/P(A),所以支持度可以用來計算置信度,代碼是學習算法最好的途徑。

  

  三 Apriori算法

  網上很多文章介紹Apriori算法都是雲里霧里,下面梳理一下脈絡。

  

  核心是apriori原理:如果某個項集是頻繁的,那么它是所有子集也是頻繁的。

  apriori原理的精妙在於他的逆否命題,若子集不是頻繁的,則所有包含它的項集都是不頻繁的。這樣剪掉不頻繁項集時,就可以同時剪掉很多包含這個項集的不頻繁的項集了。若蠻力查找大頻項集,時間復雜度是指數型,例如4個項集,它的所有組合的復雜度是15。同理,可以剪掉后件不滿足置信度規則時,同時剪掉后件包含這個規則后件的規則。形象的說,看下圖:

  eg

  項集{0,1,2,3},計算所有的組合情況如下圖,好像一個格,時間復雜度是指數型的,按照項集元素數由小到大計算每個組合的支持度,{2,3}黑色圈不滿足最小支持度,由apriori定理,則所有以它為子集的項集均不滿足最小支持度,需要剪掉。  

  

  下面繼續考慮置信度,規則{012}->{3}不滿足最小置信度,由apriori定理,所有后件包含這條規則后件的規則需要剪掉,即二后件規則:{01}->{23},{02}->{1,3},{12}->{03}和三后件規則{0}->{123},{1}->{023},{2}->{013}。

  

  讀到這里有關聯規則基礎的人應該會有感悟,通過下面代碼介紹可以細致的明白apriori算法的機制。

 

  四 apriori實現

  1 加載demo數據集(可以改成真實數據集,讀文件):

from numpy import *

def loadDataSet():
    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]

  2 生成一頻繁項集作為起始點,即長度為1的頻繁集,圖中的第一層:使用frozenset結構是因為set不可以作為dict的關鍵字

def createC1(dataSet):#create one item
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item])
   
    C1.sort()
    # print C1   
    return map(frozenset, C1)#use frozen set so we
                            #can use it as a key in a dict    

  3 計算Ck支持度,並剪掉不滿足最小指出的項集。

def scanD(D, Ck, minSupport):#create one or more big frequence item
    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
    numItems = float(len(D))
    retList = []
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key]/numItems
        if support >= minSupport:
            retList.insert(0,key)
        supportData[key] = support
    return retList, supportData

  4 由m頻繁項集生成m+1頻繁項集:舉例,Ck為1頻繁項集{01}{12}{02},生成{012},有個技巧,只合並前m-2項一樣的項集,這樣不會重復操作,如這個例子,{01}和{12}不合並,{12}{02}也不合並,只有{01}{02}合並,生成最后的{012};否則前幾個合並都是重復的。值得注意的是0-3項集要排好序,否則前k-2個沒有比較的必要。

def aprioriGen(Lk, k): #creates Ck
    retList = []
    lenLk = len(Lk)
    # print 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()
            # print L1,'--',L2
            if L1==L2: #if first k-2 elements are equal
                retList.append(Lk[i] | Lk[j]) #set union
            # print retList
    return retList

  5 生成打頻項集的算法:

    思路,生成1頻項集,根據最小支持度過濾;依次由m頻項集生成m+1頻項集,直到m+1頻項集為空停止迭代。

def apriori(dataSet, minSupport = 0.5):
    C1 = createC1(dataSet)
    D = map(set, dataSet)
    L1, supportData = scanD(D, C1, minSupport)#create one big frequence item L1
    # print L1
    L = [L1]
    k = 2
    # print L
    while (len(L[k-2]) > 0):
        # print 'L[k-2]',L[k-2]
        # print L
        Ck = aprioriGen(L[k-2], k)
        Lk, supK = scanD(D, Ck, minSupport)#scan DB to get Lk
        supportData.update(supK)
        L.append(Lk)
        k += 1
    return L, supportData

  以上都是大頻項集的生成算法,下面繼續有趣的關聯規則的發現算法:

 

  6 計算后件為H的規則的置信度,代碼可以看出只是一個條件概率公式而已;根據最小置信度,篩選出有趣的規則;

def calcConf(freqSet, H, supportData, brl, minConf=0.7):
    prunedH = [] #create new list to return
    for conseq in H:
        conf = supportData[freqSet]/supportData[freqSet-conseq] #calc confidence
        if conf >= minConf: 
            brl.append((freqSet-conseq, conseq, conf))
            prunedH.append(conseq)
    return prunedH

  7 由后件數為m的規則集生成后件為后件數為m+1的規則集,並計算置信度;遞歸到沒有可以合並的規則集停止;

  直觀的過程可以查看上圖的格,eq {23}->{01}和{12}->{03} 合並為{2}->{013};因為標紅處前k-2相同,為了避免重復的合並操作,同上面打大頻項集合並。

def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):if (len(freqSet) > (m + 1)): #try further merging
        Hmp1 = aprioriGen(H, m+1)#create Hm+1 new candidates
        Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)if (len(Hmp1) > 1):    #need at least two sets to merge
            rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)

 

  8 產生關聯規則的最后算法:

  思路,由於規則的前后件均不能為空,所以只有二頻繁項集才能產生關聯規則;

       1)首先由二頻繁項集生成規則集,遍歷所有的二頻繁項集(每個元素輪流作為后件),根據最小置信度過濾規則集;

        eg 二頻繁項集{12},則計算規則{1}->{2}和{2}->{1}的置信度;

      2)依次迭代,在三大頻項集生成規則集(每個元素輪流作為后件),需要考慮規則的合並,

        eg 三大頻項集{123},則{12}->{3},{13}->{2},{23}->{1},此外考慮合並,{1}->{23},{2}->{13},{3}->{12},還要繼續合並:根據后件,前k-2個同的合並,本例前k-2個同的個數為0,所以停止,復雜的情況看步驟7;

def generateRules(L, supportData, minConf=0.7):  #supportData is a dict coming from scanD
    bigRuleList = []
    for i in range(1, len(L)):#only get the sets with two or more items
        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         

 

  五 應用

  關聯規則可以應用到哪些問題呢?

  購物籃分析,搜索引擎的查詢詞,國會投票,毒蘑菇的相似特征提取等;

 

  六 毒蘑菇的相似特征提取

   毒蘑菇部分數據集如下:

1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 107 113 
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114 
2 4 9 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115 
1 3 10 15 23 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 113 
2 3 9 16 24 28 34 37 39 40 53 54 59 63 67 76 85 86 90 94 99 109 114 
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 98 108 114 
2 4 9 15 23 26 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 108 115 
2 4 10 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 107 115 
1 3 10 15 23 25 34 36 38 43 52 54 59 63 67 76 85 86 90 93 98 110 114 
2 4 9 14 23 26 34 36 39 42 52 55 59 63 67 76 85 86 90 93 98 107 115 
2 3 10 14 23 27 34 36 39 42 52 55 59 63 67 76 85 86 90 93 99 108 114 
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 85 86 90 93 98 107 115 

  每一行代表一個蘑菇的特征,第一列是決策類,1代表有毒,2代表五毒;

  加載數據集:

dataset=[line.split() for line in open('mashroom.dat'),readline()]

  查找大頻率項集:

L,supp=apriori(dataset,0.3)
 apriori函數在算法部分已經實現,直接調用即可。

  有時候我們只需要查找大頻項集,並不需要關聯規則,具體問題具體分析即可。

 

  七 總結

  整體算法就有兩個核心,1計算滿足最小支持度的大頻率項集,2挖掘滿足最小置信度的有趣規則;暴力遍歷每種組 合的方式指數級,利用了apriori定理,剪掉了不滿足要求的小項集和小后件規則的同時,剪掉包含他們的大頻度項集和大后件規則;還有一點主意的是。按 照圖中格的形式,一層一層有小到大迭代。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM