数据挖掘之关联规则挖掘(Apriori算法),数据挖掘apriori算法案例分析

  数据挖掘之关联规则挖掘(Apriori算法),数据挖掘apriori算法案例分析

  本文主要介绍了python数据挖掘中的关联分析Apriori算法。有需要的朋友可以借鉴一下,希望能有所帮助。祝大家进步很大,早日升职加薪。

  00-1010摘要:关联分析Apriori原理算法实现利用Apriori算法挖掘关联规则解决实际问题,发现毒蘑菇相似特征摘要:

  

目录

  主要阐述了Apriori算法原理在一些数据挖掘中频繁模式挖掘的应用实践。

  我们在买东西的时候会发现,物品的展示方式不一样,购物后的优惠券和用户忠诚度也不一样。但是,这些来源都是对大量数据的分析。为了从客户那里获得尽可能多的利润,我们需要使用各种技术来实现我们的目标。

  通过查看搭配哪些商品购物,可以帮助商店了解顾客的购买行为。这种从大规模数据集中寻找项目之间的隐含关系的方法被称为关联分析或关联规则学习。如果用蛮力算法寻找项目的不同组合,效率很低,需要用智能的方法寻找时间范围内的频繁项目集。

  

摘要:

  关联规则学习是在大规模数据集中发现有趣关系的任务。这些关系有两种形式:频繁项目集或关联规则。频繁项是频繁链接在一起的一组项,而关联规则意味着两个项之间有很强的关系。

  {酒,尿布,豆浆}是频繁项集,尿布-酒是关联规则。

  商家可以更好的了解客户。

  而频率的定义是什么?是支持和信誉。

  支持度是:该项目在数据集中所占的比例。{豆奶}支持4/5 {豆奶、尿布}支持3/5

  可信度:为关联规则定义。{尿布]-{葡萄酒}是支持度({A,B})/支持度({A})。根据这两种度量方法,但是在有上千个项目的情况下,如何计算这个组合列表呢?

  

关联分析

  例如,四种商品,我们考虑商品的组合:

  我们的目标是找到一起购买的商品集合。我们用集合的支持度来衡量出现的频率。随着物品数量的增加,比如我们有n种商品,那么就会有2个n-1组合的物品集。为了减少计算时间,提出了一种先验原则。

  先验原则:如果一个项集是频繁的,那么它的所有子集都是频繁的。

  推论:如果一个项集是不频繁的,那么我所有的超集也是不频繁的。

  我们用图表来说明:

  阴影{2,3}不常见,{0,2,3}、{1,2,3}、{0,1,2,3}也不常见。一旦计算出{2,3}的支持度,就知道它不频繁。不用计算{0,2,3],{1,2,3},{0,1,2,3}来避免指数增长。

  

Apriori原理

  Apriori算法是一种发现频繁项集的方法。两个输出参数是最小支持和数据集。首先,生成一个包含所有单项的项目列表,然后检查哪个项目集满足最低支持。接下来,去掉不满意的。将其余部分合并成2个二分项目集。继续重复删除不满足最小支持度的项集。

  数据集的每个事务的事务

  对于每个候选人,can:

  检查can是否为tran子集,并增加每个候选can:的计数。

  如果支持度不小于最小保持期,则返回所有频繁项集。

  代码如下:

  我们先实现两个函数。一个是最初生成C1候选集的函数。二是从候选集中选择满足支持度的频繁集。

  定义创建1(数据集):

  C1=[]

  对于数据集:中的事务

  对于交易:中的项目

  If[item in c 1: #如果它不在项集中

  C1 . append([项目])

  C1.sort()

  #可以用作键值

  返回地图(C1的frozenset)#每个元素都是一个frozenset

  #制造符合要求的L1,然后将L1并入C2。进一步渗透到L2。

  #frozenset可以用作键值。

  def scanD(D,Ck,minSupport):

  #首先查看记录中所有候选集的次数

  装新款

  t = {}

   for td in D:

   for can in Ck:

   if can.issubset(td):#如果是那个集合的子集

   if not ssCnt.has_key(can):ssCnt[can]=1

   else:ssCnt[can]+=1

   numCount = len(D)#记录的总数

   #记录每个项集的支持度

   supportData={}

   retList=[]

   for key in ssCnt.iterkeys():

   support = float(ssCnt[key]*1.0/numCount)

   if support>=minSupport:

   retList.insert(0,key)#加入满足条件的项集合的序列

   supportData[key] = support

   return retList,supportData

  

  测试这两个函数如下:

  

x = apriori.loadDataSet()

  C1 = apriori.createC1(x)#frozenset每个元素

  print C1

  #构建事物集

  D = map(set,x)#每个元素是集合

  L1,supportData0 = apriori.scanD(D,C1,0.5)

  print L1

  得到如下结果:

  

[frozenset([1]), frozenset([2]), frozenset([3]), frozenset([4]), frozenset([5])][frozenset([1]), frozenset([3]), frozenset([2]), frozenset([5])]

  

  而整体算法如下:

  当集合项个数大于0时候

  

  • 构建一个K个项组成的候选列表
  • 检查是否每个项集是频繁的
  • 保留频繁的并且构建K+1项的候选项列表

  

#前面K-1x项目相同的时候可以生成Lk

  def aprioriGen(Lk,k):

   #前面k-1项目相同就可以合成

   retList = []

   lenLk = len(Lk)

   for i in range(lenLk):

   for j in range(i+1,lenLk):

   L1 = list(Lk[i])[:k-2]#可以考虑1个元素的时候是0直接合并

   L2 = list(Lk[j])[:k-2]

   L1.sort()

   L2.sort()

   if L1==L2:

   retList.append(Lk[i]Lk[j])

   return retList

  def apriori(dataset,minSupport=0.5):

   C1 = createC1(dataset)

   D = map(set,dataset)

   L1,supportData = scanD(D,C1,minSupport)

   L = [L1]

   k = 2#项集为2

   #频繁n-1项目总数为

   while(len(L[k-2])>0):#因为项集存的位置是0

   Ck = aprioriGen(L[k-2],k)

   Lk,supK = scanD(D,Ck,minSupport)

   supportData.update(supK)#加入字典更新

   L.append(Lk)#L+1

   k+=1#当空集的时候退出

   return L,supportData

  测试如下:

  

dataSet = apriori.loadDataSet()

  L,supportData = apriori.apriori(dataSet,minSupport=0.7)

  print L

  我们可以获得如下的频繁项集

  

[[frozenset([3]), frozenset([2]), frozenset([5])], [frozenset([2, 5])], []]

  

  

  

挖掘关联规则

  要找到关联规则。首先需要从频繁项集开始。我们知道集合中元素是不重复的,但是我们想基于这些元素获得其他内容。某个元素或者某个元素的集合可以推导另外一个元素。

  关联规则也可以想频繁项集一样量化。频繁项集是需要满足最小支持度的要求。

  对于关联规则我们就可以用可信度来衡量。一条规则的可信度为P->H定义为support{Ph}/support(P)其实也就是P条件下H的概率满足最小可信度就是关联规则

  

  如果某条规则不满足最小可信度的要求。假设{0,1,2}->{3}不满足最小可信度的要求。

  那么任何{0,1,2}的子集也不会满足最小可信度的要求。可以利用这个规则来 减少需要测试的规则数目。利用Apriori算法,进行首先从一个频繁项集合开始,创建一个规则列表。

  规则右部包含一个元素,然后对这些规则测试。接下来合并所有剩余 规则来创建一个新的规则列表,其中规则的右部包含两个元素。这种方法称为分级法。

  

#规则生成函数

  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()

   else:

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

   return bigRuleList

  #计算可信度

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

   prunedH = []

   for conseq in H:

   conf = supportData[freqSet]/supportData[freqSet-conseq]#获得条件概率(freq-conseq) -> conseq

   if conf>=minConf:

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

   brl.append((freqSet-conseq,conseq,conf))#加入这个元祖

   prunedH.append(conseq)#为后面准备。因为若不满足规则右边该元素基础下添加也不会满足

   return prunedH

  #最初的规则生成更多的规则

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

   m = len(H[0])

   if (len(freqSet)>(m+1)):#一直到该频繁项集能包含的右边推出等于项的个数-1为止例如{1,2,3,4}当{1}-{2,3,4}以后此时H[0]长度为3

   Hmp1 = aprioriGen(H,m+1)#右边推出过程类似生成过程

   Hmp1 = calcConf(freqSet,Hmp1,supportData,brl,minConf)#过滤过程返回被推出的右边的项集的集合

   if (len(Hmp1)>1):#若有新规则生成继续递归处理

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

  测试如下:

  

#生成所有频繁项集合

  dataSet = apriori.loadDataSet()

  L,supportData = apriori.apriori(dataSet,minSupport=0.5)

  #生成规则

  rules = apriori.generateRules(L,supportData,minConf=0.5)

  

  calcConf中输出的结果如下:

  

frozenset([3]) ---> frozenset([1]) conf: 0.666666666667

  frozenset([1]) ---> frozenset([3]) conf: 1.0

  frozenset([5]) ---> frozenset([2]) conf: 1.0

  frozenset([2]) ---> frozenset([5]) conf: 1.0

  frozenset([3]) ---> frozenset([2]) conf: 0.666666666667

  frozenset([2]) ---> frozenset([3]) conf: 0.666666666667

  frozenset([5]) ---> frozenset([3]) conf: 0.666666666667

  frozenset([3]) ---> frozenset([5]) conf: 0.666666666667

  frozenset([5]) ---> frozenset([2, 3]) conf: 0.666666666667

  frozenset([3]) ---> frozenset([2, 5]) conf: 0.666666666667

  frozenset([2]) ---> frozenset([3, 5]) conf: 0.666666666667

  

  

  

利用Apriori算法解决实际问题

  发现国会投票的模式

  加州大学的机器学习数据集合有一个1984年起的国会投票记录的数据集: 这个数据集合比较老。可以尝试一些新的数据。其中一个组织是投票工程。提供了一个公共的API。

  下面是如何收集数据的过程 而数据获取过程比较繁琐。以及键值对映射可以看《机器学习实战》这本书。

  我们主要针对已经获取的txt文本来进行挖掘

  构建投票记录的数据集:

  我们希望最后的数据集合格式是每一行代表美国国会的一个成员,每一列是投票的对象。

  

from votesmart import votesmartvotesmart.apikey = 'a7fa40adec6f4a77178799fae4441030'#votesmart.apikey = 'get your api key first'

  

  现在假设将议案的标题以及ID号保存为recent100bills.txt文件,可以通过getBill来获取每条议案的内容。

  如果要获取每条议案的投票信息用getBillActionVotes() 上面都是该API提供的功能。我们主要是针对数据的预处理阶段。我们需要将BillId转换成actionID

  

#只保留包含投票数据的actionId

  def getActionIds():

   fr = open(recent20bills.txt)

   actionIdList=[];billTitleList=[]

   for line in fr.readlines():

   billNum = int(line.split(\t)[0])

   try:

   billDetail = votesmart.votes.getBill(billNum)#获取议案对象

   for action in billDetail.actions:

   if action.level==House and \

   (action.stage==Passage or \

   action.stage==Amendment Vote):

   actionId = int(action.actionId)

   actionIdList.append(actionId)

   billTitleList.append(line.strip().split(\t)[1])

   except:

   print "problem gettin bill %d"%billNum

   sleep(1)

   return actionIdList,billTitleList

  我们获得的是类似Bill:12939 has actionId:34089这样的信息。我们需要频繁模式挖掘的话,需要将上面信息转换成项集或者交易数据库的东西。一条交易记录只有一个项出线还是没出现的信息,并不包含出现的次数。

  美国有两个主要政党:共和和民主。我们可以将这个特征编码为0和1.然后对投票.

  

#基于投票数据的事物列表填充函数

  def getTransList(actionIdList,billTitleList):

   itemMeaning = [Republican,Democratic]

   for billTitle in billTitleList:

   itemMeaning.append(%s -- Nay%billTitle)

   itemMeaning.append(%s -- Yea % billTitle)

   #创建事务字典

   transDict = {}

   voteCount = 2# 0,1是所属党派。2开始是被第几次投票

   for actionId in actionIdList:

   sleep(3)

   print getting votes for actionId: %d %actionId

   try:

   voteList = votesmart.votes.getBillActionVotes(actionId)

   for vote in voteList:

   if not transDict.has_key(vote.candidateName):

   transDict[vote.candidateName] = []

   if vote.officeParties ==Democratic:

   transDict[vote.candidateName].append(1)

   elif vote.officeParties==Republican:

   transDict[vote.candidateName].append(0)

   if vote.action==Nay:

   transDict[vote.candidateName].append(voteCount)

   elif vote.action==Yea:

   transDict[vote.candidateName].append(voteCount+1)

   except:

   print "problem getting actionId:%d" %actionId

   voteCount+=2

   return transDict,itemMeaning

  其实就是获取的事物集。每一条事物集是[0/1,哪条具体规则]

  就是将所有必要信息离散化编号然后统计整个投票过程

  最后得到类似的结果:

  

Prohibiting Federal Funding of National Public Radio -- Yea

   -------->

  Republican

  Repealing the Health Care Bill -- Yea

  confidence: 0.995614

  

  

  

发现毒蘑菇的相似特征

  有时候不是想要寻找所有的频繁项集合,只是队某个特征元素项集感兴趣。我们寻找毒蘑菇的公共特征,利用这些特征就能避免迟到有毒的蘑菇。

  UCI数据集合重有蘑菇的23种特征的数据集,每一个特征是标称数据。而我们需要将样本转换成特征的集合,枚举每个特征所有可能的举止,如果某个样本 包含特征,那么特征对应的整数应该被包含在数据集中 1 3 9 13 23 25 34 36 38 40 52 54 59 63 67 76 85 86 90 93 98 107 113 每一个样本都是这样的特征集合。

  如果第一个特征有毒就是2,如果能食用就是1,下一个特征是形状有6可能值,用整数3-8表示

  相当于把需要的特征维度都进行排列离散化。最终只有1个大维特征

  

mushDatSet = [line.split() for line in open(mushroom.dat).readlines()]

  L,suppData = apriori.apriori(mushDatSet,minSupport=0.3)

  #寻找毒的公共特征

  for item in L[1]:

   if item.intersection(2):print item

  

frozenset([2, 59])

  frozenset([39, 2])

  frozenset([2, 67])

  frozenset([2, 34])

  frozenset([2, 23])

  frozenset([2, 86])

  frozenset([76, 2])

  frozenset([90, 2])

  frozenset([2, 53])

  frozenset([93, 2])

  frozenset([63, 2])

  frozenset([2, 28])

  frozenset([2, 85])

  frozenset([2, 36])

  

  那么可以给我们的提示就是如果有特征编号是这些的就不要吃这种蘑菇了

  

  

总结:

  关联分析是发现大数据集合元素间关系的工具集。可以用在不同的物品上,主要是在样本处理上需要将样本转换成特征集合。也就是将所有维的特征统一编码。

  以上就是python数据挖掘Apriori算法实现关联分析的详细内容,更多关于Apriori算法关联分析的资料请关注盛行IT软件开发工作室其它相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: