Machine Learning笔记 之 关联项挖掘

来源:互联网 发布:淘宝刻印落款加钱 编辑:程序博客网 时间:2024/06/03 09:59
#coding=utf-8#由频繁项集 推出规则 两个条件'''设定阈值:1、频繁阈值2、置信度阈值      剪枝策略:      1、项集频繁 则子项集频繁      2、项集非频繁 项集超集非频繁      以此进行剪纸搜索支持度 个数1->2,3s(1,2,3)/s(1)置信度 支持度/总的支持度置信度大的为规则'''class Apr:      def __init__(self,traindata,level_s,level_c):            self.data=traindata            self.s=level_s            self.c=level_c            self.numFlag=1            self.enums=[]            self.res=self.getRes()            self.rules=self.getRules()      def getRes(self):            #循环获取  直到最后一个            #self.getKN(datak)            res=[]            i=1            #产生初始data.k            datak= self.combine(self.data,1)            while 1:                  i+=1                  datak=self.getKN(datak)                  res.append(datak)                  #print datak,i                  if(len(datak)==0):                        return res[:-1]                  datak=self.combine(datak,i)      def getKN(self,datak):            for j in range(len(datak)):                  datak[j][1]=self.count(datak[j][0])            #print datak            datak=self.cut(datak)            return datak      def combine(self,data2,k):            #data2            #datak=[]            #获取kN            #data2 转换为 lisA            #由data2 产生 长度为k 的子集]            lisA=[]            for i in data2:                  if k==1:                        lisA+=i                  else:                        lisA+=i[0]            #print lisA,k            lisA=list(set(lisA))            if k==1:                  self.enums=lisA            RE=self.getSon(lisA,k)            return RE      def getSon(self,lisA,k):            RE=[]            #这里使用二进制的方法获取子集,算法有待继续优化            for i in range(pow(2,len(lisA))-1):                  if bin(i).count('1')==k:                        RE.append([[],[]])                        for j in range(len(bin(i)[2:])):                              if bin(i)[2:][j]=='1':                                    RE[-1][0].append(\                                          lisA[j+len(lisA)-len(bin(i)[2:])])            return RE      def cut(self,data3):            data4=[]              for i in range(len(data3)):                  if data3[i][1]>=self.s:                        data4.append(data3[i])            return data4      def count(self,lisA):            count=0            for j in range(len(self.data)):                  flag=1                  for i in lisA:                        if i not in self.data[j]:                              flag=0                              break                  if flag==1:                        count+=1            return count      #用字典的结构更好 这里不进行代码重构了      def  getRules(self):            rules=[]            lis=self.res[-1]            #这里 定义如下数据结构 由a推出b, score为置信度   [[[a],[b],score],...]            #切分a,b 求score 考虑到重复性 有如下规则            #代码思考及优化:以少推多是逻辑上不完备的,可在这儿设置阈值            mid=len(lis[0][0])/2+1            for j in range(len(lis)):                  for i in range(1,mid+1):                        res=self.getSon(lis[j][0],i)                        for k in range(len(res)):                              res2=self.subList(res[k][0],lis[j][0])                              s1=self.getScore(res[k][0])                              s2=self.getScore(lis[j][0])                              #计算bvalue s(res[k][0])/res2                              bvalue=1.0*s2/s1                              if bvalue>self.c:                                    rules.append([res[k][0],res2,bvalue])            rules.sort(reverse=False)            return rules      def getScore(self,lis):            score=0            res=self.res[len(lis)-1]            for re in res:                  if self.equalL(lis,re[0]):                        score=re[1]            return score      def equalL(self,lisA,lisB):            if len(lisA)==len(lisB):                  for la in lisA:                        if la not in lisB:                              return False                  return True            return False      def subList(self,lisA,lisB):            #lisB是爸爸             li=[]            for lb in lisB:                  if lb not in lisA:                        li.append(lb)            return li      def  getRulesK(self,inpu,k):            #输入 inpu , k个, 构造len(inpu)+k矩阵            #计算支持度            RES=[]            #得到lisM            lisM=self.subList(inpu,self.enums)            lisM=self.getSon(lisM,k)            s1=self.getScore(inpu)            for lis in lisM:                  s2=self.getScore(lis[0]+inpu)                  if s2!=0:                        score=1.0*s2/s1                        RES.append([inpu,self.subList(inpu,lis[0]),score])            RES.sort(reverse=False)            if len(RES)>0:                  return RES            else:                  return "Please decrease K value or change INPUT"data= [      ["I1","I2","I5"],      ["I2","I4"],      ["I2","I3"],      ["I1","I2","I4"],      ["I1","I3"],      ["I2","I3"],      ["I1","I3"],      ["I1","I2","I3","I5"],      ["I1","I2","I3"]  ]inpu=["I1"]apr1=Apr(data,2,0.5)print apr1.rulesres=apr1.getRulesK(inpu,2)print res
原创粉丝点击