树模型之回归树,模型树,树剪枝
来源:互联网 发布:全国软件设计师考试 编辑:程序博客网 时间:2024/05/20 21:24
在前面决策树的介绍中,我们使用ID3算法来构建决策树;这里我们使用CART算法来构建回归树和模型树。ID3算法是每次选取当前最佳的特征来分割数据,并按照该特征的所有可能取值来区分。比如,如果一个特征有4种取值,那么数据将被切分成4份。很明显,该算法不适用于标签值为连续型的数据。
CART算法使用二元切分法来处理连续型变量,即每次把数据集切分成左右两份。
回归树
回归树使用CART算法来构建树,使用二元切分法来分割数据,其叶节点包含单个值。创建回归树的函数createTree()的伪代码大致如下:
找到最佳的待切分特征:
如果该节点不能再分,将该节点存为叶节点
执行二元切分
在左子树调用createTree()方法
在右子树调用createTree()方法
创建回归树的过程与决策树类似,只是切分方法不同。同时,在计算数据的无序程度时,决策树是使用香农熵的方法,而我们的标签值是连续值,不能用该方法。那么,怎么计算连续型数值的混乱度呢?首先,计算所有数据的均值,然后计算每条数据的值到均值的差值,再求平方和,即我们用总方差的方法来度量连续型数值的混乱度。在回归树中,叶节点包含单个值,所以总方差可以通过均方差乘以数据集中样本点的个数来得到。
下面,将计算连续型数值混乱度的代码提供如下:
#计算分割代价def spilt_loss(left,right): #总方差越小,说明数据混乱度越小 loss=0.0 left_size=len(left) #print 'left_size:',left_size left_label=[row[-1] for row in left] right_size=len(right) right_label=[row[-1] for row in right] loss += var(left_label)*left_size + var(right_label)*right_size return loss
得到叶节点预测值的代码:
#决定输出标签(取出叶节点数据的标签值,计算平均值)def decide_label(data): output=[row[-1] for row in data] return mean(output)
模型树
模型树与回归树的差别在于:回归树的叶节点是节点数据标签值的平均值,而模型树的节点数据是一个线性模型(可用最简单的最小二乘法来构建线性模型),返回线性模型的系数W,我们只要将测试数据X乘以W便可以得到预测值Y,即Y=X*W。所以该模型是由多个线性片段组成的。
同样,给出叶节点预测值及计算待分割数据集混乱度的代码:
#生成叶节点def decide_label(dataSet): ws,X,Y = linearModel(dataSet) return ws#计算模型误差def spilt_loss(dataSet): ws,X,Y = linearModel(dataSet) yat = X * ws return sum(power(yat-Y,2)) #模型预测数据def modelTreeForecast(ws,dataRow): data = mat(dataRow) n = shape(data)[1] X = mat(ones((1,n))) X[:,1:n] = data[:,0:n-1] return X*ws
那么,如何比较回归树与模型树那种模型更好呢?一个比较客观的方法是计算预测值与实际值相关系数。该相关系数可以通过调用NumPy库中的命令corrcoef(yHat,y.rowvar=0)来求解,其中yHat是预测值,y是目标变量的实际值。
剪枝
通过降低树的复杂度来避免过拟合的过程称为剪枝。对树的剪枝分为预剪枝和后剪枝。一般地,为了寻求最佳模型可以同时使用这两种剪枝技术。
预剪枝:在选择创建树的过程中,我们限制树的迭代次数(即限制树的深度),以及限制叶节点的样本数不要过小,设定这种提前终止条件的方法实际上就是所谓的预剪枝。周志华的西瓜书中有对预剪枝的方法做具体描述,感兴趣的同学可以了解一下。因为我只是通过提前终止条件的方法来实现预剪枝,这种方法比较简单,不做具体描述。
后剪枝:使用后剪枝方法需要将数据集分为测试集和训练集。用测试集来判断将这些叶节点合并是否能降低测试误差,如果是的话将合并。
直接上代码:
'''后剪枝过程'''#判断是否为字典def isTree(obj): return (type(obj).__name__=='dict')def getMean(tree): #将叶节点的训练数据的标签值的平均值作为该节点的预测值 if isTree(tree['right']): tree['right'] = getMean(tree['right']) if isTree(tree['left']): tree['left'] = getMean(tree['left']) return (tree['left']+tree['right'])/2.0 #执行后剪枝(具体来说,就是将测试集按照之前生成的树一步步分类到叶节点,计算相应的标签值与叶节点预测值的总方差,如果剪枝后方差变小,则执行剪枝)def prune(testData,tree): if len(testData)==0: return getMean(tree) if (isTree(tree['left']) or isTree(tree['right'])): #判断tree['left']和tree['right']是否为字典,如果为字典则进行数据划分 lSet,rSet = data_spilt(testData,tree['index'],tree['value']) #划分数据集 if isTree(tree['left']): #如果tree['left']是字典,则执行prune()函数进行递归,直到tree['left']是叶节点时结束递归,往下继续执行函数 tree['left'] = prune(lSet,tree['left']) if isTree(tree['right']): #在tree['left']执行递归的基础上继续递归,这样可以取到所有左右两边的叶节点的值 tree['right'] = prune(lSet,tree['right']) if not isTree(tree['left']) and not isTree(tree['right']): #如果tree['left']和tree['right']都不是字典,执行下面操作 lSet,rSet = data_spilt(testData,tree['index'],tree['value']) #分割数据集 left_value = [row[-1] for row in lSet] #取出左数据集的节点值 right_value = [row[-1] for row in rSet] #取出右数据集的节点值 if tree['left'] is None or tree['right'] is None: #如果出现tree['left']或tree['right']为None时,返回树,不执行剪枝操作 return tree else: errorNoMerge = sum(power(left_value-tree['left'],2)) + sum(power(right_value-tree['right'],2)) #计算没剪枝时测试集的标签值与叶节点的预测值的总方差 treeMean = (tree['left'] + tree['right'])/2.0 testSet_value = [row[-1] for row in testData] errorMerge = sum(power(testSet_value-treeMean,2)) #计算剪枝后测试集的标签值与叶节点的预测值的总方差 if errorMerge < errorNoMerge: #如果剪枝后的方差小于剪枝前,则执行剪枝;否则返回,不剪枝。 print 'merging' return treeMean else: return tree else : return tree
以上,便是我在学习过程中对回归树,模型树,树剪枝的一些总结。
- 树模型之回归树,模型树,树剪枝
- CART回归树&模型树 生成 剪枝 in Python
- CART 分类回归树、模型树, 及REP后剪枝
- 数据挖掘回顾九:回归算法之 模型树
- 树模型和线性回归 在回归问题中的比较
- CART树回归、剪枝、Tkinter GUI
- 机器学习与R之回归树CART与模型树M5
- 机器学习十大算法之-CART分类决策树、回归树和模型树
- 专访滴滴算法大赛冠军团队:回归树模型取胜
- 模型树
- 树模型
- 树回归:CART算法构建回归树和模型树(代码笔记)
- 模型树------构建模型树
- 机器学习之回归模型
- 输入法之模型剪枝一(基于熵的剪枝)
- 广义加性模型和树模型
- 回归模型-逻辑回归
- 机器学习理论与实战(九)回归树和模型树
- 12313123
- 聪明的kk
- OKIO源码分析<Segment的设计智慧>
- Deep learning 资源、NLP词向量和语言模型
- structs1 和 structs2 的区别
- 树模型之回归树,模型树,树剪枝
- 【洛谷 1346】电车
- 算法导论 二叉搜索树
- oracle 数据库解锁
- 树的统计Count bzoj 1036 树链剖分+线段树
- 你应该掌握的七种回归技术
- 5-14 喊山(pair在队列的运用)
- (教程)配置PHP环境变量
- mysql mha+keepalived