Apriori算法

  Apriori算法用于关联分析,其目标包括两个:发现频繁项集,发现关联规则。首先需要发现频繁项集,然后才能发现关联规则。本文Apriori部分的代码来自《机器学习实战》,有需要可以看看。


发现频繁项集

  频繁项集指那些经常出现在一起的集合。若某个项集是频繁项集,则它的所有子集也是频繁的。反之,若一个项集是非频繁项集,则它的所有超集也是非频繁的。Apriori利用这个原理,避免计算非频繁项集及其所有超集的支持度。
  给定数据集,用Apriori发现频繁项集,只有一个输入参数:最小支持度。Apriori初始生成所有单个物品的候选集,然后扫描数据集,滤掉小于最小支持度的候选集,接着把剩下的集合进行组合,生成包含两个元素的候选集,如此持续下去,直到所有候选集被消去。
  频繁项集的量化指标是支持度,频繁项集必须满足支持度需求。

# 提取数据集的单元素集合(大小为1的候选集的集合)
def createC1(dataSet):C1 = set()for transaction in dataSet:for item in transaction:C1.add(item)C1 = list(C1)C1.sort()# 用frozenset是为了能作为keyreturn map(lambda x:frozenset([x]), C1)# 计算Ck中每项的支持度并过滤
def scanD(D, Ck, minSupport):ssCnt = {}for tid in D:for can in Ck:if can.issubset(tid):if not ssCnt.has_key(can):ssCnt[can] = 1else:ssCnt[can] += 1retList = [] # LksupportData = {} # 支持度(出现比例)for key in ssCnt:support = ssCnt[key] / float(len(D))if support >= minSupport:retList.insert(0, key) # 阈值过滤supportData[key] = supportreturn retList, supportData

  createC1()用于初始化,构建集合C1,它的每个元素都是大小为1的候选集,顾名思义,Ck的每个元素大小为k。scanD()用于扫描数据集,判断C1里的每一个候选集是否满足最小支持度需求,过滤掉,然后剩下的构成L1L1中的元素后续会进行组合,构成C2,然后过滤成L2,如此循环往复。

# 构造下一个候选集Ck
def aprioriGen(Lk, k):retList = []lenLk = len(Lk)for i in range(lenLk):for j in range(i+1, lenLk):L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]L1.sort(); L2.sort()if L1 == L2: # 如果它们前k-2项相同retList.append(Lk[i] | Lk[j]) # 合并return retListdef apriori(dataSet, minSupport=0.5):C1 = createC1(dataSet)D = map(set, dataSet)L1, supportData = scanD(D, C1, minSupport)L = [L1]k = 2while len(L[k-2])>0:Ck = aprioriGen(L[k-2], k)Lk, supK = scanD(D, Ck, minSupport) # 扫描并过滤supportData.update(supK)L.append(Lk)k += 1return L, supportData

  aprioriGen()接收Lk,创建候选集Ck,比如输入{0}、{1}、{2},就会输出{0,1}、{0,2}、{1,2}。注意这里有一个判断,若输入的两个元素(集合)有k-2项相同才合并,这个做法的目的是减少遍历次数。主函数是apriori(),它将持续生成Ck,然后过滤生成Lk,一直到无法继续为止。


挖掘关联规则

  关联规则源于频繁项集,任意一个频繁项集都能产生若干条关联规则,其中只有一部分成立。例如{“啤酒”,“奶粉”},可能有一条规则“啤酒”→“奶粉”,但是反之不一定成立。
  关联规则的量化指标是可信度,规则P→H的可信度定义为 support(P∪H)/support(P)。对于任何一个频繁项集,其产生的所有关联规则,都要计算可信度,把低可信度的规则去掉。然而有时候频繁项集的元素个数太多,可能产生很多关联规则,为了减少计算复杂度,利用这个规律:若某条规则不满足最小可信度需求,则该规则的所有子集也不满足最小可信度需求。

# 计算可信度
def calcConf(freqSet, H, supportData, br1, minConf=0.7):prunedH = []for conseq in H:conf = supportData[freqSet] / supportData[freqSet - conseq]if conf >= minConf: # 过滤# print "{0} --> {1} conf:{2}".format(freqSet - conseq, conseq, conf)br1.append((freqSet - conseq, conseq, conf))prunedH.append(conseq)return prunedHdef rulesFromConseq(freqSet, H, supportData, br1, minConf=0.7):m = len(H[0])if len(freqSet) > m+1:Hmp1 = aprioriGen(H, m+1)Hmp1 = calcConf(freqSet, Hmp1, supportData, br1, minConf)if len(Hmp1)>1:rulesFromConseq(freqSet, Hmp1, supportData, br1, minConf)def generateRules(L, supportData, minConf=0.7):bigRuleList = []for i in range(1, len(L)):for freqSet in L[i]:H1 = [frozenset([item]) for item in freqSet]if i>1:rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)else:calcConf(freqSet, H1, supportData, bigRuleList, minConf)return bigRuleList

  generateRules()是主函数,它有三个输入:频繁项集列表L、支持度表supportData和最小可信度minConf,输出一个包含可信度的规则列表bigRuleList。它会遍历L中每一个频繁项集,对每个频繁项集创建只包含单个元素集合的列表H1,如果每个项集只有1个元素,直接用calcConf()计算可信度,否则用rulesFromConseq()进行合并。


示例:发现毒蘑菇的相似特征

  Apriori还可以拿来做分类。我们不寻找所有的频繁项集,只对包含label的项集感兴趣。也就是说我们需要找到一些关联规则P→H,在H中包含label。这样我们就可以遍历所有样本,若P是样本的子集,就将对应的置信度作为样本是对应label的概率。当匹配的P很多时,可以取平均值。这种做法具有可解释性,可以理解为,“特征搭配为xxx和xxx时,平均有xx%的概率是正例”。

蘑菇数据可以在这里或这里找到。

为了保证label被包含在H中,需要对calConf()函数做一点改动。

def calcConf(freqSet, H, supportData, br1, minConf=0.7):prunedH = []for conseq in H:conf = supportData[freqSet] / supportData[freqSet - conseq]if conf >= minConf:# 仅当label被包含在H中if "1" in conseq or "0" in conseq:# print "{0} --> {1} conf:{2}".format(freqSet - conseq, conseq, conf)br1.append((freqSet - conseq, conseq, conf))prunedH.append(conseq)return prunedH

主函数

import apriori
import time
import numpy as np# 读取训练集
with open("./data/agaricus_train.csv", "rb") as f:dataSet = [line[:-1].split(',') for line in f.readlines()]# L中的每一个元素都至少在25%的样本中出现过
L, suppData = apriori.apriori(dataSet, 0.25) # 阈值越小,越慢# 生成规则,每个规则的置信度至少是0.6
bigRuleList = apriori.generateRules(L, suppData, 0.6)# P→H,根据P集合的大小排序
bigRuleList = sorted(bigRuleList, key=lambda x:len(x[0]), reverse=True)# 读取测试集
with open("./data/agaricus_test.csv", "rb") as f:dataSet = [line[:-1].split(',') for line in f.readlines()]
labels = np.array([int(x[0]) for x in dataSet])scores = []
for line in dataSet:tmp = []for item in bigRuleList:if item[0].issubset(set(line)):if "1" in item[1]:tmp.append(float(item[2]))# 因为是预测“为1的概率”,所以要用1减if "0" in item[1]:tmp.append(1 - float(item[2]))scores.append(np.mean(tmp)) # 求取均值# 用置信度作为预测概率
scores = map(lambda x:x>0.5, scores)
scores = np.array(scores, dtype='int')
print sum(np.equal(scores, labels)), len(labels), sum(np.equal(scores, labels))/float(len(labels))

输出

1427 1611 0.8857852265673495

虽然88.6%的识别率很低,但将最小支持度进一步调低,应该还可以提高识别率,此外,也可以将这个置信度当做一维特征,而不是单纯作为预测概率。

Apriori的缺点

  如上所见,Apriori是真的很慢,慢到令人发指。尽管它已经利用非频繁项集的超集非频繁的原理节省了不少计算量,但才不到1w行的mushroom数据,支持度选取25%,都要3分钟左右的处理时间。这是由于对于每一个 k k <script type="math/tex" id="MathJax-Element-6">k</script>,Apriori都要遍历一次整个数据集,而当支持度变低,满足条件的频繁项集变多,这个时间消耗就进一步增加。

完整实验代码

https://github.com/SongDark/Apriori


参考资料

《机器学习实战》
数据挖掘十大算法之Apriori详解
Frequent Itemset Mining Dataset Repository
UCI mushroom
mushroom 分训练集测试集

Apriori算法与python实现相关推荐

  1. Apriori算法的python实现

    原始链接:基于Python的机器学习实战:Apriori 原始链接里的代码是在python2下写的,有的地方我看的不是太明白,在这里,我把它修改成能在python3下运行了,还加入了一些方便自己理解的 ...

  2. apriori算法python代码_通俗易懂Apriori算法及Python实现

    本篇分为三个部分: 一.算法背景 啤酒与尿布故事: 某超市为增加销售量,提取出了他们超市所有的销售记录进行分析.在对这些小票数据进行分析时,发现男性顾客在购买婴儿尿片时,通常会顺便搭配带打啤酒来犒劳自 ...

  3. 原理 + 代码 | Apriori 算法与基于关联规则的购物篮推荐

    本文的代码与数据可在公众号 " 数据分析与商业实践 " 后台回复 " 0716 " 获取,更多商业实践案例等你来撩 推荐系统将成为未来十年里最重要的变革,社会化 ...

  4. 【商业挖掘】关联规则——Apriori算法(最全~)

    目录 一.关联规则挖掘 二.Apriori-关联规则算法 三.Apriori算法分解-Python大白话式实现 步骤1: 外部库调用❀ 步骤2: 数据导入❀ 步骤3: 数据处理❀ 步骤4:输出所有Go ...

  5. Apriori算法基本概念以及原理解析

    Apriori算法中几个重要的概念 A->B: 支持度: P(A^B) 表示A和B同时发生时的概率,没有先后顺序. 可信度或置信度: P(B|A) 表示A发生时,B发生的概率,有先后顺序. P( ...

  6. 关联分析——频繁项集的产生之Apriori算法

    关联分析--频繁项集的产生之Apriori算法 频繁项集的产生-Apriori算法 Apriori算法的Python实现 提取1-项集 提取频繁k-项集 生成候选k-项集 Apriori算法 封装 频 ...

  7. Apriori算法介绍(Python实现)

    导读: 随着大数据概念的火热,啤酒与尿布的故事广为人知.我们如何发现买啤酒的人往往也会买尿布这一规律?数据挖掘中的用于挖掘频繁项集和关联规则的Apriori算法可以告诉我们.本文首先对Apriori算 ...

  8. Apriori算法简介及实现(python)

    Apriori这个词的意思是"先验的",从priori这个词根可以猜出来~;) .该算法用于从数据中挖掘频繁项数据集以及关联规则.其核心原理是基于这样一类"先验知识&qu ...

  9. python——pandas数据分析(表格处理)工具实现Apriori算法

    pandas 是基于NumPy 的一种工具, 名字很卡哇伊,来源是由" Panel data"(面板数据,一个计量经济学名词)两个单词拼成的.pandas纳入了大量库和一些标准的数 ...

最新文章

  1. 设计模式 之美 -- 原型模式
  2. 如何在centos7下tomcat中安装https
  3. 奇异值分解(SVD)原理详解及推导 (转)
  4. 【产品干货】Uber产品经理首次在中国自述产品理念:我们看中的并非只是钱
  5. OpenCASCADE绘制测试线束:几何命令之转换
  6. 【GISER Painter】矢量切片(Vector tile)
  7. BugkuCTF-Crypto题贝斯家
  8. Python编程教程:面向对象之高级特性!
  9. 官方科普iQOO 5 120W闪充方案:首发6C高倍率电芯 15分钟充入100%
  10. 4.16-4.22课题(拼团系统)进度汇报
  11. roller for little vGL
  12. 回顾线性系统和非线性系统
  13. 浅谈端上智能之计算优化
  14. mysql查询慢的原因_MySQL查询缓慢的N种原因,以及N+1种解决方法
  15. [CnPeng说]低代码并不Low
  16. 【Day4.5】走人行天桥去百丽宫海生馆
  17. 解决ueditor编辑器图片在线管理图片无法显示
  18. 【火炉炼AI】深度学习001-神经网络的基本单元-感知器
  19. 数学建模_统计回归模型的梳理与总结:逐步回归,残差检验,自相关
  20. 自动提交flag-python

热门文章

  1. .Android手机邮箱设置详细教程
  2. 如何在ipone自带邮件上添加网易邮箱
  3. [NameError]: name ‘F’ is not defined
  4. JAVA应该怎么学?
  5. CPython、Jython、PyPy
  6. linux源码分析之cpu初始化 kernel/head.s,linux源码分析之cpu初始化
  7. FusionCharts简单教程(一)---建立第一个FusionCharts图形
  8. 大数据hive篇_group seting解决业务问题
  9. PG使用pg_settings表查看参数的生效条件
  10. 大端和小端的区别和判断