APRIORI算法详解和python代码

APRIORI算法就是关联分析的一种算法

主要概念:频繁项集,关联规则,支持度,置信度。

频繁项集:经常出现的一些集合

关联规则:意味这两种元素具有某种强烈的联系

支持度:数据集中包含该项集的记录占总记录的比例

置信度:对应支持度相除

详细代码

from numpy import *


#导入数据
def loadDataSet():
    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]

#求出所有的元素
def createC1(dataSet):
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item])
    C1.sort()
    return map(frozenset, C1)  #将c1转化成不变集合


def scanD(D, Ck, minSupport): #D为全部数据集 由集合组成的集合
                              #CK为大小为k(包含k个元素)的候选集(一开始是由大小为1的元素组成的集合的集合)
                              #minSupport为设定的最小支持度
    ssCnt = {}    #创建一个空map
    for tid in D:   #枚举D中的每一个集合
        for can in Ck:    #枚举候选集中的每一个集合
            if can.issubset(tid):  #如果can是tid的一个子集
                ssCnt[can] = ssCnt.get(can, 0) + 1   #给can这个项集数量加1,
                                                     #get的第二个参数是字典不存在key值的时候的默认值
    numItems = float(len(D))   #求吃dataset中的数据个数
    retList = []   
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key] / numItems
        if support >= minSupport:
            retList.insert(0, key)     #这一行代表将频繁项集插入到列表首部
        supportData[key] = support
    return retList, supportData   ##返回值值retlist是支持度大于minSupport的,supportData记录各频繁项集的支持度


def aprioriGen(Lk, k):
    retList = []
    lenLk = len(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]   #提取了每一个集合的前k项
            L1.sort(); L2.sort()
            if L1 == L2:   #只有当前k-1项相同,最后一项不同的时候才进行合并
                retList.append(Lk[i] | Lk[j])
    return retList

def apriori(dataSet, minSupport = 0.5):
    C1 = createC1(dataSet)
    D = map(set, dataSet)  #map()方法中有两个参数,一个是函数,一个是list,
                           #返回值是一个list表示把序列中每一个元素用这一个函数处理
    L1, supportData = scanD(D, C1, minSupport)  #大小为1的频繁项
    L = [L1]    #把L1这个list存到L中
    k = 2
    while (len(L[k-2]) > 0):
        Ck = aprioriGen(L[k-2], k)   #访问上一个频繁项集,然后构造候选项  
        Lk, supK = scanD(D, Ck, minSupport)  #找出符合要求的本次集合
        supportData.update(supK) #更新字典
        L.append(Lk)             #添加到list中
        k += 1
    return L, supportData 




def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
    #生成候选规则集
    #实质每次生成了后面的规则的一个集合,每层调用合并一次基大小加1
    m = len(H[0])  #m从1开始
    if(len(freqSet) > (m + 1)):  #如果频繁项集的大小大于m+1说明还不止一种分法
        Hmpl = aprioriGen(H, m + 1)   #合并成元素大小是m+1的list
        Hmpl = calcConf(freqSet, Hmpl, supportData, brl, minConf)  #然后去评估置信度   
        if (len(Hmpl) > 1):  #如果频繁项集还能合并,则继续调用
            rulesFromConseq(freqSet, Hmpl, supportData, brl, minConf)

def calcConf(freqSet, H, supportData, brl, minConf=0.7):
    # 对候选规则集进行评估 
    #计算规则的可信度,并过滤出满足最小可信度要求的规则
    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 generateRules(L, supportData, minConf=0.7):     #关联规则生成函数
                                                    #L是频繁项集和,sup是支持度,最小置信度默认是0.7
                                                    #如果是
    bigRuleList = []
    for i in range(1, len(L)):
        for freqSet in L[i]:    #freset第i个list
            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




if __name__ == '__main__':
    dataSet = loadDataSet()
    print "数据集是: ", dataSet
    C1 = createC1(dataSet)
    D = map(set, dataSet)
    #print D
    L1, suppDat = scanD(D, C1, 0.5)
    print "只含一个元素的频繁项集", L1
    L, suppData = apriori(dataSet)
    print "所有频繁项集", L
    print "===========================完美分割线========================="
    rules = generateRules(L, suppData, minConf = 0.5)
    print "===========================完美分割线========================="
    print "关联规则树", rules
    print "===========================完美分割线========================="
    print "===========================完美分割线========================="
    L, suppData = apriori(dataSet, minSupport=0.7)
    print "所有频繁项集", L
    print "===========================完美分割线========================="
    rules = generateRules(L, suppData, minConf = 0.5)
    print "===========================完美分割线========================="
    print "关联规则树", rules
    print "===========================完美分割线========================="

你可能感兴趣的:(数据挖掘,数据挖掘算法,python,算法,数据,numpy)