Apriori的Python实现

来源:互联网 发布:淘宝老顾客回购率 编辑:程序博客网 时间:2024/05/29 02:52

Apriori算法:


扫描一遍数据库,得到一阶频繁项

用一阶频繁项构造二阶候选项

扫描数据库对二阶候选项进行计数,删除其中的非频繁项,得到二阶频繁项

然后构造三阶候选项,以此类推,直到无法构造更高阶的候选项,或到达频繁项集的最大长度限制。

Apriori.py

# 构建初始候选项集def createC1(dataSet):    C1 = []    for transaction in dataSet:        for item in transaction:            if [item] not in C1:                C1.append([item])    C1.sort()    return list(map(frozenset, C1))# 计算并筛选Ck中的项集在数据集合D中的支持度def scanD(D, Ck, minSupport):    ssCnt = {}    # 计算每个的出现次数    for tid in D:        for can in Ck:            if can.issubset(tid):                ssCnt[can] = ssCnt.get(can, 0) + 1    # 计算满足最小支持度的项集的集合和所有项集支持度信息的字典    numItems = len(D)    retList = []    supportData = {}    for key in ssCnt:        # 每个项集的支持度        support = float(ssCnt[key]) / numItems        # 将满足最小支持度的项集 加入retList        if support >= minSupport:            retList.append(key)        # 汇总支持度数据        supportData[key] = support    return retList, supportData# 由初始候选项集的集合Lk生成新的候选项集 k表示生成的新项集中所含有的元素个数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]            L1.sort()            L2.sort()            if L1 == L2:                retList.append(Lk[i] | Lk[j])    return retList# Aprior算法def apriori(dataSet, minSupport=0.5):    # 构建初始候选项集C1    C1 = createC1(dataSet)    D = list(map(set, dataSet))    # 构建初始的频繁项集 即所有项集只有一个元素    L, suppData = scanD(D, C1, minSupport)    L = [L]    k = 2    # 最初的L中的每个项集含有一个元素 新生成的项集每个项集应该依次多一个元素    while (len(L) > k - 2):        Ck = aprioriGen(L[k - 2], k)        Lk, supK = scanD(D, Ck, minSupport)        # 将新的项集的支持度数据加入原来的总支持度字典中        suppData.update(supK)        # 将符合最小支持度要求的项集加入L        if len(Lk) > 0:            L.append(Lk)        # 新生成的项集中的元素个数应不断增加        k += 1    # 返回所有满足条件的频繁项集的列表,和所有候选项集的支持度信息    return L, suppData# 规则生成与评价def calcConf(freqSet, H, supportData, brl, minConf=0.7):    prunedH = []    for conseq in H:        conf = supportData[freqSet] / supportData[freqSet - conseq]        if conf >= minConf:            brl.append((freqSet - conseq, conseq, conf))            prunedH.append(conseq)    return prunedH# 对频繁项集中元素超过2的项集进行合并def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):    m = len(H[0])    # 查看频繁项集是否大到移除大小为m的子集    if len(freqSet) > m + 1:        # 生产大小大一的子集        Hmp = aprioriGen(H, m + 1)        # 如果不止一条规则满足要求 进一步递归合并        Hmp = calcConf(freqSet, Hmp, supportData, brl, minConf)        if len(Hmp) > 1:            rulesFromConseq(freqSet, Hmp, supportData, brl, minConf)# 根据频繁项集L和所有项集的支持度supportData和最小可信度来生成规则def generateRules(L, supportData, minConf=0.7):    bigRuleList = []    for i in range(1, len(L)):        for freqSet in L[i]:            H = [frozenset([item]) for item in freqSet]            # 如果频繁项集中的元素个数大于2 需要进一步合并            if i > 1:                rulesFromConseq(freqSet, H, supportData, bigRuleList, minConf)            else:                calcConf(freqSet, H, supportData, bigRuleList, minConf)    return bigRuleListdef main():    # 创建数据集    def loadDataSet():        return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]    myData = loadDataSet()    L, suppData = apriori(myData, 0.5)    print('频繁项集:', L)    print('所有候选项集的支持度信息:')    for data in suppData:        print(data, ' : ', suppData[data])    rules = generateRules(L, suppData, 0.5)    print('生成规则:')    for rule in rules:        print(rule[0], ' --> ', rule[1], ' : ', rule[2])if __name__ == '__main__':    exit(main())

输出结果:

频繁项集: [[frozenset({1}), frozenset({3}), frozenset({2}), frozenset({5})], [frozenset({1, 3}), frozenset({2, 3}), frozenset({3, 5}), frozenset({2, 5})], [frozenset({2, 3, 5})]]所有候选项集的支持度信息:frozenset({1})  :  0.5frozenset({3})  :  0.75frozenset({4})  :  0.25frozenset({2})  :  0.75frozenset({5})  :  0.75frozenset({1, 3})  :  0.5frozenset({2, 3})  :  0.5frozenset({3, 5})  :  0.5frozenset({2, 5})  :  0.75frozenset({1, 2})  :  0.25frozenset({1, 5})  :  0.25frozenset({2, 3, 5})  :  0.5生成规则:frozenset({3})  -->  frozenset({1})  :  0.6666666666666666frozenset({1})  -->  frozenset({3})  :  1.0frozenset({3})  -->  frozenset({2})  :  0.6666666666666666frozenset({2})  -->  frozenset({3})  :  0.6666666666666666frozenset({5})  -->  frozenset({3})  :  0.6666666666666666frozenset({3})  -->  frozenset({5})  :  0.6666666666666666frozenset({5})  -->  frozenset({2})  :  1.0frozenset({2})  -->  frozenset({5})  :  1.0frozenset({5})  -->  frozenset({2, 3})  :  0.6666666666666666frozenset({3})  -->  frozenset({2, 5})  :  0.6666666666666666frozenset({2})  -->  frozenset({3, 5})  :  0.6666666666666666