失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 《机器学习实战》chapter 11 使用apriori算法进行关联分析

《机器学习实战》chapter 11 使用apriori算法进行关联分析

时间:2023-09-09 23:39:12

相关推荐

《机器学习实战》chapter 11 使用apriori算法进行关联分析

使用apriori算法进行关联分析apriori原理:1、一个项集是非频繁的,那么它的所有超集也是非频繁的2、一个项集是频繁的,那么它的所有子集也是频繁的一、支持度(support)-使用apriori发现频繁项集对于数据集(包含M个项集)1、求单个元素组成项集的集合C1(无重复)2、利用minsupport(最小支持度或非频繁)过滤掉非频繁的单元素项集,得L13、单个元素两两组合成2元素的项集的集合C24、利用minsupport(最小支持度或非频繁)过滤掉非频繁的2元素项集,得L25、利用2元素项集两两组合得3元素项集C36、利用minsupport(最小支持度或非频繁)过滤掉非频繁的3元素项集,得L37、重复上述过程求支持度(过滤支持度)低的项集就是这样一个过程:C1->L1->C2->L2->C3->L3->....->Ck->Lkapriori的应用:一个项集是非频繁的,那么它的所有超集也是非频繁的要获得项集合并(每种可能集合)的支持度就需要多次重复上述过程,例如

由图可以看出,对于仅有4个物品的集合,也需要遍历15次,如果是100种呢?事实上,对于N种物品的数据集共有2^N - 1种项集组合,也就是说我们需要遍历2^N - 1次。如上图,C2=[{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}],其中 {2, 3}是非频繁的,由apriori我们知道他的超集也是非频繁的,所以我们这里直接过滤掉非频繁的{2, 3}得到L2=[{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}]这时,由L2组合得到的C3就比由C2组合得到的C3少了两种可能(没有了{0, 2, 3}, {1, 2, 3}),也不存在C4了。如果放到更大的数据集种,apriori的效果将更加可观。

二、置信度(confidence)-从频繁项集挖掘关联规则如果有一个关联规则{豆奶,莴苣},那么就可能有一条关联规则“豆奶-->莴苣”,这意味着如果有人买了豆奶,那么在统计上他会购买莴苣的概率比较大。但是,这一条反过来并不总是成立。也就是说,即使“豆奶-->莴苣”统计上显著,那么“莴苣-->豆奶”也不一定成立。就比方说{啤酒,尿布}这个项集,“啤酒-->尿布”,我们说男人在下班后给孩子买尿布的同时,会顺手购买自己爱喝的啤酒。但是去买啤酒的男人,又有多少是刚有孩子的?这个概率是要小很多的。类似于,上一节的频繁项集的生成,我们可以为每个频繁项集产生许多关联规则。

如果能够减少规则数目来确保问题的可解性,那么计算起来就会好很多。apriori的应用:如果某条规则并不能满足最小可信度要求,那么该规则的所有子集也不会满足最小可信度要求。上图中,假设0, 1, 2-->3不满足最小可信度要求,那么就知道任何左部为{0, 1, 2}子集的规则也不会满足最小可信度要求。算法过程:对于频繁项集列表L:[[{1}, {2}, {3}, {5}][{1, 3}, {2, 5}, {2, 3}, {3, 5} ][{2, 3, 5} ]]

生成关联规则_function():遍历L:计算规则右部只有单个元素的置信度(并过滤掉不满足最低置信度阈值的规则)如果频繁项集中的元素个数有3个或更多计算右部有2个、3个...len(freqSet)-1个元素的规则置信度

注意:1、遍历L时从至少有2个元素的项集开始,只有一个元素,就不存在关联规则了2、对每一个频繁项集freqSet,求只有单个元素的项集组成的列表H1,用H1作为规则右部3、频繁项集元素个数有3个或3个以上时,用len(H1[0]) + 1作为递归变量,累加右部元素个数4、apriori的应用:先求右部为单个元素的规则置信度,将不满足最低置信度阈值的0, 1, 2-->3剔除,这样,左部为{0, 1, 2}的所有子集的规则也直接被剔除不再计算。5、修正书中一个我认为不正确的地方

这个函数中,书中代码在频繁项集个数大于2时,只计算了规则右部为两个或两个以上元素的情况,而漏算了规则右部只有一个元素的情况。修正部分如下:

如理解有偏差,欢迎批评指正。

代码部分:

# !/usr/bin/env python# -*- coding: utf-8 -*-def loadData():return [[1, 3, 4], [2, 3, 5], [1, 2, 3, 5, ], [2, 5]]def createC1(dataSet):"""构建大小为1的所有候选项集的集合:param dataSet::return:"""C1 = []for transaction in dataSet:for item in transaction:if not [item] in C1:C1.append([item])C1.sort()return list(map(frozenset, C1))def scanD(D, Ck, minSupport):"""Ck中的元素经过最小支持度过滤得到Lk,和每个元素的支持度:param D: 数据集:param Ck::param minSupport: 最小支持度(过滤):return:过程:对数据集中的每条交易记录tran对每个候选项集can:检查一下can是否是tran的子集:如果是:则增加can的计数值如果不是:把can的值设为1对每个候选项集:如果其支持度不低于最小值,则保留该项集返回所有频繁项集列表"""ssCnt = {}for tid in D:for can in Ck:if can.issubset(tid):if can not in ssCnt:ssCnt[can] = 1else:ssCnt[can] += 1numItems = float(len(D))retList = []supportData = {}for key in ssCnt:support = ssCnt[key] / numItemsif support >= minSupport:retList.insert(0, key)supportData[key] = supportreturn retList, supportDatadef aprioriGen(Lk, k):"""合并频繁项集为k个元素:param Lk: 频繁项集列表:param k: 项集元素个数:return:"""retList = []lenLk = len(Lk)for i in range(lenLk):for j in range(i+1, lenLk):# 每一个项集同其后面的项集做比较# 如果前k-2个元素相同(取不到k-2),则合并为k个元素的项集,添加到retList中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 retListdef Apriori(dataSet, minSupport=0.5):""":param dataSet: 数据集:param minSupport: 最小支持度:return:过程:C1->L1->C2->L2->C3->L3-> ... ->Ck->Lk"""# 单个物品项组成的集合C1 = createC1(dataSet)# 集合表示的数据集DD = list(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, supportDatadef calcConf(freqSet, H, supportData, bigRuleList, minConf=0.7):"""从频繁项集freqSet,计算关联规则(freqSet - H) --> H的置信度并过滤置信度低于最小置信度阈值的规则:param freqSet: 频繁项集:param H: 出现在规则右部:param supportData: 支持度字典:param bigRuleList: 关联规则列表:param minConf: 最小置信度阈值:return: 满足最小可信度要求的规则列表"""# 初始化满足最小可信度要求的规则列表prunedH = []for conseq in H:conf = supportData[freqSet] / supportData[freqSet - conseq]if conf >= minConf:print(freqSet-conseq, "-->", conseq, "conf : ", conf)bigRuleList.append((freqSet - conseq, conseq, conf))# 与bigRuleList对应的置信度值列表prunedH.append(conseq)return prunedHdef rulesFromConseq(freqSet, H, supportData, bigRuleList, minConf=0.7):"""由于freqSet中的元素个数大于等于3,计算规则的右部为多个元素的情形:param freqSet: 频繁项集:param H: 出现在规则右部的元素列表:param supportData: 支持度列表:param bigRuleList: 关联规则列表:param minConf: 最小置信度阈值:return:"""m = len(H[0])# m + 1,其实示一个递归变量,递归地增加右部元素个数if len(freqSet) > (m + 1):# 合并元素,任意组合成m+1个元素的项集Hmp1 = aprioriGen(H, m + 1)# 过滤关联规则(freqSet - Hmp1) --> Hmp1的置信度小于最小置信度阈值的规则# 规则右部有m + 1个元素Hmp1 = calcConf(freqSet, Hmp1, supportData, bigRuleList, minConf)# 递归累加右部元素个数if len(Hmp1) > 1:rulesFromConseq(freqSet, Hmp1, supportData, bigRuleList, minConf)else:# 当右部元素个数和频繁项集freqSet的长度一样时,不再划分,返回returndef generateRules(L, supportData, minConf=0.7):"""基于给定的频繁项集L和支持度supportData,计算满足最小支持度阈值的规则:param L: 频繁项集列表:param supportData: 包含那些频繁项集支持数据的字典:param minConf: 最小置信度阈值:return: 包含可信度的规则列表"""# 初始化规则存放列表bigRuleList = []# 遍历频繁项集for i in range(1, len(L)):#for freqSet in L[i]:# 只包含单个元素集合的列表H1H1 = [frozenset([item]) for item in freqSet]# 过滤关联规则(freqSet - H1) --> H1的置信度小于最小置信度阈值的规则# H1是右部为单个元素的情形H1 = calcConf(freqSet, H1, supportData, bigRuleList, minConf)if i > 1:# 如果频繁项集中元素个数大于等于3,就需要考虑右部为多个元素的情形rulesFromConseq(freqSet, H1, supportData, bigRuleList, minConf)return bigRuleListdataSet = loadData()L, supportData = Apriori(dataSet)rules = generateRules(L, supportData, minConf=0.7)print(rules)

如果觉得《《机器学习实战》chapter 11 使用apriori算法进行关联分析》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。