初探决策树之ID3算法

优点: 计算复杂度不高,输出结果易于理解,对中间值得缺失不敏感,可以处理不相关特征数据
缺点: 可能会产生过度匹配问题(过拟合)
适用数据类型:数值型和标称型

一. 初始算法结构

def createBranch():
    检测数据集中的每个子项是否属于同一分类:
          If so return  类标签
          Else
                寻找划分数据集的最好特征
                划分数据集
                创建分支节点
                    for 每个划分的子集
                        调用函数createBranch并增加返回结果到分支节点中
                 return 分支节点

二. 思考问题

  1. 怎么找最好特征
  2. 离散值和连续性值数据如何处理
  3. 算法过拟合问题如何处理
  4. 分类效果如何
    4.1 编码实现
    4.2 结合Kaggle或UCI数据测试
    4.3 遇到问题如何解决
  5. 下一步学习方向

下面将围绕上述问题进行一一展开学习

三. 解决问题

  1. 怎么找最好特征

    在ID3算法里面采用计算信息增益(Informatica Gain)的方式来选取最佳特征,而信息增益又是由香农熵(Shannon Entropy)的变化而来的。

    香农熵计算方式:

    • Entropy(D)=ni=1p(xi)log2p(xi)

    • 香农熵反应的是数据的有序程度,当香农熵越大时,说明数据越无序。

    • InfoGain(D,a)=Entropy(D)Vv=1|Dv||D|Entropy(Dv)

    • 上述表示的是用属性a作为划分得到的信息增益值,其中V表示离散属性a可能的取值集合{ a1,a2,...,aV },最好特征选取就是选择Info Gain最大的那个特征。
  2. 离散值和连续性值数据如何处理

    注意到,ID3目前不支持连续性值当的处理,关于连续值得处理将放到下一篇学习ID3的改进算法C4.5算法学习中讲解。

  3. 算法过拟合问题如何处理

    在ID3算法中未考虑过拟合问题,将在C4.5学习中讲解(预剪枝和后剪枝做法)。

  4. 分类效果如何
    4.1 编码实现

    • 最好特征的选取方式

      def chooseBestFeatureToSplit(self, dataSet):
          numFeatures = len(dataSet[0]) - 1
          baseEnt = self.calcEntropy(dataSet)
          bestInfoGain = 0.0 # 存放最好的信息增益值
          bestFeature = -1
          for i in range(numFeatures):
              columnList = [tmp[i] for tmp in dataSet]
              columVauleSet = set(columnList)
              tmpEntropy = 0.0
              for value in columVauleSet:   # 统计出按照每个特征 按照某个元素划分的熵*权重
                  subDataSet = self.splitDataSetByAxis(dataSet, i, value)
                  prob = len(subDataSet) / float(len(dataSet))
                  tmpEntropy += prob * self.calcEntropy(subDataSet)
              infoGain = baseEnt - tmpEntropy   # 注意熵越低越好,熵
              if infoGain> bestInfoGain:   # 信息增益越大越好
                  bestInfoGain = infoGain
                  bestFeature = i
          return bestFeature
      
    • 决策树创建代码

      def chooseBestFeatureToSplit(self, dataSet):
          numFeatures = len(dataSet[0]) - 1
          baseEnt = self.calcEntropy(dataSet)
          bestInfoGain = 0.0 # 存放最好的信息增益值
          bestFeature = -1
          for i in range(numFeatures):
              columnList = [tmp[i] for tmp in dataSet]
              columVauleSet = set(columnList)
              tmpEntropy = 0.0
              for value in columVauleSet:   # 统计出按照每个特征 按照某个元素划分的熵*权重
                  subDataSet = self.splitDataSetByAxis(dataSet, i, value)
                  prob = len(subDataSet) / float(len(dataSet))
                  tmpEntropy += prob * self.calcEntropy(subDataSet)
              infoGain = baseEnt - tmpEntropy   # 注意熵越低越好,熵
              if infoGain> bestInfoGain:   # 信息增益越大越好
                  bestInfoGain = infoGain
                  bestFeature = i
          return bestFeature
      

    4.2 划分效果

    由于该算法实用性不强,为此本文未针对UCI数据集进行测试,采用《机器学习实战》书中的简单例子进行了样本可视化处理,在C4.5和后续的学习中会讲到真实数据的处理。

  5. 下一步学习

    下一步主要学习决策树的改进算法,以及boost相关算法,如XGBoost 和 AdaBoost ,再学习Random Forecast。最终总结各个算法的优缺点以及在数据集中的表现。

    • 最后附上Github地址:
      机器学习造轮子记录

参考资料

  • 《Machine Learning in Action》,Peter Harringtion
  • https://en.wikipedia.org/wiki/ID3_algorithm
  • Quinlan, J. R. 1986. Induction of Decision Trees. Mach. Learn. 1, 1 (Mar. 1986), 81–106

你可能感兴趣的:(机器学习之路,算法,id3决策树)