数据挖掘学习记录:Apriori算法原理及其实现

基本概念

支持度与置信度

  关联规则中的支持度和置信度是规则兴趣度的两种度量。它们分别反映所发现的规则的有用性和确定性

支持度:表示项集X在总数据集中出现的概率
在这里插入图片描述

置信度:包含X和Y的项集数与包含X的项集数之比:
在这里插入图片描述

  • 关联规则的置信度反映了,如果项集中出现X,那么同时出现Y的概率是多少。
  • 例如:关联规则R1:{brea}→{milk}的可信度为 confidence(R1)=support({bread, milk})/ support({bread})= 0.5/0.7 =5/7。

项集的最小支持度与频繁集

  用于发现关联规则的项集必须满足最小支持度的阈值,称为项集的最小支持度,记为supmin

  • 从统计的意义上讲,它表示用户关心的关联规则必须满足的最低要求,最低重要性。
  • 只有满足最小支持度的项集才能产生关联规则。

  支持度大于或者等于supmin的项集称为频繁项集,简称频繁集,反之称为非频繁集。

  • 通常,k-项集如果满足supmin,可称为k-频繁集,记作Lk

强关联规则

关联规则的最小支持度记为supmin,最小置信度记为confmin
如果关联规则同时满足如下2个条件:

  • support(X → Y)≥ supmin
  • confidence(X→Y)≥ confmin

则称关联规则为强关联规则,否则为弱关联规则。
筛选出来的强关联规则可用于指导决策。

Apriori算法简介

  Apriori算法是一个关联规则挖掘算法,也是最经典的算法。它利用逐层搜索的迭代方法找出数据库中项集的关系,以形成规则,其过程由连接剪枝组成。

Apriori算法通过多次扫描数据集,找出所有频繁集,然后用这些频繁集产生强关联规则。
Apriori算法通过迭代来穷举出数据集中的所有频繁集。

Apriori算法的性质:频繁集的所有非空子集也一定是频繁的。

算法示例及其过程

在这里插入图片描述
算法过程:

  1. 输入数据集D,最小支持度阈值supmin
  2. 首先,产生1-频繁集 L1
  3. 随后,在 L1 上通过连接修剪产生2-频繁集 L2
  4. 依次类推,可在 Lk 上通过连接修剪产生(k+1) - 频繁集 Lk+1
  5. 最后,直到无法产生新的频繁集为止。

连接: 只相差一个项的两个项集才能进行连接(集合的“合并“操作)

   例如:由L2生成C3的过程中,L2中的{A,C}和{B,C}只相差一个项,因此它们可以连接生成{A,B,C}。 但是L2中的{A,C}和{B,E}无法进行连接。

修剪: 去除子集不是频繁集的项集(算法性质)

   例如:虽然L2中的{A,C}和{B,C}可以连接生成{A,B,C},但是由于{A,B,C}的子集{A,B}不是频繁集(不在L2中),因此,在生成L3时,需要从C3中删除{A,B,C} 。

Apriori算法的实现

  这次代码所用的数据集是博主的一次作业要求,因此这次代码也针对的是一次实验,泛用性有待验证,如有错误敬请指出。
作业要求:

  1. 编写Apriori算法程序。
  2. 用Apriori 算法找出频繁项集,支持度和置信度根据情况自行设定。
  3. 找出强关联规则以及相应的支持度和置信度。

  资源已经上传到了博主的资源库中,有需要的朋友们可以去下载体验。代码有所参考书籍《机器学习实战》,《数据挖掘:概念与技术》内容。

代码如下:

import xdrlib,xlrd #读 excel

File='Apriori_1000_Items_DataSet.xls' # 获取数据文件

##Apriori 算法

##1.获取数据集 Datasets
try:
    workbook = xlrd.open_workbook(File)#打开 excel 文件
    table = workbook.sheet_by_index(0)#打开第一个工作表
    nrows = table.nrows#获取当前行
    ncols = table.ncols#获取当前列
    datasets = [] #数据集
    for row in range(2, nrows):
        cell_value = table.row_values(row, 1)  # 获取第二列中单元格的数据
        item = cell_value[0]  # 将获取的数据化为字符串
        excle_soloCell = []  # 空列表,装单个数据的分离,并每次循环置空
        for i in range(0, len(item)):
            excle_soloCell.append(item[i])
        datasets.append(excle_soloCell)  # 把数据追加到 excel_list 中
    print('数据集 Datasets:',end='')
    print(datasets)
except Exception as e:
    print(str(e))

# 2.从 datasets 中获取候选集 C1
#  因数据集中无空集等多余数据所以候选集C1即为datasets
def creatC1(dataSet):
    C1 = []
    for transaction in dataSet:
        for item in transaction:
            if not item in C1:
                if item == 0:  # 0->'false' 1->'true'!
                    item = 'false'
                if item == 1:
                    item = 'true'
                if {item} not in C1:
                    C1.append({item})
    return list(map(frozenset,C1))#frozenset 是冻结的集合,不可以增添或删除或改变


#3.扫描候选集,生成 k-频繁项集 Lk
##分为两步:3.1 扫描 3.2 组合
##3.1 扫描,返回频繁集 Lk
def scanDatasets(Datasets,Ck,minSupport):
    item_count = {} #计算候选频繁集中每个项在 Datasets 中的数量。这是一个字典,key 是频繁项集中的项,value 是这些项的个数
    for transaction in Datasets:
        for item in Ck:
            if item.issubset(transaction):
                if item not in item_count.keys():
                    item_count[item] = 1
                else:
                    item_count[item] +=1
    transaction_number = float(len(Datasets))
    frequentSet = [] #频繁项集
    supportData = {} #key:候选项 item in Ck value:支持度
    for key in item_count:
        support = item_count[key]/transaction_number
        supportData[key] = support
        if support>=minSupport:
            frequentSet.append(key)
    return frequentSet,supportData


##3.2 组合,通过 Lk 频繁项集构造 Ck+1 候选项集
def apriori_Gen(Lk,k):#k 是要组合成的 k 候选集 Lk 的类型是集合 set
    Ck = []#ck+1 候选项集
    for i in range(len(Lk)):
        for j in range(i+1,len(Lk)):
            L1 = list(Lk[i])[0:k-2]
            L2 = list(Lk[j])[0:k-2]
            if L1==L2:
                Ck.append(Lk[i]|Lk[j])#Lk 元素的类型是集合(frozenset)这里‘|’是并集的操作
    return Ck


##4 apriori 算法主函数
def apriori(Datasets,minsupport):
    C1 = creatC1(Datasets)
    L1,supportData = scanDatasets(Datasets,C1,minsupport)
    L = [L1]
    k = 2
    while(len(L[k-2])>0): #L[k-2]就是 L(k-1) 当上一个频繁项集不等于 0 是循环才能进行下去
        Ck = apriori_Gen(L[k-2],k)
        Lk,supK = scanDatasets(Datasets,Ck,minsupport)
        supportData.update(supK)
        L.append(Lk)
        k +=1
    return L,supportData


L,supportData = apriori(datasets,0.2)#此处输入关联规则的最小支持度
print('频繁项集:')
frequentsest_number = 1
for frequentset in L:
    print(frequentset)
    print('%d-频繁项集的个数为 %d'%(frequentsest_number,len(frequentset)))
    frequentsest_number += 1



def calcConf(freqSet, H, supportData, brl, minConf):
    # calcConf(对两个元素的频繁项,计算可信度,例如: {1,2}/{1} 或者 {1,2}/{2} 看是否满足条件)
    # freqSet 频繁项集中的元素,例如: frozenset([1, 3])
    # H 频繁项集中的元素的集合,例如: [frozenset([1]), frozenset([3])]
    # prunedH 记录 可信度大于阈值的集合
    prunedH = []
    for conseq in H:
        conf = supportData[freqSet]/supportData[freqSet-conseq]
        if conf >= minConf: # 只要买了 freqSet-conseq 集合,一定会买 conseq 集合(freqSet-conseq 集合和 conseq 集合是全集)
            print (freqSet-conseq, '-->', conseq, 'conf:', conf)
            brl.append((freqSet-conseq, conseq, conf))
            prunedH.append(conseq)
    return prunedH


def rulesFromConseq(freqSet, H, supportData, brl, minConf):
    m = len(H[0])
    if (len(freqSet) > (m + 1)):
    # 生 成 m+1 个 长 度 的 所 有 可 能 的 H 中 的 组 合 
        Hmp1 = apriori_Gen(H, m+1)
        # 返回可信度大于最小可信度的集合
        Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf)
        # 计算可信度后,还有数据大于最小可信度的话,那么继续递归调用,否则跳出递归
        if (len(Hmp1) > 1):
            rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)


    # 生成关联规则
def generateRules(L, supportData, minConf):
        # L 频繁项集列表
        # bigRuleList 可信度规则列表(组合)
        
    bigRuleList = []
    for i in range(1, len(L)):
    # 获取频繁项集中每个组合的所有元素
        for freqSet in L[i]:
        # 组合总的元素并遍历子元素,并转化为 frozenset 集合,再存放到 list 列表中
            H1 = [frozenset([item]) for item in freqSet]
            # 2 个的组合,走 else, 2 个以上的组合,走 if
            if (i > 1):
                rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
            else:
                calcConf(freqSet, H1, supportData, bigRuleList, minConf)
    return bigRuleList


print('关联规则')
associationRule = generateRules(L,supportData,0.4) #此处修改关联规则的最小置信度
print('关联规则个数:',len(associationRule))

  以上便是Apriori算法个人学习与理解的主要内容。Apriori算法主要针对的还是各类购物篮的关联分析问题,可以给商家一个促销的契机
.

博主第一篇博文,不定期更新,新人上路,敬请指教。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值