Apriori算法 python实现

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


主要流程:

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

    输出:最大的频繁k项集

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

    2)挖掘频繁k项集

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

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

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

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

主要代码:

 

1. judegefreq函数,使用先验性质判断筛选掉那些具有非频繁子集的候选,Cki为k候选集,subLk为k-1频繁集

 

def judgefreq(Cki, subLk):
    # 判断子集是否是频繁集,以便使用先验性质删除那些具有非频繁子集的候选
    
for i in Cki:
        Cksub= Cki - frozenset([i])
        if Cksub not in subLk:
            return False
    return True

 

 

2. getLki函数,获得频繁k项集Lk。先产生候选k项集Ck,调用函数judgefreq筛选。然后扫描数据库进行计数,根据最小绝对支持度min,得到Lk

def getLki(dataset, Lki,k, min, supportdata):
    # 获取频繁k项集Lk
    
allLki = list(Lki)
    Ck = set()
    for i in range(len(Lki)):     # 产生候选Ck
        
for j in range(1, len(Lki)):
            a = list(allLki[i])
            b = list(allLki[j])
            a.sort();b.sort()
            if a[0:k - 2] == b[0:k - 2]:
                if judgefreq(allLki[i] | allLki[j], Lki):
                    Ck.add(allLki[i] | allLki[j])    #加入频繁候选
    
Lk = set()
    item_count = {}
    for t in dataset:  # 扫描数据集进行计数
        
for Cki in Ck:
            if Cki.issubset(t):
                if Cki not in item_count:
                    item_count[Cki] = 1
                else:
                    item_count[Cki] += 1
    total = float(len(dataset))
    for item in item_count:
        if (item_count[item])>=min:
            Lk.add(item)
            supportdata[item] = item_count[item] / total
    return Lk

 

 

 

3. getL函数,调用getLki获得全体频繁集L及其相对支持度

def getL(dataset, k, minsup):
# 获取所有的频繁项集L
    
support = {}
    C1 = set()
    for data in dataset:
        for i in data:
            item = frozenset([i])
            C1.add(item)
 #获取候选1项集C1
    
L1 = set()
    item_count = {}
    for t in dataset:
        for C1i in C1:
            if C1i.issubset(t):
                if C1i not in item_count:
                    item_count[C1i] = 1
                else:
                    item_count[C1i] += 1
    total = float(len(dataset))
    for item in item_count:
        if (item_count[item]) >= minsup:
            L1.add(item)
            support[item] = item_count[item] / total
 #获取频繁1项集L1
    
Lksub1 = L1.copy()
    L = []
    L.append(Lksub1)
    for i in range(2, k+1):
        Li=getLki(dataset, Lksub1,i, minsup, support)
        if(len(Li)==0):
            break

        
Lksub1 = Li.copy()
        L.append(Lksub1)
    return L, support

 

4. rulesgenerating函数,由频繁集产生关联规则,即找出其中满足最小置信度的

即对每一个频繁项集,产生其非空子集。对每个非空子集,若置信度公式结果大于最小置信度阈值,则产生该关联关系。

 

def rulesgenerating(L, supportcount, confidence):
# 由频繁项集产生关联规则
    
rules = []
    sublist = []
    for i in range(0, len(L)):
        for fatherset in L[i]:
            for subset in sublist:
                if subset.issubset(fatherset):
                    conf = supportcount[fatherset] / supportcount[fatherset - subset]
                    rule = (fatherset - subset, subset, conf)
                    if conf >= confidence:  # 与最小置信度阈值比较
                        
if rule not in rules:
                          rules.append(rule)
            sublist.append(fatherset)
    return rules

 

5. 主函数

这里取了取minsup2000项,且发现取到3000以上时速度会显著提高

取最小置信度阈值为0.8

耗时:产生频繁项集 约11

产生关联规则 103

 

if __name__ == "__main__":
    book=xlwt.Workbook(encoding='utf-8', style_compression=0)
    sheet = book.add_sheet('frequentset', cell_overwrite_ok=True) #创建excel文件
    
print("running...")
    dataset = []
    rulelist=[]
    with open('homework1.dat') as file_object:
        for j in range(4208):
            line = file_object.readline()
            dataset.append(line.strip('\n').split(' '))  # 获得数据共4208项,一行22
    
L, support = getL(dataset, k=22, minsup=2000)

    rules = rulesgenerating(L, support, confidence=0.8) # 获得关联关系
    
m=0
    for Lk in L:
        print("频繁" + str(len(list(Lk)[0])) + "项集")
        print("*******************************************")
        for freq_set in Lk:
            print(list(freq_set))
            p=list(freq_set)
            for j in range(len(p)):
                sheet.write(m, j, p[j])   #写入frequentset表格中
            
m+=1
    print()
    print("关联规则:")
    for item in rules:
        print (list(item[0]), "=>", list(item[1]))


    book.save(r'E:\project\o\datamining\frequentset.xls') #保存频繁集结果表格
    
print("完毕......")

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值