Python实现决策树_ID3算法

决策树:

ID3算法:
1、香农熵:
如果待分类的事务可能划分在多个分类中,则  x   的信息定义为: 其中 p (   x ) 选择该分类的概率。
熵定义为信息的期望值,计算公式为:当熵越高时,说明不同类型的数据越多,数据集集合无序程度越高。
选择dataSet数据集中最后一项分类( featVec[- 1 ])的香农熵计算,代码实现如下:

  1. import math
  2. def calcShannonEnt(dataSet):
  3.     numEntries = len(dataSet)
  4.     labelCounts = {}
  5.     for featVec in dataSet:
  6.         currentLabel = featVec[-1]
  7.         labelCounts[currentLabel] = labelCounts.get(currentLabel, 0) + 1  
  8.     shannonEnt = 0.0
  9.     for key in labelCounts:
  10.         prob = float(labelCounts[key])/numEntries
  11.         shannonEnt -= prob * math.log(prob,2)
  12.     return shannonEnt 

2、按给定的特征划分数据集:

  1. def splitDataSet(dataSet, axis, value):  
  2.     retDataSet = []
  3.     for featVec in dataSet:
  4.         if featVec[axis] == value:
  5.             reducedFeatVec = featVec[:axis]
  6.             reducedFeatVec.extend(featVec[axis+1:])
  7.             retDataSet.append(reducedFeatVec)
  8.     return retDataSet

有点类似Excel中的筛选功能,如下图等价于  featVec[1] == 'prescript'  筛选后的矩阵列表


步骤1:选择包含某个字段的列进行筛选( if  featVec[axis] == value
步骤2:Excel自动得到第X列中包含‘value’的矩阵列表,但python需要进行切片和组合,如下:

  1. reducedFeatVec = featVec[:axis]
  2. reducedFeatVec.extend(featVec[axis+1:])
  3. retDataSet.append(reducedFeatVec)

tips:list.append 和 list.extend 的区别,两者都是在列表末尾添加元素:
>>> a = [1,2,3]
>>> b = [4,5,6]
>>> a.append(b)
>>> a
[1, 2, 3, [4, 5, 6]]
如果执行append方法,则列表得到第四个元素,而第四个元素也是一个列表
>>> a = [1,2,3]
>>> a.extend(b)
>>> a
[1, 2, 3, 4, 5, 6]
使用extend方法,则得到一个包含a和b所有元素的列表

3、选择最好的数据集划分方式:
要求1:数据必须是一种有列表元素组成的列表,而且所有的列表元素都要具有相同的数据长度;
要求2:数据的最后一列或者每个实例的最后一个元素是当前实例的类别标签。

  1. def chooseBestFeatureToSplit(dataSet):  
  2.     numFeatures = len(dataSet[0]) - 1
  3.     baseEntropy = calcShannonEnt(dataSet)
  4.     bestInfoGain = 0.0; bestFeature = -1
  5.     #创建唯一的分类标签列表
  6.     for i in range(numFeatures):
  7.         featList = [example[i] for example in dataSet]
  8.         uniqueVals = set(featList)
  9.         newEntropy = 0.0
  10.         #计算每种划分方式的信息熵
  11.         for value in uniqueVals:  
  12.             subDataSet = splitDataSet(dataSet, i, value)  
  13.             prob = len(subDataSet)/float(len(dataSet))  
  14.             newEntropy += prob * calcShannonEnt(subDataSet)       
  15.         infoGain = baseEntropy - newEntropy  
  16.         #计算最好的信息增益
  17.         if (infoGain > bestInfoGain):         
  18.             bestInfoGain = infoGain           
  19.             bestFeature = i  
  20.     return bestFeature  

4、创建树:

     生成直方图,选出出现次数最多的类别,代码如下:
  1. def majorityCnt(classList):  
  2.     classCount={}  
  3.     for vote in classList:  
  4.         if vote not in classCount.keys(): classCount[vote] = 0  
  5.         classCount[vote] += 1  
  6.     sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)  
  7.     return sortedClassCount[0][0]  

      用递归的方式创建树,代码如下:
  1. def createTree(dataSet,labels):  
  2.     classList = [example[-1for example in dataSet]  
  3.     if classList.count(classList[0]) == len(classList):   
  4.         return classList[0#类别完全相同则停止继续划分
  5.     if len(dataSet[0]) == 1#遍历完所有特征时返回出现次数最多的
  6.         return majorityCnt(classList)  
  7.     bestFeat = chooseBestFeatureToSplit(dataSet)
  8.     bestFeatLabel = labels[bestFeat]
  9.     myTree = {bestFeatLabel:{}}
  10.     del(labels[bestFeat])
  11.     featValues = [example[bestFeat] for example in dataSet]
  12.     uniqueVals = set(featValues)
  13.     for value in uniqueVals:
  14.         subLabels = labels[:]  #得到列表包含的所有属性值
  15.         myTree[bestFeatLabel][value] = createTree(splitDataSet(dataSet, bestFeat, value),subLabels)
  16.     return myTree

4、决策树存储:
      递归算法运行太慢,所以需要把生成的决策树进行保存,存储&读取代码如下:
  1. def storeTree(inputTree,filename):  
  2.     import pickle  
  3.     fw = open(filename,'w')  
  4.     pickle.dump(inputTree,fw)  
  5.     fw.close()  
  6.       
  7. def grabTree(filename):  
  8.     import pickle  
  9.     fr = open(filename)  
  10.     return pickle.load(fr) 
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值