机器学习实战之Apriori

1. 关联分析

1.1 定义

       关联分析是一种在大规模数据上寻找物品间隐含关系的一种任务.这种关系有2种形式:频繁项集和关联规则.

(1) 频繁项集(frequent item sets): 经常出现在一起的物品的集合;

       
(2) 关联规则(association rules): 暗示两种物品之间可能存在很强的关系.

1.2 量化关联分析是否成功的算法

      
支持度和可信度是用来量化关联分析是否成功的方法.

      
(1)支持度(support) : 一个项集的支持度被定义为数据集中包含该项集的记录所占的比例.
支持度针对项集而言,可以设置最小支持度,只保留满足最小支持度的项集.以下图中的清 单为例,
{豆奶}的支持度为4/5;{豆奶,尿布}的支持度为3/5.

      
(2) 可信度或置信度(confidence) : 针对关联规则定义的. 例如:
规则{尿布}->{葡萄酒}的可信度被定义为
"支持度{尿布,葡萄酒}/支持度{尿布}"  . 支持度{尿布,葡萄酒}为3/5 , 支持度{尿布}
为4/5, 即这条规则可信度为3/4. 这意味着对于包含"尿布"的所有记录,我们的规则对其中75%的记录都适用.




2. Apriori

2.1 问题: 假设一家商店里只有4种商品:0,1,2,3. 下图显示了所有可能被购买的商品组合:




对于单个项集的支持度,
通过遍历每条记录并检查该记录是否包含该项集来计算.但是对于包含N种物品的数据集共有中项集组合,重复计算上述过程是不现实的.

2.2 Apriori原理

   
Apriori原理能够减少计算量. 

    其内容是:
若某个项集是频繁的, 那么它的子集也是频繁的; 则其逆否命题也是正确的,即 若一个项集是非频繁的,
则它的所有超集也是非频繁的.

    举例说明:
已知阴影项集{2,3}是非频繁的。利用这个知识,我们就知道项集{0,2,3},{1,2,3}以及{0,1,2,3}也是非频繁的。也就是说,一旦计算出了{2,3}的支持度,知道它是非频繁的后,就可以紧接着排除{0,2,3}、{1,2,3}和{0,1,2,3}。使用该原理可以避免项集数目的指数增长,从而在合理时间内计算出频繁项集.




2.3 实现Apriori算法来发现频繁项集

(1) Apriori算法是发现频繁项集的一种方法. 其两个输入参数分别是数据集和最小支持度.

(2) Apriori算法流程: 

首先生成所有单个物品的项集列表; 然后扫描交易记录查看哪些项集满足最小支持度要求,去掉不满足最小支持度的项集.

对剩下来的集合进行组合以生成包含两个元素的项集;
然后扫描交易记录查看哪些项集满足最小支持度要求,去掉不满足最小支持度的项集.

上述过程重复直到所有项集都被去掉

(3) Apriori算法生成频繁项集的伪代码

数据集中的每条交易记录tran:

         
对每个候选项集can:

                      
检查交易记录tran是否包含候选项集can:

                      
若包含,则增加can的计数;

对每个候选项集:

        
若该候选项集的支持度不低于最小支持度, 则保留; 反之, 则去掉.

返回所有频繁项集列表

其具体实现代码如下:

#c1是所有单个物品的集合

def createC1(dataSet):

    c1 =
[]

    for
transaction in dataSet:

  
   
 for item in transaction:

  
   
   
 if not [item] in c1:

  
   
   
   
 c1.append([item])

  
 c1.sort()

    return
map(frozenset,c1)  #frozenset是不能改变的集合,用户不能修改



#由ck得到lk的过程,即从ck选出支持度不小于指定值的项构成lk

def scanD(data,ck,minSupport):

  
 #统计每个候选项集及其对应的出现次数  
 

    ssCnt =
{}

    for
transaction in data:

  
   
 for can in ck:

  
   
   
 if can.issubset(transaction):

  
   
   
   
 if not ssCnt.has_key(can):

  
   
   
   
   
 ssCnt[can] = 1

  
   
   
   
 else:

  
   
   
   
   
 ssCnt[can] = 1



  
 #去掉不满足最小支持度的候选项集

    numItems =
float(len(data))

    retList = []
#存储满足支持度不低于最小值的项集

    supportData
= {} #存储所有项集及其支持度

    for key in
ssCnt:

  
   
 support = ssCnt[key]/numItems

  
   
 if support >= minSupport:

  
   
   
 retList.insert(0,key)

  
   
 supportData[key] = support

    return
retList,supportData #返回的retlist是ck中满足最小支持度项集的集合

(4) Apriori完整的实现

整个Apriori算法的伪代码如下:

当集合中项的个数大于0时:

          
构建一个k个项组成的候选项集的列表(k从1开始)

          
遍历数据集来筛选并保留候选项集列表中满足最小支持度的项集

          
构建由k 1个项组成的候选项集的列表

以下是实现代码:

#由频繁集lk和项集个数生成候选集ck,其中lk中每一项中含有元素k-1个,生成的ck中每一项中含有元素k个

def aprioriGen(lk,k):

    retList =
[]

    lenlk =
len(lk)

  
 #retList可能会为空

    for i in
range(lenlk):

  
   
 for j in range(i
1,lenlk): 

  
   
 #只有在两项中前k-2个元素一样时,将这两个集合合并(这样合并得到的大小就为k)

  
   
   
   
   
   
 

  
   
   
 l1 = list(lk[i])[:k-2]

  
   
   
 l2 = list(lk[j])[:k-2]

  
   
   
 l1.sort();
l2.sort()  
   
   
 

  
   
   
 if l1 == l2:

  
   
   
   
 retList.append(lk[i] | lk[j])

    return
retList

*** 在候选项集生成过程中, 只有在前k-2个项相同时才合并, 原始频繁项集中每一项含有k-1个元素,
为了合成得到每一项大小是k的候选项集列表,只有在前k-2项相同时,最后一项不同时,才有可能得到频繁项集.注意这里不是两两合并,
因为限制了候选项集的大小.

def apriori(dataSet,minSupport =
0.5):

  
 #单独产生c1,l1  
 

    c1 =
createC1(dataSet)

    data =
map(set,dataSet)

  
 l1,supportData = scanD(data,c1,minSupport)
#得到l1,大小为1的频繁项集集合

    

  
 #由l1得到c2,c2得到l2,依次循环

    l =
[l1]

    k = 2

  
 #当lk为空时,退出循环

    while
(len(l[k-2]) > 0):

  
   
 ck = aprioriGen(l[k-2],k)

  
   
 lk,supportK = scanD(data,ck,minSupport)

  
   
 supportData.update(supportK)

  
   
 l.append(lk)

  
   
 k = 1

    return
l,supportData #所有的频繁集及其支持度

3. 从频繁项集中挖掘相关规则

3.1 关联规则的量化指标是可信度. 

      
一条规则P?H的可信度定义为support(P |
H)/support(P),其中“|”表示P和H的并集。可见可信度的计算是基于项集的支持度的。

      
下图给出一个频繁项集{0,1,2,3}产生的关联规则,
其中阴影区域给出的是低可信度的规则.可以发现如果{0,1,2}?{3}是一条低可信度规则,那么所有其他以3作为后件(箭头右部包含3)的规则均为低可信度的.因为{3}的支持度肯定比包含3的项集的支持度要高,
即分子没变,但是分母增加, 则得到的可信度就降低了.

         
结论:若某条规则不满足最小可信度要求, 则其规则的所有子集也不会满足最小可信度要求. 以图4为例,假设规则{0,1,2} ?
{3}并不满足最小可信度要求,那么就知道任何左部为{0,1,2}子集的规则也不会满足最小可信度要求。

        
利用此结论可以大大减少需要测试的规则数目.

3.2 关联规则生成函数

函数generateRules()是主函数,调用另2个函数.其他两个函数是rulesFromConseq()和calcConf(),分别用于生成候选规则集合以及对规则进行评估(计算可信度)。

(1)
函数generateRules()有3个参数:频繁项集列表L、包含那些频繁项集支持数据的字典supportData、最小可信度阈值minConf。函数最后要生成一个包含可信度的规则列表bigRuleList,后面可以基于可信度对它们进行排序。L和supportData正好为函数apriori()的输出。该函数遍历L中的每一个频繁项集,并对每个频繁项集构建只包含单个元素集合的列表H1。代码中的i指示当前遍历的频繁项集包含的元素个数,freqSet为当前遍历的频繁项集(回忆L的组织结构是先把具有相同元素个数的频繁项集组织成列表,再将各个列表组成一个大列表,所以为遍历L中的频繁项集,需要使用两层for循环)。

#关联规则生成函数

def generateRules(L,supportData,minConf=0.7):

  
 #存储所有关联规则  
 

    bigRuleList
= []



    for i in
range(1,len(L)): #一条关联规则至少需要2个元素,故下标从1开始

  
   
 for freqSet in L[i]: #frequent为大小为i的项集

  
   
   
 H1 = [] #对每个频繁项集构了,建只包含单个元素的集合,即可以出现在规则右边

  
   
   
 for item in freqSet:

  
   
   
   
 H1.append(frozenset([item]))

  
   
   
 if (i > 1):

  
   
   
   
 H1 =
calcConf(freqSet,H1,supportData,bigRuleList,minConf)

  
   
   
   
 #包含三个及以上元素的频繁集

  
   
   
   
 rulesFromConseq(freqSet,H1,supportData,bigRuleList,minConf)

else:

  
   
   
   
 #包含两个元素的频繁集

  
   
   
   
 calcConf(freqSet,H1,supportData,bigRuleList,minConf)

return
bigRuleList

(2)calcConf函数: 计算规则的可信度,并过滤出满足最小可信度要求的规则.
返回值prunedH保存规则列表的右部,这个值将在下一个函数rulesFromConseq()中用到。

函数实现代码如下:

#处理包含两个元素的频繁集,计算规则的可信度,并过滤出满足最小可信度要求的规则

def calcConf(freqSet,H,supportData,brl,minConf=0.7):

  
 #保存关联规则的列表

    prunedH =
[]



    for conseq
in H:

  
   
 #对一个频繁集合,其分母都是一样的,supprot{1,2}/support{1},supprot{1,2}/support{2}

conf =
supportData[freqSet]/supportData[freqSet-conseq]

  
   
 if conf >= minConf:

  
   
   
 print freqSet - conseq,
'---->',conseq,'  conf:',conf

  
   
   
 brl.append((freqSet-conseq,conseq,conf))

  
   
   
 prunedH.append(conseq)

    return
prunedH

(2) rulesFromConseq()函数; 根据当前候选规则集H生成下一层候选规则集 ;

      
H为规则右边可能出现的频繁项集, H中元素的长度逐渐增大; 比如 原频繁集包含3个元素,则出现在规则右边的元素可能有1个,2个;
假设规则{0,1,2} ?
{3}并不满足最小可信度要求,那么就知道任何左部为{0,1,2}子集的规则也不会满足最小可信度要求,即不考虑{0,1} ?
{2,3}。因此我们先从右边只有一个元素时开始,只有存在可以出现在规则右边的元素,右边才有可能出现元素个数为2的情况.数据分析师培训



代码如下:

#根据当前候选规则集H生成下一层候选规则集,H是可以出现在规则右边的元素列表

def rulesFromConseq(freqSet,H,supportData,brl,minConf=0.7):

  
 #可以出现在规则右边的元素个数[1]=1,[1,2]=2,从1个元素增加直到小于freqSet的总个数都行

m =
len(H[0])



    if
(len(freqSet) > (m 1)):

  
   
 hmp1 = aprioriGen(H,m 1) #产生大小为m
1的频繁集列表,(1,2->3)->(1->2,3),生成下一层H

hmp1 =
calcConf(freqSet,hmp1,supportData,brl,minConf)

  
   
 if (len(hmp1) >
1):#规则右边的元素个数还可以增加

  
   
   
 rulesFromConseq(freqSet,hmp1,supportData,brl,minConf)

机器学习实战之Apriori的更多相关文章

  1. 基于Python的机器学习实战:Apriori

    目录: 1.关联分析 2. Apriori 原理 3. 使用 Apriori 算法来发现频繁集 4.从频繁集中挖掘关联规则 5. 总结 1.关联分析  返回目录 关联分析是一种在大规模数据集中寻找有趣 ...

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

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

  3. Python两步实现关联规则Apriori算法,参考机器学习实战,包括频繁项集的构建以及关联规则的挖掘

    .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px so ...

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

    机器学习实战(Machine Learning in Action)学习笔记————07.使用Apriori算法进行关联分析 关键字:Apriori.关联规则挖掘.频繁项集作者:米仓山下时间:2018 ...

  5. 机器学习实战笔记(Python实现)-00-readme

    近期学习机器学习,找到一本不错的教材<机器学习实战>.特此做这份学习笔记,以供日后翻阅. 机器学习算法分为有监督学习和无监督学习.这本书前两部分介绍的是有监督学习,第三部分介绍的是无监督学 ...

  6. 机器学习实战 - 读书笔记(12) - 使用FP-growth算法来高效发现频繁项集

    前言 最近在看Peter Harrington写的"机器学习实战",这是我的学习心得,这次是第12章 - 使用FP-growth算法来高效发现频繁项集. 基本概念 FP-growt ...

  7. 【机器学习实战】Machine Learning in Action 代码 视频 项目案例

    MachineLearning 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远 Machine Learning in Action (机器学习实战) | ApacheCN(apa ...

  8. 机器学习实战(Machine Learning in Action)学习笔记————10.奇异值分解(SVD)原理、基于协同过滤的推荐引擎、数据降维

    关键字:SVD.奇异值分解.降维.基于协同过滤的推荐引擎作者:米仓山下时间:2018-11-3机器学习实战(Machine Learning in Action,@author: Peter Harr ...

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

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

随机推荐

  1. (3)mysql表和字段的操作

    创建表 create table name( id int, student ) ); 查看表结构 ****常用**** describe 表名; 修改表名 老表 rename 新表 ALTER TA ...

  2. HDU-1698-Just a Hook-区间更新+线段树成段更新

    In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of the heroes. T ...

  3. Vue .sync修饰符与$emit(update:xxx)写法问题

    在学习vue自定义事件的.sync修饰符实现改变数值时发现一个问题如下由于props的大小写命名:fatherNum,对应不同的$emit()会有不同的效果,具体如下: 使用.sync修饰符,即 // ...

  4. Django之跨表查询——正反向查询(ManyToManyField)

    1.多对多查询:涉及到两张表以上的查询. author_obj = models.Author.objects.first() print(author_obj.name) # 查询金老板写过的书 r ...

  5. VMware Workstation 10 配置Ubuntu环境

    分享到 一键分享 QQ空间 新浪微博 百度云收藏 人人网 腾讯微博 百度相册 开心网 腾讯朋友 百度贴吧 豆瓣网 搜狐微博 百度新首页 QQ好友 和讯微博 更多... 百度分享 VMware Work ...

  6. mac系统升级导致无法在iOS设备中运行Safari Web 调试器

    macOS系统升级之后,可能会导致Safari开发选项中没有iOS设备,进而无法运行Safari Web 调试器. 此问题的解决办法: 请转到设置>常规>重置>重置位置和隐私.现在, ...

  7. 在使用python语言的open函数时,提示错误OSError: [Errno 22] Invalid argument: ‘文件路径’

    如题,在使用python语言的open函数时,提示错误OSError: [Errno 22] Invalid argument: '文件路径',在查阅了大量资料后也得到了一些解决方案,但是这些解决方案 ...

  8. 机器学习-线性回归算法(单变量)Linear Regression with One Variable

    1 线性回归算法 http://www.cnblogs.com/wangxin37/p/8297988.html 回归一词指的是,我们根据之前的数据预测出一个准确的输出值,对于这个例子就是价格,回归= ...

  9. hadoop 环境下不知道yarn端口可以通过此命令查找

    yarn jar hadoop-examples-2.6.0-mr1-cdh5.10.0.jar pi 1 30 hadoop-examples-2.6.0-mr1-cdh5.10.0.jar 此JA ...

  10. centos 7 开机启动服务项优化

    1. 使用 systemctl list-unit-files 可以查看启动项 systemctl list-unit-files | grep enable 过滤查看启动项如下 abrt-ccpp. ...