apriori支持度实现

算法思想
该算法的基本思想 是:首先找出所有的频集,这些项集出现的频繁性至少和预定义的最小支持度一样。然后由频集产生强关联规则,这些规则必须满足最小支持度和最小可信度。然后使用第1步找到的频集产生期望的规则,产生只包含集合的项的所有规则,其中每一条规则的右部只有一项,这里采用的是中规则的定义。一旦这些规则被生成,那么只有那些大于用户给定的最小可信度的规则才被留下来。为了生成所有频集,使用了递归的方法。

Aprior算法流程

下面我们对Aprior算法流程做一个总结。

输入:数据集合D,支持度阈值αα

输出:最大的频繁k项集

1)扫描整个数据集,得到所有出现过的数据,作为候选频繁1项集。k=1,频繁0项集为空集。

2)挖掘频繁k项集

a) 扫描数据计算候选频繁k项集的支持度

b) 去除候选频繁k项集中支持度低于阈值的数据集,得到频繁k项集。如果得到的频繁k项集为空,则直接返回频繁k-1项集的集合作为算法结果,算法结束。如果得到的频繁k项集只有一项,则直接返回频繁k项集的集合作为算法结果,算法结束。

c) 基于频繁k项集,连接生成候选频繁k+1项集。

  1. 令k=k+1,转入步骤2。

从算法的步骤可以看出,Aprior算法每轮迭代都要扫描数据集,因此在数据集很大,数据种类很多的时候,算法效率很低。

在这里插入图片描述

#-*- coding: UTF-8 -*-

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

# 将所有元素转换为frozenset型字典,存放到列表中
def createC1(dataSet):
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not [item] in C1:        #去重得到单元素项
                C1.append([item])
    C1.sort()                           #排序

    return list(map(frozenset, C1))  # 使用frozenset是为了后面可以将这些值作为字典的键 frozenset一种不可变的集合,set可变集合


# 过滤掉支持度不符合的集合 即剪枝
def scanD(D, Ck, minSupport):
    ssCnt = {}                      #建立字典存储各项及数目
    for tid in D:
        for can in Ck:
            if can.issubset(tid):  # 判断can是否是tid的《子集》 (这里使用子集的方式来判断两者的关系)
                ssCnt[can] = ssCnt.get(can,0)+1   #读取字典 存在can得到数值 不存在得到零 在取到的值加1 .get(要取的值,没有返回的值)
    retList = []  # 记录支持度大于给定值的数据
    supportData = {}  # 每个数据值的支持度
    for key in ssCnt:
        support = ssCnt[key] / len(D)     #计算支持度
        if support >= minSupport:           #和给定支持度比较
            retList.append(key);supportData[key] = support  #将符合支持度条件的数据存储
    return retList, supportData  # 排除不符合支持度元素后的元素 每个元素支持度# 返回频繁项集列表retList 所有元素的支持度字典


# 生成所有可以组合的集合
# 频繁项集列表Lk
# 连接后项集元素个数k  [frozenset({2, 3}), frozenset({3, 5})] -> [frozenset({2, 3, 5})]
def aprioriGen(Lk, k):
    retList = []
    lenLk = len(Lk)
    for i in range(lenLk):  # 两层循环比较Lk中的每个元素与其它元素
        for j in range(i + 1, lenLk):
            L1 = list(Lk[i])[:k - 2]  # 将集合转为list后 取0-k-2
            L2 = list(Lk[j])[:k - 2]
            L1.sort();
            L2.sort()
            if L1 == L2:# 该函数每次比较两个list的前k-2个元素,如果相同则求并集得到k个元素的集合
                retList.append(Lk[i] | Lk[j])  # 求并集python求并集符号|
    return retList  # 返回连接后的项集


# 调用上述函数
# 返回 所有满足大于阈值的组合 集合支持度列表
def apriori(dataSet, minSupport):
    D = list(map(set, dataSet))  # 转换列表记录为字典  [{1, 3, 4}, {2, 3, 5}, {1, 2, 3, 5}, {2, 5}]
    C1 = createC1(dataSet)  # 将每个元素转会为frozenset字典    [frozenset({1}), frozenset({2}), frozenset({3}), frozenset({4}), frozenset({5})]
    L1, supportData = scanD(D, C1, minSupport)  # 过滤数据
    L = [L1]   #频繁项集的集合
    k = 2
    while (len(L[k-2]) > 0):  # 若仍有满足支持度的集合则继续做关联分析
        Ck = aprioriGen(L[k-2], k)  # Ck候选频繁项集
        Lk, supK = scanD(D, Ck, minSupport)  # Lk频繁项集 supk支持度
        L.append(Lk)  # 更新L集合
        supportData.update(supK)   # 更新字典(把新出现的集合:支持度加入到supportData中)
        k=k+1  # 每次新组合的元素都只增加了一个,所以k也+1(k表示元素个数)
    support = {}
    for i in L[k - 3]:     #遍历符合支持度元素最多的项
        support[i] = supportData.get(i)   #从字典中取出项及其支持度
    return support   #返回项及其支持度

if __name__ == '__main__':
    while int(input('请输入序号:1 测试 0 退出\n')):
        print('输入支持度(0->1)')
        support = float(input())        #定义float型输入支持度
        supp= apriori(loadDataSet(),support)
        print(supp)                  #打印结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值