基于Apriori算法的关联分析

关联分析是数据挖掘中的一种常用算法。它包括频繁项集挖掘和关联规则挖掘两个阶段。
频繁模式的挖掘有Apriori算法,还有FP-growth算法。下面的代码是利用Apriori算法挖掘频繁模式,然后找出关联规则的python实现。

#-*-coding: utf-8 -*-

#基于Apriori算法 挖掘频繁模式,找到关联规则

#本程序为利用Apriori算法挖掘频繁模式和关联规则。
#为了挖掘频繁模式,首先扫描数据集,通过最小支持度的约束,构建频繁1项集,然后由频繁k-1项集,构建出频繁k项集
#为了从频繁k项集中挖掘关联规则,先要确定最小置信度的约束,然后找出符合条件的关联规则

#首先,扫描记录,找到满足最小支持度的项集
#函数返回所有频繁项集列表
def loadDataSet():
    return [[1,3,4], [2,3,5], [1,2,3,5], [2,5]]

def createC1(dataSet):
    #构建频繁1项集,即每个候选项集只包含一个元素
    C1 = []  #C1表示频繁1项集
    for transaction in dataSet:
        for item in transaction:
            if [item] not in C1:
                C1.append([item])
    C1.sort()
    return map(frozenset, C1)

def scanD(D, Ck, minSupport):
    #计算Ck中的相机在数据集合D中的支持度
    #返回满足最小支持度的项集的集合,和所有项集支持度信息的字典
    temp = {}  #使用map来存储各个项集支持度信息
    for tid in D:
        for can in Ck:
            if can.issubset(tid):
                temp[can] = temp.get(can, 0)+1
    numItems = float(len(D))
    retList = []
    supportData = {}
    for key in temp:
        support = temp[key]/numItems
        if support >= minSupport: #如果满足最小置信度,加入retList
            retList.insert(0, key)
        supportData[key] = support
    return retList, supportData

def aprioriGen(Lk, k):
    #初始候选集Lk生成频繁k项集
    retList = []
    lenLk = len(Lk)
    #这两个for循环是重点,从k-1项集生成k项集
    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):
                retList.append(Lk[i]|Lk[j]) #添加上的是两者并起来的元素
    return retList

def apriori(dataSet, minSupport = 0.5):
    C1 = createC1(dataSet)
    D = map(set, dataSet)
    #先构建初始频繁项集,即频繁1项集
    L1, suppData = scanD(D, C1, minSupport)
    L = [L1]
    k = 2 #新生成的下一个是频繁2项集,所以k=2

    while(len(L[k-2]) > 0):
        Ck = aprioriGen(L[k-2], k)
        Lk, supK = scanD(D, Ck, minSupport)
        suppData.update(supK) #将新的项集的支持度数据加入原来的总支持度字典中
        L.append(Lk) #将符合最小支持度要求的项集加入L
        k += 1
    return L, suppData

#上面是利用Apriori算法挖掘频繁模式集,
#下面是根据频繁项集挖掘关联规则

def calcConf(freqSet, H, supportData, brl, minConf = 0.7):
    #计算规则的可信度,返回满足最小可信度的规则。

    #freqSet(frozenset):频繁项集
    #H(frozenset):频繁项集中所有的元素
    #supportData(dic):频繁项集中所有元素的支持度
    #brl(tuple):满足可信度条件的关联规则
    #minConf(float):最小可信度
    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))
    return prunedH

def rulesFromConseq(freqSet, H, supportData, brl, minConf = 0.7):
    #对频繁项集中元素超过2的项集进行合并。

    #freqSet(frozenset):频繁项集
    #H(frozenset):频繁项集中的所有元素,即可以出现在规则右部的元素
    #supportData(dict):所有项集的支持度信息
    #brl(tuple):生成的规则
    m = len(H[0])
    if len(freqSet) > m+1:  # 从右边只有一个元素开始,如果还可以往右边加,就使用aprioriGen函数,继续往右边添加元素
                             #再进行计算,根据置信度添加关联规则。如果右边频繁向大于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):
    #根据频繁项集和最小可信度生成规则。

    #L(list):存储频繁项集
    #supportData(dict):存储着所有项集(不仅仅是频繁项集)的支持度
    #minConf(float):最小可信度
    bigRuleList = []
    for i in range(1, len(L)):
        for freqSet in L[i]:
            H1 = [frozenset([item]) for item in freqSet] #将每个频繁模式集中的元素放入H1中
            if i>1:   #如果是频繁2项集,可以直接根据置信度直接生成规则。如果频繁3项集及以上,右侧的元素个数就不确定了,所以需要继续传入函数
                rulesFromConseq(freqSet, H1, supportData,bigRuleList,minConf)
            else:
                calcConf(freqSet, H1, supportData, bigRuleList, minConf)
    return bigRuleList


if __name__ == '__main__':
    # 导入数据集
    myDat = loadDataSet()
    # 选择频繁项集
    L, suppData = apriori(myDat, 0.5)

    rules = generateRules(L, suppData, minConf=0.7)
    print 'rules:\n', rules

你可能感兴趣的:(知识点)