Python实现决策树C4.5算法的示例

  


  

  

  

C4.5算法是在ID3算法上的一种改进,它与ID3算法最大的区别就是特征选择上有所不同,一个是基于信息增益比,一个是基于信息增益。

  

之所以这样做是因为信息增益倾向于选择取值比较多的特征(特征越多,条件熵(<强>特征划分后强劲的类别变量的熵)越小,信息增益就越大),因此在信息增益下面加一个分母,该分母是当前所选<强>特征的熵强,注意:这里而不是类别<强>变量的熵了。

  

这样就构成了新的特征选择准则,叫做信息增益比。为什么加了这样一个分母就会消除ID3算法倾向于选择取值较多的特征呢?

  

因为特征取值越多,该特征的熵就越大,分母也就越大,所以信息增益比就会减小,而不是像信息增益那样增大了,一定程度消除了算法对特征取值范围的影响。
  

  

  

在算法实现上,C4.5算法只是修改了信息增益计算的函数calcShannonEntOfFeature和最优特征选择函数chooseBestFeatureToSplit。

  

calcShannonEntOfFeature在ID3的calcShannonEnt函数上<强>加了个参数壮举强,ID3中该函数只用计算类别变量的熵,而calcShannonEntOfFeature可以计算指定特征或者类别变量的熵。

  

chooseBestFeatureToSplit函数在计算好信息增益后,同时计算了<强>当前特征的熵IV 强,然后相除得到信息增益比,以最大信息增益比作为最优特征。

  

在划分数据的时候,有可能出现特征取同一个值,那么该特征的熵为0,同时信息增益也为0(类别变量划分前后一样,因为特征只有一个取值),0/0没有意义,可以跳过该特征。
  

  

 Python实现决策树C4.5算法的示例

        #=utf - 8编码   进口经营者   从数学导入日志   导入的时间   导入系统,系统   进口的字符串      def createDataSet (trainDataFile):   打印trainDataFile   数据集=[]   试一试:   鳍=开放(trainDataFile)   在鳍线:   行=line.strip ()   关口=line.split (“\ t”)   行=[关口[1],[2]的山谷,关口[3],[4]的山谷,关口[5],[6]的山谷,关口[7],[8]的山谷,关口[9],关口[10],[0]]的山谷   dataSet.append(行)   打印行号   除了:   打印“使用xxx。py trainDataFilePath”   西斯退出()   标签=[‘cip1’,‘cip2’,‘cip3’,‘cip4’,‘sip1’,‘sip2’,‘sip3’,‘sip4’,‘运动’,‘域’)   打印dataSetlen, len(数据集)   返回数据集,标签      # calc香农熵的标签或特性   def calcShannonEntOfFeature(数据集,专长):   numEntries=len(数据集)   labelCounts={}   feaVec的数据集:   currentLabel=feaVec(专长)   如果currentLabel不在labelCounts:   labelCounts [currentLabel]=0   labelCounts [currentLabel] +=1   shannonEnt=0.0   在labelCounts关键:   概率=浮动(labelCounts[主要])/numEntries   shannonEnt -=概率*日志(问题2)   返回shannonEnt      def splitDataSet(数据集、轴、价值):   retDataSet=[]   featVec的数据集:   如果featVec(轴)==值:   reducedFeatVec=featVec(轴):   reducedFeatVec.extend (featVec[轴+ 1:])   retDataSet.append (reducedFeatVec)   返回retDataSet      def chooseBestFeatureToSplit(数据):   numFeatures=len(数据集[0])——1 #最后坳是标签   baseEntropy=calcShannonEntOfFeature(数据集,1)   bestInfoGainRate=0.0   bestFeature=1   因为我在范围(numFeatures):   featList=(例子[我]例如数据集)   uniqueVals=集(featList)   newEntropy=0.0   uniqueVals价值:   subDataSet=splitDataSet(数据集,我,值)   概率=len (subDataSet)/浮动(len(数据集)   newEntropy +=概率* calcShannonEntOfFeature (subDataSet, 1) # calc条件熵   infoGain=baseEntropy - newEntropy   4=calcShannonEntOfFeature(数据集,我)   如果(iv==0): #价值的功能都是一样的,infoGain和第四都等于0,跳过功能   继续   infoGainRate=infoGain/iv   如果infoGainRate比;bestInfoGainRate:   bestInfoGainRate=infoGainRate   bestFeature=我   返回bestFeature      #特性是详尽的,回来你想要的标签   def majorityCnt(班级名册):   classCount={}   在班级名册投票:   如果投票不在classCount.keys ():   classCount(投票)=0   classCount【投票】+=1   返回马克斯(classCount)      def createTree(数据集、标签):   班级名册=(例子[1]例如数据集)   如果classList.count(班级名册[0])==len(班级名册):#所有的数据是相同的标签   返回班级名册[0]   如果len(数据集[0])==1:#所有特性是详尽   返回majorityCnt(班级名册)   bestFeat=chooseBestFeatureToSplit(数据集)   bestFeatLabel=标签(bestFeat)   如果(bestFeat==1): #特征一样,但类别不一样,即类别与特征不相关,随机选第一个类别做分类结果   返回班级名册[0]   myTree={bestFeatLabel: {}}   德尔(标签(bestFeat))   featValues=[示例(bestFeat)例如在数据集)   uniqueVals=集(featValues)   uniqueVals价值:   subLabels=标签[:]   myTree [bestFeatLabel][]价值=createTree (splitDataSet(数据集,bestFeat、价值),subLabels)   返回myTree      def main ():   如果(len (sys.argv) & lt;3):   打印“使用xxx。py小火车outputTreeFile”   西斯退出()   数据标签=createDataSet (sys.argv [1])   t1=time.clock ()   myTree=createTree(数据、标签)   t2=time.clock ()   输出信号=(sys开放。argv [2], ' w ')   fout.write (str (myTree))   fout.close ()   打印“执行”,t2-t1   if __name__==癬_main__”:   main ()

Python实现决策树C4.5算法的示例