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

Apriori算法:如果某个项集是频繁的,那么它的所有子集也是频繁的。

生成候选项集:

数据集扫描:
对数据集中的每条交易记录
对每个候选项集can
检查一下can是否是tran的子集
如果是,can增加
对每个候选项集:
如果其支持度不低于最小值,则保留该项集

Apriori算法中的辅助函数:

#创建一个用于测试的简单数据集
def loadDataSet():
    return [[1, 3, 4], [2, 3, 5],[1, 2, 3, 5],[2, 5]]

#构建第一个候选项集的列表C1,存储不重复的项值
def createC1(dataSet):
    C1 = []
    #扫描数据集
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item]) #添加只包含该物品项的一个列表,Python不能创建只有一个整数的集合,所以这里必须使用列表
    C1.sort()#对大列表进行排序
    #将每个单元素列表映射到frozenset()
    return list(map(frozenset, C1)) #frozenset类型,不可以改变,可以将集合作为字典键值使用
    #python3.6 map()求长度改成list(map())

#数据集Ck,包含候选集合的列表D以及感兴趣项集的最小支持度minSupport
#用于从C1生成L1
def scanD(D, Ck, minSupport):
    ssCnt = {} #创建空字典
    #遍历数据集中所有交易记录以及C1中的所有候选集
    for tid in D:
        for can in Ck:
            #issubset()判断集合的所有元素是否都包含在指定集合
            if can.issubset(tid):
                #has_key()用于判断键是否存在于字典中 python3.6后改成__contain__
                if not ssCnt.__contain__(can):
                ssCnt[can]=1 #不存在设为1
                else:ssCnt[can] += 1 #存在加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

Apriori算法:

#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()
            #如果这两个集合的前面k-2个元素都相等,那么就将这两个集合合成一个大小为k的集合
            if L1==L2:
                retList.append(Lk[i] | Lk[j]) #取并集
    return retList

#{0},{1},{2}的排列组合,如果一个个匹配会得到3个{0,1,2},如果第一个元素相等再取并集 可以直接得到{0,1,2}

def apriori(dataSet, minSupport = 0.5):
    C1 = createC1(dataSet)
    D = list(map(set, dataSet)) #将set()映射到dataSet列表中的每一项
    L1, supportData = scanD(D, C1, minSupport) #创建L1
    L = [L1] #放入列表L中
    k = 2 #L1只有两个元素
    while(len(L[k-2]) > 0):
        Ck = aprioriGen(L[k-2], k)#创建Ck 剩下的K-2个
        Lk, supK = scanD(D, Ck, minSupport)#基于Ck来创建Lk
        supportData.update(supK) #更新到supK
        L.append(Lk) #Lk加入列表L
        k += 1 #元素增加一个
    return L,supportData

从频繁项集中挖掘关联规则

#频繁项集列表L,supportData包含那些频繁项集支持数据的字典,minConf最小可信度阈值
def generateRules(L, supportData, minConf=0.7):
    bigRuleList = [] #包含可信度的规则列表
    for i in range(1, len(L)):
        for freqSet in L[i]:
            #遍历L中的每一个频繁项集,并对每个频繁项集创建只包含单个元素的列表H1
            H1 = [frozenset([item]) for item in freqSet]
            if(i > 1):
                rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)#频繁项集的元素数目超过2,那么进行对它进行进一步的合并
            else:
                calcConf(freqSet, H1, supportData, bigRuleList, minConf)#如果项集中只有两个元素,使用calcConf()来计算可信度值
    return bigRuleList

#生成候选规则集合
def calcConf(freqSet, H, supportData, br1, minConf=0.7):
    prunedH = [] #保存规则
    for conseq in H:
        #计算最小可信度值
        conf = supportData[freqSet]/supportData[freqSet-conseq]
        #如果某条规则满足最小可信度值
        if conf >= minConf:
            print(freqSet-conseq,'-->',conseq,'conf',conf)
            #对br1进行填充,br1是前面通过检查的bigRuleList
            br1.append((freqSet-conseq, conseq, conf))
            # 通过检查的规则被返回
            prunedH.append(conseq)
    return prunedH

#对规则进行评估 H可以出现在规则右部的元素列表
def rulesFromConseq(freqSet, H, supportData, br1, minConf=0.7):
    m = len(H[0])#先计算H中的频繁集大小m
    #查看该频繁项集是否大到可以移除大小为m的子集,如果可以就移除
    if (len(freqSet) > (m + 1)):
        Hmp1 = aprioriGen(H, m+1)#生成H中元素的无重复组合
        Hmp1 = calcConf(freqSet, Hmp1, supportData, br1, minConf)#测试它们的可信度以确定是否满足要求
        if (len(Hmp1) > 1):
            rulesFromConseq(freqSet, Hmp1, supportData, br1, minConf)



if __name__ == '__main__':
    dataSet = loadDataSet()
    L, supportData = apriori(dataSet,0.5)
    rules = generateRules(L, supportData, 0.7)
    print(rules)

你可能感兴趣的:(机器学习实战,python,机器学习)