Python数据挖掘----Apriori算法

Apriori算法

Apriori算法定义

  • 文字定义:
    Apriori算法是第一个关联规则挖掘算法,也是最经典的算法。它利用逐层搜索的迭代方法找出数据库中项集的关系,以形成规则,其过程由连接(类矩阵运算)与剪枝(去掉那些没必要的中间结果)组成。该算法中项集的概念即为项的集合。包含K个项的集合为k项集。项集出现的频率是包含项集的事务数,称为项集的频率。如果某项集满足最小支持度,则称它为频繁项—百度文库
  • 理解Apriori算法:
    Apriori的原理,如果某个项集是频繁项集,那么它所有的子集也是频繁的。
    以0,1,2,3为例子,有 2^4-1 种可能组合遍历。这是一种指数增长,而基于Apriori算法,可以有效降低计算的时间,提高计算效率。
    假如 {0,1} 是频繁的,那么 {0}, {1} 也一定是频繁的。
    反过来,若集合{2,3}是非频繁的,则{0,2,3},{1,2,3}和{0,1,2,3}也是非频繁的。
    {0,1,2,3}共有2^4-1种组合:
    {0},{1},{2},{3},
    {0,1},{0,2},{0,3},{1,2},{1,3},{2,3}
    {0,1,2},{0,1,3},{0,2,3},{1,2,3}
    {0,1,2,3}
    Apriori算法就是删除非频繁的项集,来达到降低计算的时间的效果。
    藕粉色字为非频繁的项集,表示计算机可以忽略这些组合。

题目

  • 数据库中有9个事务,即|D|=9。Apriori假定事务中的项按字典次序存放。
  • 9个事务 [[‘1’, ‘2’, ‘5’],[‘2’, ‘4’],[‘2’, ‘3’],
                   [‘1’, ‘2’, ‘4’],[‘1’, ‘3’],[‘2’, ‘3’],
                   [‘1’, ‘3’],[‘1’, ‘2’, ‘3’, ‘5’],[‘1’, ‘2’, ‘3’]]
  • 请使用Apriori算法发现D中的频繁项集。

分析

  • 设置最小支持度、导入数据
  • 将项目集提取出来
  • C1 计算支持度(小于支持度的剔除) L1
  • C2=L1间组合,剪枝,计算支持度(小于支持度的剔除) L2 判定L2是否为空
  • 直到候选频繁X-项集LX为空
  • 得到频繁项集后,使用set的issubset()得到最大频繁项集

代码

#得到C1
def filterC1():
    sum = []
    #筛选出数据中的所有元素
    [sum.append(j) for i in rawData for j in i if j not in sum]
    return list(map(set, sum))

#计算支持度:          cx->lx
def support(cx):
    #创建lx空表
    lx = []
    for i in cx:
        #计算各集合在数据中出现的次数
        ip = 0
        for j in rawData:
            if i.issubset(j):
                ip += 1
        #若该支持度大于最小支持度,则将该集合写入lx列表
        if ip/len(rawData) >= minSupport:
            lx.append(i)
        #若小于,则将该集合写入剪枝列表中
        else:
            pruning.append(i)
    return lx

#无重复组合+剪枝      lx->c(x+1)
def noRepCom(lx):
    #创建cx空表
    cx = []
    #对当前集合扩增一位,外加剪枝操作
    for i in lx:
        for j in l1:
            #判定l1中的元素是否在该集合中,若不在
            if j.issubset(i) == False:
                #使用集合类型的 “与” 运算,得到新的组合
                b = i | j
                #如果剪枝列表存在需要剪枝元素
                if len(pruning) != 0:
                    for k in pruning:
                        #剪枝集合如果不在新的组合中(剪枝),同时b不在cx的列表中(去重)
                        if k.issubset(b) == False and b not in cx:
                            cx.append(b)
                #如果剪枝列表为空
                else:
                    #只需去重即可
                    if b not in cx:
                        cx.append(b)
    return cx


#main
#导入数据
rawData = [['1', '2', '5'],['2', '4'],['2', '3'],['1', '2', '4'],
           ['1', '3'],['2', '3'],['1', '3'],['1', '2', '3', '5'],
           ['1', '2', '3']]
#将数据转换为集合的数据类型
rawData = list(map(set, rawData))
print(rawData)

#设置最小支持度
minSupport = 0.3
#剪枝组
pruning = []

#得到c1
cn = filterC1()
print('c1:', cn)
#计算支持度,得到 l1
l1 = support(cn)
print('l1:', l1)
#打印剪枝列表
print('pruning', pruning, '\n')
#lx对l1进行切片,得到新的列表
#原因:在noRepCom(lx)中使用了 l1,同时为了在下面的死循环找到进入循环的入口
lx = l1[:]
#n为计算次数,sum为频繁项集
n, sum = 2, []
#Apriori算法循环
while(len(cn) != 0):
    #例子:由l1得到c2
    cn = noRepCom(lx)
    print('c'+str(n)+':', cn)
    #例子,由c2得到l1
    lx = support(cn)
    print('l'+str(n)+':', lx)
    #打印剪枝列表
    print('pruning', pruning, '\n')
    #步数+1
    n += 1
    #累积频繁项集
    sum += cn
print('D的频繁项集:',sum)

#找到sum中的最大频繁项集
for i in range(len(sum)):
    #设置flag标记,初始化为 1
    flag = 1
    for j in range(i+1, len(sum)):
        #如果sum[j]集合包含了sum[i]集合,则将flag标记置为1,退出当前循环
        if sum[i].issubset(sum[j]) == True:
            flag = 0
            break
     #若flag仍为1,则打印它因为它就是我们想要的最大频繁项集
    if flag == 1:
        print('D中的最大频繁项集:',sum[i])

测试

在这里插入图片描述

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

拓展

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值