Apriori算法实现 python

Apriori:使用逐层迭代方法基于候选产生找出频繁项集

输入:

  • D:事务数据库
  • min_support:最小支持度阈值【p(AB)】

输出:L,D中的频繁项集

方法:

  1. L1=find_frequent_1_itemsets(D)
  2. for(k=2;Lk-1 != Null;k++){
  3.           Ck=apriori_generate(Lk-1)
  4.           for each 事务t属于D{ //扫描D进行计数
  5.                 Ct=subset(Ck,t) //得到t的子集,它们是候选
  6.                 for each 候选c属于Ct
  7.                        c.count++
  8.           }
  9.           Lk={c(Ck|c.count>=min_support)}
  10. }
  11. return L+=Lk

apriori_generate(Lk-1:frequent_(k-1)_itemset)

  1. for each 项集l1属于Lk-1
  2.      for each 项集l2属于Lk-1
  3.           if(l1[1]=l2[1] and ...l1[k-2]=l2[k-2] and l1[k-1]<l2[k-2]) then
  4.                    c=l1和l2连接(可直接 异或 得到)
  5.                    if has_infrequent_subset(c,Lk-1) then//如果有非频繁候选项集则进行剪枝【利用先验性质:频繁项集的所有非空子集也一定是频繁的】
  6.                           delete c
  7.                    else add c to Ck
  8. }
  9. return Ck

has_infrequent_subset(c,Lk-1)

  1. for each(k-1)subset s of c
  2.       if s 不属于 Lk-1 then
  3.              return True 
  4. return False

参考此链接:https://www.cnblogs.com/llhthinker/p/6719779.html

#coding:utf-8
import scrapy
import xlwt, lxml
import re, json
import matplotlib.pyplot as plt
import numpy as np
import pylab,math
from scipy import linalg

def loadDataSet():
    dataSet=[['l1', 'l2', 'l5'], ['l2', 'l4'], ['l2', 'l3'],['l1', 'l2', 'l4'], ['l1', 'l3'], ['l2', 'l3'],['l1', 'l3'], ['l1', 'l2', 'l3', 'l5'], ['l1', 'l2', 'l3']]
    return dataSet

def createC1(dataSet):#得到频繁1项集的集合
    c1=set()
    for t in dataSet:
        for item in t:
            itemSet=frozenset([item])
        #set无序且不重复,是可变的,有add(),remove()等方法;基本功能包括关系测试和消除重复元素. 集合对象还支持union(联合), intersection(交集), difference(差集)和sysmmetric difference(对称差集)等数学运算.
        #frozenset 是冻结的集合,它是不可变的,存在哈希值,它可以作为字典的key,也可以作为其它集合的元素。缺点是一旦创建便不能更改,也没有add,remove()方法
            c1.add(itemSet)
    # print(c1)
    return c1
# createC1(loadDataSet())

def isApriori(CkItem,Lksub1 ):#使用先验知识检测Lk是否为频繁项集【频繁项集的所有非空子集也一定是频繁的】
    #CkItem:候选k项集的集合
    #Lksub1:Lk-1,频繁k-1项集
    for item in CkItem:
        subCk=CkItem-frozenset([item])
        # print(subCk)
        if subCk not in Lksub1:
            return False
    return True

def createCk(Lksub1,k):
    Ck=set()
    length=len(Lksub1)
    Lksub1List=list(Lksub1)
    for i in range(length):
        for j in range(1,length):
            l1=list(Lksub1List[i])
            l2=list(Lksub1List[j])
            l1.sort()
            l2.sort()
            if l1[0:k-2]==l2[0:k-2]:
                CkItem=Lksub1List[i] | Lksub1List[j]
                if isApriori(CkItem,Lksub1):
                    Ck.add(CkItem)
    return Ck

def generate_Lk_by_Ck(dataSet,Ck,min_support,support_data):
    # print(Ck)
    # print('+++++++++++++++++++++++++++')
    Lk=set()
    item_count={}#统计并记录每一个Ck子集的出现次数
    for t in dataSet:
        for item in Ck:
            if item.issubset(t):#判断item是否在事务数据集中
                if item not in item_count:
                    item_count[item]=1
                else:
                    item_count[item]+=1
    t_num=len(dataSet)
    for item in item_count:#满足支持度大于最小支持度的Ck子集添加到频繁项集Lk中,最终返回频繁k项集
        if item_count[item]/t_num>=min_support:
            Lk.add(item)
            support_data[item]=item_count[item]/t_num
    # print(item_count)
    # print('+++++++++++++++++++++++++++++')
    return Lk

def generate_L(dataSet,k,min_support):
    support_data={}
    C1=createC1(dataSet)
    L1=generate_Lk_by_Ck(dataSet,C1,min_support,support_data)
    Lksubl=L1.copy()
    L=[]
    L.append(Lksubl)
    for i in range(2,k+1):
        Ci=createCk(Lksubl,i)
        Li=generate_Lk_by_Ck(dataSet,Ci,min_support,support_data)
        Lksubl=Li.copy()
        L.append(Lksubl)
    return L,support_data

def generate_big_rules(L,support_data,min_conf):#生成关联规则
    big_rule_list=[]
    sub_set_list=[]
    for i in range(len(L)):
        for freq_set in L[i]:
            for sub_set in sub_set_list:
                if sub_set.issubset(freq_set):
                    conf=support_data[freq_set]/support_data[freq_set-sub_set]
                    big_rule=(freq_set-sub_set,sub_set,conf)
                    if conf>=min_conf and big_rule not in big_rule_list:
                        big_rule_list.append(big_rule)
            sub_set_list.append(freq_set)
    return big_rule_list

if __name__ == '__main__':
    dataSet=loadDataSet()
    L,support_data=generate_L(dataSet,k=3,min_support=0.2)
    big_rule_list=generate_big_rules(L,support_data,min_conf=0.7)
    for Lk in L:
        print('frequent'+str(len(list(Lk)[0]))+'-itemsets\t\tsupport')
        print()
        for freq_set in Lk:
            print(freq_set,support_data[freq_set])
    print()
    print('Big Rules')
    for item in big_rule_list:
        print(item[0],'=>',item[1],'conf: ',item[2])

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值