关联规则挖掘算法-apriori

关联分析

关联分析即从数据集中发现项之间的隐藏关系。apriori算法主要是基于频繁项集的关联分析。
关联规则挖掘有两个步骤:

  1. 寻找频繁项集
  2. 从频繁项集产生关联规则

apriori性质

任一频繁项集的所有非空子集也必须是频繁项集。这个项集可以在生成k-itemset的候选项时,如果这个候选项的(k-1)子集中有某个子集不存在(k-1)-itemset中,那么这个候选项直接删除,即不是k-itemset频繁项集。

apriori算法具体步骤

apriori算法实现

def loadDataSet():
    ''' 生成测试数据集

    '''
    return [
        [1,3,4],[2,3,5],[1,2,3,5],[2,5]
    ]


def createC1(dataSet):
    ''' 获取1-item候选集

    :param dataSet:
    :return: 1-item候选集
    '''
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:
                C1.append([item])
    C1.sort()
    return list(map(frozenset, C1))


def scanD(dataSet, Ck, minSupport):
    ''' 获取k-item频繁项集

    :param dataSet:
    :param Ck: 候选集
    :param minSupport:
    :return: 频繁项集
    '''
    ssCnt = {}
    for tid in dataSet:
        for can in Ck:
            if can.issubset(tid):
                if not can in ssCnt.keys():
                    ssCnt[can] = 1
                else:
                    ssCnt[can] += 1

    numItems = float(len(dataSet))
    retList = []
    supportData = {}
    for key in ssCnt:
        support = ssCnt[key]/numItems
        if support >= minSupport:
            retList.insert(0, key)
        supportData[key] = support
    return retList,supportData


def genCk(Lk, K):
    '''从k-item频繁项集中生成k+1-item候选集,原则:保证前K-2项相同,

    :param Lk: 频繁项集
    :param K:
    :return: 候选集
    '''
    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


def apriori(dataSet, minSupport):
    '''寻找频繁项集

    :param dataSet:
    :param minSupport: 最小支持度--某个频繁项集在所有事务中出现的频率的最小值
    :return:所有维度的频繁项集,以及支持度
    '''
    C1 = createC1(dataSet)
    L1,supportData = scanD(dataSet, C1, minSupport)

    L = [L1]
    k = 2
    while (len(L[k-2]) > 0):
        Ck = genCk(L[k-2], k)
        Lk, supK = scanD(dataSet, Ck, minSupport)
        supportData.update(supK)
        L.append(Lk)
        k += 1
    return L,supportData

一个优化:genCk函树用来生成候选项,生成的候选项Ck可能很多,导致寻找Lk时计算量很大。为了压缩Ck,可用用上述apriori性质做剪枝。
添加has_infrequent_subset函数,genCk函数添加候选时调用这个函数做一步判断。

def genCk(Lk, K):
    '''从k-item频繁项集中生成k+1-item候选集,原则:保证前K-2项相同,

    :param Lk: 频繁项集
    :param K:
    :return: 候选集
    '''
    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:
                Lkij = Lk[i] | Lk[j]
                if has_infrequent_subset(Lkij, Lk):
                    retList.append(Lkij)
    return retList


def has_infrequent_subset(candidate, itemsets):
    ''' 假设candidate是k候选项,判断candidate的k-1子集中是否有不存在k-1候选项中的项

    :param candidate:
    :param itemsets:
    :return:
    '''
    tmpSet = set(candidate)
    for item in tmpSet:
        cc = tmpSet.copy()
        cc.remove(item)
        if not frozenset(cc) in itemsets:
            return False
    return True

apriori算法介绍完毕!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值