Python 递归实现决策树算法

来源:互联网 发布:软件开发基础知识 编辑:程序博客网 时间:2024/06/09 05:48

决策树实现

上一篇博客记录了决策树构建的基本思想和构建的主要流程,这篇博客将介绍Python2.7下决策树算法的具体实现。

1.递归构建思路

  决策树构建的思路非常清晰,由函数treeGrow(dataset)的递归来实现决策树左右子树的构建,构建的顺序为1->2->3->4->5->6->7,与使用其他语言实现决策树算法没有差别。利用Python中的字典数据类型,通过key,value的赋值,多层嵌套字典,实现决策树的存储。
  决策树的构建有3个基本的结束条件:
(1)用于构建决策树的特征使用完毕
(2)叶子结点中的标签均为同一类别
(3)决策树构建完成

def treeGrow(dataset,features):    if  len(classList) == classList.count(classList[0]):  #no more feature        return classifyMaxLabel(classList)    if  len(dataSet[0]) == 1:  # pure dataset        return classList[0]    bestFeature = findBestSplit(dataset)    del bestFeature    left_data,right_data = SplitDataset(dataset, bestFeature)    tree['bestFeature-'] = treeGrow(left_data,features)    tree['bestFeature+'] = treeGrow(right_data,features)    return tree  # finish tree

决策树构建详细过程

2.具体实现

  决策树构建主要以TreeGrow函数为主体,构建以下几个函数来实现决策树构建。比较重要的函数为findBestSplit(dataSet)函数包含数据集信息熵、信息增益的计算,计算方法和原理在上一篇博客里有详细介绍,代码实现起来并不难。

函数名 功能 createDataSet(data) 创建数据集 splitDataSet(data,feature,value) 划分用来训练左右子树的数据集 findBestSplit(dataSet) 根据信息增益找到最合适的属性进行结点划分 calcShannonEnt(dataset) 按照属性分类计算数据的信息熵 classfy(classList) 找出类别列表中出现次数最多的类别 predict(tree,newObject) 实现决策树的预测功能

3.遇到的问题

  在运行时遇到了问题:决策树所有的右子树均为空
   
  原因分析:在PyCharm里调试程序,发现构建失败原因是构建右子树时,属性集feature_list为空。用于结点划分的属性存储在属性集feature_list中,在构建左右子树时均会使用属性集中的属性进行结点划分。决策树构建的递归算法与在C、C++其他语言实现是相同的,但C、C++中list为值类型,而Python中列表list为引用类型,在函数递归构建左子树的过程中使用过的属性会从feature_list中删除,feature_list的值会发生改变。因此,在构建右子树时,属性feature_list 为空,决策树所有的右子树没能完成构建。
  
  解决方法:通过copy模块的deepcopy函数对feature_list列表进行硬拷贝,拷贝在函数的当前层,在递归构建树的时候采用硬拷贝的属性集构建右子树。

right_features = copy.deepcopy(features)  # deepcopy the feature listleft_data,right_data = SplitDataset(dataset, bestFeature)tree['bestFeature-'] = treeGrow(left_data,features)tree['bestFeature+'] = treeGrow(right_data,right_features)

  小结: 关于列表是引用类型的问题,在之前的博客里也有提到过:Python多维数组初始化的两种方式和浅拷贝问题,但是具体运用时,还是经常会忽略这些细节。Python里的引用类型主要就是列表。元组不能改变其中的元素,只能整个元组一起删除或者和其他元组组合在一起。字典数据结构的value值要求是不能改变的数据类型,如整数、字符串。
  
  这个bug找了很久才找到原因,吃一堑长一智,以后对编程语言里的引用类型的操作要多加注意,避免出现类似的错误。

原创粉丝点击