机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析

关键字:Apriori、关联规则挖掘、频繁项集
作者:米仓山下
时间:2018-11-2
机器学习实战(Machine Learning in Action,@author: Peter Harrington)
源码下载地址:https://www.manning.com/books/machine-learning-in-action
git@github.com:pbharrin/machinelearninginaction.git

*************************************************************
一、Apriori算法——生成频繁项集

Apriori算法原理:
原理:如果某个项集是频繁的,那么它所有的子集也是频繁的。反过来,如果一个项集是非频繁集,那么他所有的超集也是非频繁的
--------------------------------------------------------------
#创建测试数据集,包含四个列表的列表:[[1, 3, 4], [2, 3, 5], [1, 2, 3, 5], [2, 5]]
loadDataSet()
#根据测试数据集生成第一个频繁项集,频繁项为单个
createC1(dataSet)
#根据给定的频繁项集Ck,支持度minSupport,计算在数据集D中Ck各频繁项的支持度,并返回支持度大于minSupport的频繁项(数组),及所有频繁项的支持度(频繁项为key,支持度为value的字典)
scanD(D, Ck, minSupport)
--------------------------------------------------------------
#根据给定频繁项集生成下Lk,通过集合并集运算,得到频繁项集Lk+1。

  1. def aprioriGen(Lk, k): #creates Ck
  2. retList = []
  3. lenLk = len(Lk)
  4. for i in range(lenLk):
  5. for j in range(i+1, lenLk):
  6. L1 = list(Lk[i])[:k-2]; L2 = list(Lk[j])[:k-2]
  7. L1.sort(); L2.sort()
  8. if L1==L2: #if first k-2 elements are equal
  9. retList.append(Lk[i] | Lk[j]) #set union
  10. return retList

#注:这里强调一下为什么只比较前k-2元素,书中强调的原因是可以减少循环次数,但并没有进一步解释这样做的逻辑。示例数据中,两项的频繁项集为[{2,3}, {3,5}, {2,5}, {1,3}],所有两两并集为[{2,3,5},{1,3,5}]。但是如果仅比较前k-2个元素相同的进行合并为[{2,3,5}],之所以没有{1,3,5}是因为{1,5}不存在,即它不是频繁项集,按照Apriori的原理“某个子项集不是频繁的,那么它的超集也不是频繁的”。因此比较前k-2个元素既可以减少循环次数又不会漏掉频繁项。

--------------------------------------------------------------
#不断扫描数据集,由单元素频繁项不断合并,并求解它们的支持度,记录下符合条件的频繁项,以及频繁项的支持度

  1. def apriori(dataSet, minSupport = 0.5):
  2. C1 = createC1(dataSet) #生成单元素频繁项集
  3. D = map(set, dataSet)
  4. L1, supportData = scanD(D, C1, minSupport) #计算单元素频繁项集的支持度,并筛选
  5. L = [L1]
  6. k = 2
  7. while (len(L[k-2]) > 0): #当最加入新频繁项集长度大于零
  8. Ck = aprioriGen(L[k-2], k) #合并频繁项集形成新的候选集
  9. Lk, supK = scanD(D, Ck, minSupport) #计算候选集的支持度,并筛选
  10. supportData.update(supK) #更新存储频繁项支持度的词典
  11. L.append(Lk) #将最新得到的频繁项加入列表中
  12. k += 1
  13. return L, supportData

--------------------------------------------------------------
测试:

  1. >>> import apriori
  2. >>> data=apriori.loadDataSet()
  3. >>> data
  4. [[, , ], [, , ], [, , , ], [, ]]
  5. >>> L,supportData=apriori.apriori(data)
  6. >>> L
  7. [[frozenset([]), frozenset([]), frozenset([]), frozenset([])], [frozenset([, ]), frozenset([, ]), frozenset([, ]), frozenset([, ])], [frozenset([, , ])], []]
  8. >>> supportData
  9. {frozenset([]): 0.75, frozenset([]): 0.75, frozenset([, , ]): 0.5, frozenset([, ]): 0.25, frozenset([, ]): 0.25, frozenset([, ]): 0.5, frozenset([]): 0.25, frozenset([, ]): 0.5, frozenset([, ]): 0.75, frozenset([]): 0.5, frozenset([, ]): 0.5, frozenset([]): 0.75}
  10. >>>

*************************************************************
二、Apriori算法——从频繁项集中挖掘关联规则

置信度:
  置信度(confidence)揭示了A出现时B是否一定出现,如果出现,则出现的概率是多大。如果A->B的置信度是100%,则说明A出现时B一定会出现(返回来不一定)。用公式表示是,物品A->B的置信度=物品{A,B}的支持度 / 物品{A}的支持度:(A称为前件,B称为后件)
Confidence(A->B) = support({A,B}) / support({A}) = P(B|A)

如果某条规则不满足最小可信度要求,那么该规则的所有子集也不会满足最小置信度要求。假设{0,1,2}->{3}不满足最小可信度的要求。那么任何{0,1,2}的子集也不会满足最小可信度的要求。可以利用该性质来减少需要测试的规则数目。

--------------------------------------------------------------
#规则生成函数

  1. def generateRules(L, supportData, minConf=0.7): #supportData is a dict coming from scanD
  2. bigRuleList = [] #存储关联规则的列表
  3. for i in range(1, len(L)): #取出两个或更多元素的频繁项集,L[0]为单元素频繁项集,遍历
  4. for freqSet in L[i]: #遍历频繁项集L[i]中的频繁项
  5. H1 = [frozenset([item]) for item in freqSet] #某个频繁项中的元素列表
  6. if (i > 1): #元素大于两个的频繁项,将频繁项中的元素进行组合成后件(规则)
  7. rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)
  8. else: #i=1,两个元素的频繁项
  9. calcConf(freqSet, H1, supportData, bigRuleList, minConf)
  10. return bigRuleList

--------------------------------------------------------------
#计算可信度
#输入:freqSet——频繁项, H——频繁项元素列表, supportData——频繁项支持度列表, brl——存储关联规则的列表, minConf——最小可信度
#输出:brl——频繁项freqSet中存在的关联规则,prunedH——返回关联规则中的后件列表

  1. def calcConf(freqSet, H, supportData, brl, minConf=0.7):
  2. prunedH = [] #关联规则中的后件列表
  3. for conseq in H: #遍历频繁项中的元素,conseq为元素
  4. conf = supportData[freqSet]/supportData[freqSet-conseq] #可信度(freq-conseq)->conseq
  5. if conf >= minConf: #可信度>minConf
  6. print freqSet-conseq,'-->',conseq,'conf:',conf #打印关联规则及可信度
  7. brl.append((freqSet-conseq, conseq, conf)) #保存关联规则及可信度
  8. prunedH.append(conseq) #保存后件(规则),为后面准备。注:不满足规则的后件,在该元素基础下添加也不会满足
  9. return prunedH

--------------------------------------------------------------
#最初的规则生成更多的规则
#输入:freqSet——频繁项, H——频繁项元素列表;输出:brl——频繁项freqSet中存在的关联规则

  1. def rulesFromConseq(freqSet, H, supportData, brl, minConf=0.7):
  2. m = len(H[0])
  3. if (len(freqSet) > (m + 1)): #频繁项元素数目>后件(候选规则)的元素数,一直执行。例如{1,2,3,4}当{1}-{2,3,4}以后此时H[0]长度为3
  4. Hmp1 = aprioriGen(H, m+1) #合并候选后件(规则),由Hm生成Hm+1。注:不满足规则的后件,在该元素基础下添加也不会满足
  5. Hmp1 = calcConf(freqSet, Hmp1, supportData, brl, minConf) #返回规则后件(规则)列表
  6. if (len(Hmp1) > 1): #返回后件(规则)列表包含1个以上后件(规则),递归进一步组合这些规则
  7. rulesFromConseq(freqSet, Hmp1, supportData, brl, minConf)

--------------------------------------------------------------
测试:

  1. >>> reload(apriori)
  2. <module 'apriori' from 'apriori.py'>
  3. >>> L, supportData=apriori.apriori(data)
  4. >>> L
  5. [[frozenset([1]), frozenset([3]), frozenset([2]), frozenset([5])], [frozenset([1, 3]), frozenset([2, 5]), frozenset([2, 3]), frozenset([3, 5])], [frozenset([2, 3, 5])], []]
  6. >>> supportData
  7. {frozenset([5]): 0.75, frozenset([3]): 0.75, frozenset([2, 3, 5]): 0.5, frozenset([1, 2]): 0.25, frozenset([1, 5]): 0.25, frozenset([3, 5]): 0.5, frozenset([4]): 0.25, frozenset([2, 3]): 0.5, frozenset([2, 5]): 0.75, frozenset([1]): 0.5, frozenset([1, 3]): 0.5, frozenset([2]): 0.75}
  8. >>> rules=generateRules(L, supportData, minConf=0.6)
  9. frozenset([3]) --> frozenset([1]) conf: 0.666666666667
  10. frozenset([1]) --> frozenset([3]) conf: 1.0
  11. frozenset([5]) --> frozenset([2]) conf: 1.0
  12. frozenset([2]) --> frozenset([5]) conf: 1.0
  13. frozenset([3]) --> frozenset([2]) conf: 0.666666666667
  14. frozenset([2]) --> frozenset([3]) conf: 0.666666666667
  15. frozenset([5]) --> frozenset([3]) conf: 0.666666666667
  16. frozenset([3]) --> frozenset([5]) conf: 0.666666666667
  17. frozenset([5]) --> frozenset([2, 3]) conf: 0.666666666667
  18. frozenset([3]) --> frozenset([2, 5]) conf: 0.666666666667
  19. frozenset([2]) --> frozenset([3, 5]) conf: 0.666666666667
  20. >>>
  21. >>> rules=generateRules(L, supportData, minConf=0.7)
  22. frozenset([1]) --> frozenset([3]) conf: 1.0 #出现1集合中一定出现了3
  23. frozenset([5]) --> frozenset([2]) conf: 1.0 #出现5集合中一定出现了2
  24. frozenset([2]) --> frozenset([5]) conf: 1.0 #出现2集合中一定出现了5
  25. >>>
  26. >>> rules
  27. [(frozenset([1]), frozenset([3]), 1.0), (frozenset([5]), frozenset([2]), 1.0), (frozenset([2]), frozenset([5]), 1.0)]
  28. >>>

*************************************************************
三、示例:发现毒蘑菇的相似特征
数据集:mushroom.dat
说明:mushroom数据集是关于肋形蘑菇的23种特征的数据集,每个特征都包含一个标称数据值。
mushroom.dat前几列数据为:
1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 107 113
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114
2 4 9 15 23 27 34 36 39 41 52 55 59 63 67 76 85 86 90 93 99 108 115
第一个特征表示有毒(2)或则可食用(1),下一特征为蘑菇伞的形状,六种可能的值3-8表示。

  1. #将数据读取转换为集合
  2. >>> mushDataSet=[line.split() for line in open('mushroom.dat').readlines()]
  3. >>> mushDataSet[0]
  4. ['', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '']
  5. >>> len(mushDataSet)
  6. 8124
  7.  
  8. #生成频繁项集
  9. >>> L, supportData=apriori.apriori(mushDataSet,minSupport = 0.3)
  10. >>> len(L)
  11. 10
  12. >>> L[9]
  13. []
  14. >>> L[8]
  15. [frozenset(['', '', '', '', '', '', '', '', '']), frozenset(['', '', '', '', '', '', '', '', '']), frozenset(['', '', '', '', '', '', '', '', '']), frozenset(['', '', '', '', '', '', '', '', ''])]
  16. >>>
  17.  
  18. #所有特征的标称性数值并不重复,打印长度为8的所有有毒(2)的频繁项
  19. >>> for item in L[7]:
  20. ... if item.intersection(''):print item
  21. ...
  22. frozenset(['', '', '', '', '', '', '', ''])
  23. frozenset(['', '', '', '', '', '', '', ''])
  24. frozenset(['', '', '', '', '', '', '', ''])
  25. frozenset(['', '', '', '', '', '', '', ''])
  26. frozenset(['', '', '', '', '', '', '', ''])
  27. frozenset(['', '', '', '', '', '', '', ''])
  28. frozenset(['', '', '', '', '', '', '', ''])
  29. frozenset(['', '', '', '', '', '', '', ''])
  30. frozenset(['', '', '', '', '', '', '', ''])
  31. frozenset(['', '', '', '', '', '', '', ''])
  32. frozenset(['', '', '', '', '', '', '', ''])
  33. frozenset(['', '', '', '', '', '', '', ''])
  34. frozenset(['', '', '', '', '', '', '', ''])
  35. frozenset(['', '', '', '', '', '', '', ''])
  36. frozenset(['', '', '', '', '', '', '', ''])
  37. frozenset(['', '', '', '', '', '', '', ''])
  38. frozenset(['', '', '', '', '', '', '', ''])
  39. frozenset(['', '', '', '', '', '', '', ''])
  40. >>>

#这样就可以看到有哪些特征的蘑菇大概率是毒蘑菇。但:并不表示没有这些特诊的蘑菇就没有毒

*************************************************************
四、总结
关联分析用于发现大规模数据集中元素间有趣关系。通过两种两种方式量化这些有趣关系:第一种是使用频繁项集,给出经常一起出现的元素项;第二种是关联规则,每条关联规则意味着元素之间“如果……那么”的关系。

减少扫描频繁项统计扫描次数的方法就是Apriori。Apriori原理是说如果一个元素项是不频繁的那么包含该元素的超集也是不频繁的。Apriori算法从单元素项集合开始,通过组合满足最小支持度要求的项集来形成更大的集合。支持度用来度量一个集合在原始数据中出现的频率。

原始数据中每条数据是集合,但并不要求每条数据具有相同的长度

缺点:每次增加频繁项集的大小,Apriori算法都会扫描整个数据集。数据集很大时会降低频繁项集发现的速度。相比,12章中FPgrowth算法只需要对数据库进行两次扫描,能够显著加快频繁项集发现速度

参考文献:
https://blog.csdn.net/wanghao109/article/details/39452303
https://www.cnblogs.com/bigmonkey/p/7405555.html
https://blog.csdn.net/zllnau66/article/details/81534368

机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析的更多相关文章

  1. 机器学习实战 - 读书笔记(11) - 使用Apriori算法进行关联分析

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第11章 - 使用Apriori算法进行关联分析. 基本概念 关联分析(associat ...

  2. 机器学习实战 [Machine learning in action]

    内容简介 机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中萃取有价值的信息或模式,成为各行业求生存.谋发展的决定性手段,这使得这一过去为分析师和数学家所专属 ...

  3. 学习笔记之机器学习实战 (Machine Learning in Action)

    机器学习实战 (豆瓣) https://book.douban.com/subject/24703171/ 机器学习是人工智能研究领域中一个极其重要的研究方向,在现今的大数据时代背景下,捕获数据并从中 ...

  4. K近邻 Python实现 机器学习实战(Machine Learning in Action)

    算法原理 K近邻是机器学习中常见的分类方法之间,也是相对最简单的一种分类方法,属于监督学习范畴.其实K近邻并没有显式的学习过程,它的学习过程就是测试过程.K近邻思想很简单:先给你一个训练数据集D,包括 ...

  5. 【机器学习实战】第11章 使用 Apriori 算法进行关联分析

    第 11 章 使用 Apriori 算法进行关联分析 关联分析 关联分析是一种在大规模数据集中寻找有趣关系的任务. 这些关系可以有两种形式: 频繁项集(frequent item sets): 经常出 ...

  6. Coursera 机器学习 第6章(下) Machine Learning System Design 学习笔记

    Machine Learning System Design下面会讨论机器学习系统的设计.分析在设计复杂机器学习系统时将会遇到的主要问题,给出如何巧妙构造一个复杂的机器学习系统的建议.6.4 Buil ...

  7. 【python与机器学习实战】感知机和支持向量机学习笔记(一)

    对<Python与机器学习实战>一书阅读的记录,对于一些难以理解的地方查阅了资料辅以理解并补充和记录,重新梳理一下感知机和SVM的算法原理,加深记忆. 1.感知机 感知机的基本概念 感知机 ...

  8. 机器学习——使用Apriori算法进行关联分析

    从大规模的数据集中寻找隐含关系被称作为关联分析(association analysis)或者关联规则学习(association rule learning). Apriori算法 优点:易编码实现 ...

  9. Machine Learning(Andrew Ng)学习笔记

    1.监督学习(supervised learning)&非监督学习(unsupervised learning) 监督学习:处理具有若干属性且返回值不同的对象.分为回归型和分类型:回归型的返回 ...

随机推荐

  1. Android之apk优化

    公司的apk越做越大...作为一个有追求的程序员,我觉得有必要给apk瘦身了... 优化之前,先来分析一下apk结构,下面附上一张apk结构图: apk结构.png 由于我这个项目集成了百度地图.百度 ...

  2. Gen对于数组Array的处理

    举个例子,如下: public void t() { String[][] a = new String[][] { { "x", "y" } }; Strin ...

  3. Spring Boot + Spring Cloud 实现权限管理系统 后端篇(五):模块化切分

    切分工程 考虑到后续我们的模块会越来越多,依赖的公共代码和配置需要集中管理,我们在这里先把公共模块和配置从后台管理业务中剥离出来. 新增两个工程,切分后结构如下: kitty-boot:启动器及全局配 ...

  4. TensorFlow object detection API应用--配置

    目标检测在图形识别的基础上有了更进一步的应用,但是代码也更加繁琐,TensorFlow专门为此开设了一个object detection API,接下来看看怎么使用它. object detectio ...

  5. tomcat关闭后线程依然运行解决办法

    tomcat关闭后线程依然运行解决办法,设置线程为守护线程 守护线程与非守护线程 最近在看多线程的Timer章节,发现运用到了守护线程,感觉Java的基础知识还是需要补充. Java分为两种线程:用户 ...

  6. “网红架构师”解决你的Ceph 运维难题

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由Tstack发表于云+社区专栏 本文为长篇连续剧,将分多个篇幅发表,主要介绍了从动手部署环境到后期运营故障处理过程中常见的问题,内容由 ...

  7. TensorFlow-实战Google深度学习框架 笔记(上)

    TensorFlow TensorFlow 是一种采用数据流图(data flow graphs),用于数值计算的开源软件库.在 Tensorflow 中,所有不同的变量和运算都是储存在计算图,所以在 ...

  8. 【转载】Layered Window(分层窗体,透明窗体)

    本文转载自花间醉卧<Layered Window(分层窗体,透明窗体)> //为窗体添加WS_EX_LAYERED属性,该属性使窗体支持透明 ModifyStyleEx(0, WS_EX_ ...

  9. 布局中的BFC---重点是前言

    一.前言 说实话,听到BFC这个概念我心里一阵咯噔,这到底是什么?有种似曾相识的感觉,但是又很模糊.问了一下度娘,看到张鑫旭的<CSS深入理解流体特性和BFC特性下多栏自适应布局>.呀,原 ...

  10. ApiGen安装

    # 首先,下载ApiGen(http://apigen.org/apigen.phar) # *nix系统 下载phar文件后, 移动到PATH目录中,以保证全局有权限调用 $ mv apigen.p ...