机器学习实战第11章——使用 Apriori 算法进行关联分析

Posted weiququ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了机器学习实战第11章——使用 Apriori 算法进行关联分析相关的知识,希望对你有一定的参考价值。

从大规模数据集中寻找物品间的隐含关系被称作关联分析(association analysis)或者关联规则学习(association rule learning)。
 
优点:简单
缺点:对大数据集比较慢
使用数据类型:数值型或者标称型
 
一、相关定义:
频繁项集:经常出现在一起的物品集合
关联规则:两种物品之间存在很强的关系,表示为P->H
support支持度:该项集在所有数据集中出现的次数所占的比例,Support(P,H) = NUM(P,H) / N
confidence置信度:Confidence(P->H) = support({P,H}) / support({P}) = P(H|P)
 
二、使用Apriori算法发现频繁项
原理:如果某个项集是频繁的,那么它的子集也是频繁的,也就是说如果一个项集是非频繁的,那么它的超集也是非频繁的。
输入:数据集D,支持度阈值s
输出:最大频繁k项集
1. k=1, 扫描整个数据集,得到所有出现过的数据,作为初始候选频繁1项集candiItem1
2. 计算频繁k项集
    a)  计算候选频繁k项集的支持度
    b)去掉所有支持度小于阈值s的项集,得到频繁k项集。
    c)如果频繁k项集为空,则直接返回频繁k-1项集,算法结束。如果得到的频繁项集只有一项,直接返回频繁k项集,算法结束
    d)  基于频繁k项集,连接生成候选频繁k+1项集
3. 令k=k+1,进入步骤2
实现代码:
def loadDataSet():
    return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
 
 
def createC1(DataSet):
    """
    创建初始候选频繁项集c1
    :param DataSet:
    :return:
    """
    C1 = []
    for lineSet in DataSet:
        for item in lineSet:
            if not [item] in C1:
                C1.append([item])
    C1.sort()
    return list(map(frozenset,C1))  #use forzen set so we can use it to as a key in dict
 
 
def getLk(DataSet, Ck, minSupport):
    """
    返回ck的频繁项集,和支持度
    :param C:
    :return:
    """
    Lk = [];    #频繁项集
    Cksupport = {};   #CK的支持度
    Lksupport = {}; #LK的支持度
    numItem = float(len(DataSet))
    for C in Ck:
        for D in DataSet:
            if set(C).issubset(set(D)):
                if C not in Cksupport: Cksupport[C] = 1
                else: Cksupport[C] += 1
 
    for key in Cksupport:
        sup = Cksupport[key] / numItem
        if sup >= minSupport:
            Lk.append(key)
            Lksupport[key] = sup
    return Lk, Lksupport
 
 
def aprioriGen(Lk):
    """
    根据频繁项集LK生成Ck+1
    :param Lk:
    :return:
    """
    Ck = []
    for i in range(len(Lk)-1):
        for j in range(i + 1, len(Lk)):
            c = list(set(Lk[i]).union(set(Lk[j])))
            if c not in Ck:
                Ck.append(c)
    return list(map(frozenset, Ck))
 
 
def aprior(DataSet, minSupport=0.5):
     """
    生成频繁项集
    :param DataSet:原始数据集
    :return:
        L:满足最小支持度的频繁项集
        supportData:支持度数据集
    """
    k = 1
    C1 = createC1(DataSet)
    L1, supportData = getLk(DataSet, C1, minSupport)
    L = [L1]
    C = [C1]
    while(len(L[-1]) > 1):
        k += 1
        C.append(aprioriGen(L[-1]))
        Lk, LkSupport = getLk(DataSet, C[k-1], minSupport)
        L.append(Lk)
        supportData.update(LkSupport)
    # if len(L[-1]) == 1 or len(L) <= 1:
    #     for item in L[-1]:
    #         supportData.update({item : LSupport[item]})
    #     return L[-1], LSupport
    # else :
    #     for item in L[-2]:
    #         supportData.update({item : LSupport[item]})
    #     return L[-2], LSupport
    return L, supportData
 
if __name__ == ‘__main__‘:
    DataSet = loadDataSet()
    L, LSupport = aprior(DataSet, 0.7)
    print(L, LSupport)  
结果:
技术分享图片
 
三、从频繁项中挖掘关联规则
一条规则P->H的置信度为support(P,H)/support(P)
输入:最大频繁项集L,对应的支持度数据集supportData,最低置信度minConf
输出:满足最低置信度的规则bigRuleList
对每个频繁项集Li:
    如果元素个数大于等于2:
        生成关联规则(获取单个元素的H1, P=Li-Hk)
        计算规则置信度,将置信度大于minConf的规则存入bigRuleList
        while:H的长度小于len(Li)-1:
        根据Hk,生成关联规则(获取H(k+1), P=Li-H(k+1))
        计算规则置信度,将置信度大于minConf的规则存入bigRuleList
返回bigRuleList
 
实现代码:
def generateRules(L, supportData, minConf=0.7):
    """
    生成满足最小可信度的关联规则
    :param L: 最大频繁项集
    :param supportData: 支持度数据集
    :param minConf: 最低可信度
    :return: 满足最小可信度的关联规则
    """
    bigRuleList = []
    for i in range(len(L)):
        for freqSet in L[i]:
            if len(freqSet) >= 2:
                H1 = [frozenset([item]) for item in freqSet]
                prunedH = calConf(freqSet, supportData, minConf, H1, bigRuleList)
                while len(prunedH) < len(H1) - 1:
                    Hk = aprioriGen(prunedH)   #CREATE H(K+1)
                    prunedH = calConf(freqSet, supportData, minConf, Hk, bigRuleList)
 
 
 
def calConf(Lk, supportData, minCof, H, bigRuleList):
    """
    计算规则的可信度,返回满足最小可信度的H
    :param Lk:  频繁项集
    :param supportData: 支持度
    :param minCof:  最小可信度
    :param H:  规则的后件集合
    :param bigRuleList: 满足最小可信度的生成规则
    :return: prunedH    满足最小可信度的后件
    """
    prunedH = []
    confData = {}
    for conseq in H:
        conf = supportData[Lk] / supportData[frozenset(Lk)-frozenset(conseq)]
        if conf >= minCof:
            print(Lk-conseq, ‘-->‘, conseq, ‘conf:‘, conf)
            bigRuleList.append((Lk - conseq, H, conf))
            prunedH.append(conseq)
    return prunedH
if __name__ == ‘__main__‘:
    DataSet = loadDataSet()
    L, LSupport = aprior(DataSet, 0.7)
    print(L, LSupport)
    generateRules(L, LSupport, 0.5)
 
技术分享图片

 

  

以上是关于机器学习实战第11章——使用 Apriori 算法进行关联分析的主要内容,如果未能解决你的问题,请参考以下文章

Apriori算法与FP-growth算法

《机器学习实战》 书上的Apriori算法 内循环为啥只执行了一次

机器学习实战精读--------Apriori算法

《机器学习实战》使用Apriori算法和FP-growth算法进行关联分析(Python版)

apriori算法的代码,python实现,参考《机器学习实战》

机器学习实战-第3章-决策树算法(ID3)