机器学习实战之树回归
来源:互联网 发布:动态寄生虫 猫云seo 编辑:程序博客网 时间:2024/05/22 17:51
1. 两种树构建算法比较
ID3:
每次选取当前最优的特征来分割数据,并按照该特征所有可能取值来切分;一旦按某特征切分后,该特征在之后的算法执行过程中不会再起作用.
缺点: 不能处理连续型特征,除非事先将连续型特征转换成离散型,但转换过程破坏了连续型变量的内在性质.
CART;
二元切分法,每次把数据切成两份;若特征值大于给定值,就走左子树,反之,右子树.
2. 树构建
2.1 树存储
采用字典来存储树的数据结构,该字典包含以下4个元素:待切分的特征;待切分的特征值;右子树(当不再需要继续切分时,是单个值);左子树。
2.2 创建树
流程如下:找到最佳的待切分特征:
如果该节点不能再分,将该节点存为叶节点
执行二元切分
在左、右子树分别调用创建树的函数
<span style="font-size:18px;">#负责产生叶节点def regLeaf(dataset):return mean(dataset[:,-1])#误差估计函数.计算目标变量的平均误差 总方差=均方差*样本数def regErr(dataset):return var(dataset[:,-1])*shape(dataset)[0]#def createTree(dataset,leaftype=regLeaf,errType=regErr,ops=(1,4)):feat,val = chooseBestSplit(dataset,leaftype,errType,ops)if feat == None:return valretTree = {}retTree['spInd'] = featretTree['spVal'] = vallset,rset = binarySplitData(dataset,feat,val)retTree['left'] = createTree(lset,leaftype,errType,ops)retTree['right'] = createTree(rset,leaftype,errType,ops)return retTree</span>
2.3 创建回归树
(1)回归树:其叶节点是常数值
(2)选择最佳特征的依据:计算数据的混乱度:计算所有数据的平均值,然后计算每条数据到均值的差值的平方,这里需要的是总方差,即均方差乘以数据个数。
(3)如何寻找当前最佳切分特征和特征值:函数choosebest。其思想是:遍历所有的特征及其可能的取值来找到误差最小化的切分阈值。
在此函数中,有三种情况不会切分数据集:
- 如果数据集的值全部相等
- 若找到最优划分之后,但是划分后的数据集的误差相比划分前的数据集的误差减少不大时,即效果提升不明显时,不执行划分操作
- 若找到的最优划分切分得到的数据集很小时,不执行划分
(4)其伪代码如下:
对每个特征:
对当前特征可能的每个取值:
将数据分成两部分
计算切分误差
若当前误差小于当前最小误差,更新当前最小误差,及其最佳切分方式
返回最佳切分特征和特征值
实现代码如下:
<span style="font-size:18px;">#找到数据的最佳二元划分方式def chooseBestSplit(dataset,leaftype=regLeaf,errtype=regErr,ops=(1,4)):tols = ops[0]#容许的误差下降值toln = ops[1] #切分的最小样本数if len(set(dataset[:,-1].T.tolist()[0])) == 1:return None,leaftype(dataset)m,n = shape(dataset)S = errtype(dataset)bestS = inf;bestindex = 0;bestvalue = 0#寻找最好的切分方式,最佳切分就是使得切分后能够达到最低误差的切分for featindex in range(n-1):for splitVal in set(dataset[:,featindex]):mat0,mat1 = binarySplitData(dataset,featindex,splitVal)if (shape(mat0)[0] < toln) or (shape(mat1)[0] < toln):continuenewS = errtype(mat0) + errtype(mat1)if newS < bestS:bestS = newSbestindex = featindexbestvalue = splitVal#切分数据集后,效果提升不大,则不应进行切分操作而直接创建叶节点if (S- bestS) < tols:return None,leaftype(dataset)mat0,mat1 = binarySplitData(dataset,bestindex,bestvalue)if (shape(mat0)[0] < toln) or (shape(mat1)[0] < toln):return None,leaftype(dataset)return bestindex,bestvalue</span>
2.4 创建模型树
(1)模型树: 其叶节点是分段线性函数;分段线性指的是模型由多个线性片段组成
(2)如何找到最佳切分?对于给定的数据集,先用线性模型对它进行拟合,然后计算真实的目标值与模型预测值间的差值,最后将这些差值的平方求和作为所需的误差值。
其计算过程如下所示:
<span style="font-size:18px;">def linearSolve(dataSet): #helper function used in two places m,n = shape(dataSet) X = mat(ones((m,n))); Y = mat(ones((m,1)))#create a copy of data with 1 in 0th postion X[:,1:n] = dataSet[:,0:n-1]; Y = dataSet[:,-1]#and strip out Y xTx = X.T*X if linalg.det(xTx) == 0.0: raise NameError('This matrix is singular, cannot do inverse,\n\ try increasing the second value of ops') ws = xTx.I * (X.T * Y) return ws,X,Ydef modelLeaf(dataSet):#create linear model and return coeficients ws,X,Y = linearSolve(dataSet) return wsdef modelErr(dataSet): ws,X,Y = linearSolve(dataSet) yHat = X * ws return sum(power(Y - yHat,2))</span>
3. 树剪枝(tree pruning)
(1)基本概念
过拟合:一棵树节点过多,且使用测试集验证过的。
剪枝:通过降低决策树的复杂度来避免过拟合的过程。
- 预剪枝(prepruning):即函数chooseBestSplit()中的不切分的那三个条件
- 后剪枝(postpruning):需要使用测试集和训练集
过程:首先指定参数,使得构建得到的树足够大,足够复杂,便于剪枝。然后从上向下找到叶节点,用测试集来判断将这些叶节点合并是否能够降低测试误差,若是的话就合并。
其伪代码如下:
基于已有的树切分测试数据:
如果存在任一子集是一棵树,则在该子集中地柜剪枝过程
计算将当前两个叶节点合并后的误差
计算不合并的误差
如果合并会降低误差的话,就将叶节点合并
其实现代码如下:
<span style="font-size:18px;"> 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#input:待剪枝的树与剪枝所需的测试数据def prune(tree,testdata):if shape(testdata)[0] == 0:return getMean(tree)if (isTree(tree['right']) or isTree(tree['left'])):lset,rset = binarySplitData(testdata,tree['spInd'],tree['spVal'])if isTree(tree['left']) :tree['left'] = prune(tree['left'],lset)if isTree(tree['right']) :tree['right'] = prune(tree['right'],rset)if not isTree(tree['left']) and not isTree(tree['right']):lset,rset = binarySplitData(testdata,tree['spInd'],tree['spVal'])errorNmerge = sum(power(lset[:,-1]-tree['left'],2)) +\sum(power(rset[:,-1]-tree['right'],2))treeMean = (tree['left'] + tree['right'])/2.0errormerge = sum(power(testdata[:,-1]-treeMean,2))if errormerge < errorNmerge:print "merging"return treeMeanelse:return treeelse:return tree</span>
4. 模型评价
如何评价回归树、模型树、线性回归等模型的好坏呢?
比较客观的方法是计算相关系数。numpy.corrcoef()函数实现
5. 使用回归树和模型树进行预测
其实现代码如下:
<span style="font-size:18px;">def regTreeEval(model, inDat): return float(model)def modelTreeEval(model, inDat): n = shape(inDat)[1] X = mat(ones((1,n+1))) X[:,1:n+1]=inDat return float(X*model)def treeForeCast(tree, inData, modelEval=regTreeEval): if not isTree(tree): return modelEval(tree, inData) if inData[tree['spInd']] > tree['spVal']: if isTree(tree['left']): return treeForeCast(tree['left'], inData, modelEval) else: return modelEval(tree['left'], inData) else: if isTree(tree['right']): return treeForeCast(tree['right'], inData, modelEval) else: return modelEval(tree['right'], inData) def createForeCast(tree, testData, modelEval=regTreeEval): m=len(testData) yHat = mat(zeros((m,1))) for i in range(m): yHat[i,0] = treeForeCast(tree, mat(testData[i]), modelEval) return yHat</span>
- 机器学习实战之树回归
- 机器学习实战之回归
- 机器学习实战之回归
- 机器学习实战-树回归
- 机器学习实战 树回归
- 《机器学习实战》笔记之九——树回归
- 第9章 机器学习实战之树回归
- 机器学习实战之logistic回归
- 5.机器学习实战之Logistic回归
- Python机器学习实战之逻辑回归
- 机器学习实战之Logistic回归
- 机器学习实战 回归
- 机器学习实战之线性回归+局部加权线性回归
- 机器学习实战——树回归
- 机器学习实战-CART分类回归树
- 【机器学习实战-python3】树回归
- 机器学习实战_09树回归
- 【机器学习实战-python3】树回归
- svn资源同步问题
- 伟哥教您Windows下手动搭建Laravel5.2开发环境Nginx+Php+MySQL
- Files 的值“ < < < < < < < .mine”无效。路径中具有非法字符。
- c++中的string常用函数用法总结
- Nginx的upstream目前支持5种方式的分配
- 机器学习实战之树回归
- Jtellij for mac 方法调用树
- 专题二1019
- 【iOS】快速集成轮播控件
- android studio 2.0 下创建JNI应用
- 计算机基础知识温故而知新
- 为什么静态成员、静态方法中不能用this和super关键字
- Eclipse去除js(JavaScript)验证错误
- 【笔试/面试】—— 判断一个链表是否有环