剪枝

由于悲观错误剪枝 PEP (Pessimistic Error Pruning)、代价-复杂度剪枝 CCP (Cost-Complexity Pruning)、基于错误剪枝 EBP (Error-Based Pruning)、最小错误剪枝 MEP (Minimum Error Pruning)都是用于分类模型,故我们用降低错误剪枝 REP ( Reduced Error Pruning)方法进行剪枝。它的基本思路是:对于决策树 T 的每棵非叶子树s, 用叶子替代这棵子树.如果s 被叶子替代后形成的新树关于D 的误差等于或小于s关于D 所产生的误差, 则用叶子替代子树s。降低错误剪枝 REP优点是计算复杂性低、对未知示例预测偏差较小、自底向上处理。

剪枝的具体代码如下:

myDat2=loadDataSet('ex2.txt')

myMat2=mat(myDat2)

myTree=createTree(myMat2, ops=(0,1))

myDatTest=loadDataSet('ex2test.txt')

myMat2Test=mat(myDatTest)

pruneTree=prune(myTree, myMat2Test)

#print "prune tree",pruneTree

yModelHat = createForeCast(pruneTree, myMat2[:,0])

print "model tree",corrcoef(yModelHat, myMat2[:,1],rowvar=0)[0,1]

其中prune函数如下:

def prune(tree, testData):

if shape(testData)[0] == 0: return getMean(tree) #if we have no test data collapse the tree

if (isTree(tree['right']) or isTree(tree['left'])):#if the branches are not trees try to prune them

lSet, rSet = binSplitDataSet(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 they are now both leafs, see if we can merge them

if not isTree(tree['left']) and not isTree(tree['right']):

lSet, rSet = binSplitDataSet(testData, tree['spInd'], tree['spVal'])

errorNoMerge = sum(power(lSet[:,-1] - tree['left'],2)) +\

sum(power(rSet[:,-1] - tree['right'],2))

treeMean = (tree['left']+tree['right'])/2.0

errorMerge = sum(power(testData[:,-1] - treeMean,2))

if errorMerge < errorNoMerge:

print "merging"

return treeMean

else: return tree

else: return tree

剪枝后可以看到相关系数为99.17%。

2、回归树、模型树和普通回归树比较

以下分别是回归树模型树和普通回归树调用实现:

trainMat=mat(loadDataSet('bikeSpeedVsIq_train.txt'))

testMat=mat(loadDataSet('bikeSpeedVsIq_test.txt'))

myRegTree=createTree(trainMat, ops=(1,20))

yRegHat = createForeCast(myRegTree, testMat[:,0])

print "regression tree",corrcoef(yRegHat, testMat[:,1],rowvar=0)[0,1]

myModelTree=createTree(trainMat, modelLeaf,modelErr,(1,20))

yModelHat = createForeCast(myModelTree, testMat[:,0],modelTreeEval)

print "model tree",corrcoef(yModelHat, testMat[:,1],rowvar=0)[0,1]

ws,X,Y=linearSolve(trainMat)

for i in range(shape(testMat)[0]):

yModelHat[i]=testMat[i,0]*ws[1,0]+ws[0,0]

print "stardand",corrcoef(yModelHat, testMat[:,1],rowvar=0)[0,1]

三者比较结果如下:

可以看到模型树的精确度最高,简单的线性回归效果最差。

3、Incremental Learning of Linear Model Trees

Duncan Potts 04年提出了基于线性模型树的增量学习算法,用于处理连续的流式输入数据模型而不必像以往批处理算法一样每次都需要运算整个训练集。作者说这种算法较以往的增量算法运用更少的样本可以得到对未知函数更好的近似,并且这种算法需要的参数更少。

3.1 模型树

由最小二乘法RLS可以得到:

RSS就是最小的J值(有且仅当)。

Python实现如下:

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,Y

def modelLeaf(dataSet):#create linear model and return coeficients

ws,X,Y = linearSolve(dataSet)

return ws

def modelErr(dataSet):

ws,X,Y = linearSolve(dataSet)

yHat = X * ws

return sum(power(Y - yHat,2))

3.2、增量模型树算法

作者在考虑一个有可能的分裂节点分成两个线性模型是否比用一个线性模型对函数的估计更好可以当成一个检验假设。假设H0 : ,如果假设成立则使用单个线性模型,其误差可以通过RLS计算得到RSS0,假设不成立分裂即使用两个线性模型,即 。它们对应的样本量分别为N1和N2。其误差分别为RSS1和RSS2,一般情况下,一个数据集使用两个子模型来近似总会比使用单个模型来近似要好很多,所以RSS1+RSS2<RSS0.在这个假设之下,可以用一个F分布函数来表示一个数据集来自单个线性模型的可能性,表示如下:

其值越大,表明此数据集来自单个线性模型的可能性越大。同时由于数据集是流动的,所以在每一个节点的不同特征下需要考虑的分裂值也是动态变化的。所以在每个节点需要维护k(d-1)个潜在的分裂值,其中d表示特征数, k表示每个特征下需要考虑的分裂值。对于模型树的规模必须要加以限制:

随着模型树的规模越大,δ值会越小,所以需要给值提供一个下限。对于F分布的p-value python里面scipy库有stats:

pvalue=stats.f.sf(F,N-2*d,d),其中d,N-2d是自由度。其余代码如下。

3.3、Python实现具体如下:

def train(dataSet,tolN,delta0,split):#assume dataSet is NumPy Mat so we can array filtering

if len(set(dataSet[:,-1].T.tolist()[0])) == 1: #exit cond 1

return None, modelLeaf(dataSet)

#feat, val = chooseBestSplit(dataSet, leafType, errType, ops)#choose the best split

N,d = shape(dataSet)

#the choice of the best feature is driven by Reduction in RSS error from mean

RSS0 = modelErr(dataSet)

bestS = inf; bestIndex = 0; bestValue = 0;minp=inf;minRSS1=0;minRSS2=0;

print '1ok'

for featIndex in range(d-1):

for splitVal in set(dataSet[:,featIndex]):

mat0, mat1 = binSplitDataSet(dataSet, featIndex, splitVal)

if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN): continue

RSS1 = modelErr(mat0)

RSS2 = modelErr(mat1)

print '2ok'

F=(RSS0-RSS1-RSS2)*(N-2*d)/((RSS1+RSS2)*d)

pvalue=stats.f.sf(F,N-2*d,d)

if pvalue<minp:

N1,d1=shape(mat0)

N2,d2=shape(mat1)

minp=pvalue

minRSS1=RSS1

minRSS2=RSS2

bestIndex = featIndex

bestValue = splitVal

if minRSS2==0:

return None,modelLeaf(dataSet)

delta=RSS0/(N-d)-(minRSS1+minRSS2)/(N1+N2-2*d)

print minp,delta

if minp > split or delta < delta0:

return None,modelLeaf(dataSet)

lSet, rSet = binSplitDataSet(dataSet, bestIndex, bestValue)

if (shape(lSet)[0] < tolN) or (shape(rSet)[0] < tolN):  #exit cond 3

return None,modelLeaf(dataSet)

return bestIndex,bestValue

def createTrain(dataSet,tolN,delta0,split):#assume dataSet is NumPy Mat so we can array filtering

feat, val = train(dataSet,tolN,delta0,split)#choose the best split

if feat == None: return val #if the splitting hit a stop condition return val

retTree = {}

retTree['spInd'] = feat

retTree['spVal'] = val

lSet, rSet = binSplitDataSet(dataSet, feat, val)

retTree['left'] = createTrain(lSet,tolN,delta0,split)

retTree['right'] = createTrain(rSet,tolN,delta0,split)

return retTree

3.4、实验过程

我用类sin训练集做测试,为了方便做了以下界面:

可以看到当asplit过小或者δ0过大时都容易发生欠拟合:

相反,当asplit过大或者δ0过小时都容易发生过拟合:

决策树及其python实现的更多相关文章

  1. scikit-learn决策树的python实现以及作图

    decsion tree(决策树) 其中每个内部结点表示在一个属性上的测试,每个分支代表一个属性的输出,而每个树叶结点代表类或类的分布.树的最顶层是根节点 连续变量要离散化 机器学习中分类方法的一个重 ...

  2. 100天搞定机器学习|Day23-25 决策树及Python实现

    算法部分不再细讲,之前发过很多: [算法系列]决策树 决策树(Decision Tree)ID3算法 决策树(Decision Tree)C4.5算法 决策树(Decision Tree)CART算法 ...

  3. 决策树的python实现

    决策树 算法优缺点: 优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关的特征数据 缺点:可能会产生过度匹配的问题 适用数据类型:数值型和标称型 算法思想: 1.决策树构造的整 ...

  4. 3.1决策树理论--python深度机器学习

    参考彭亮老师的视频教程:转载请注明出处及彭亮老师原创 视频教程: http://pan.baidu.com/s/1kVNe5EJ   0. 机器学习中分类和预测算法的评估:   准确率 速度 强壮行 ...

  5. 【机器学习笔记之二】决策树的python实现

    本文结构: 是什么? 有什么算法? 数学原理? 编码实现算法? 1. 是什么? 简单地理解,就是根据一些 feature 进行分类,每个节点提一个问题,通过判断,将数据分为几类,再继续提问.这些问题是 ...

  6. python实现决策树

    1.决策树的简介 http://www.cnblogs.com/lufangtao/archive/2013/05/30/3103588.html 2.决策是实现的伪代码 “读入训练数据” “找出每个 ...

  7. 决策树ID3算法--python实现

    参考: 统计学习方法>第五章决策树]   http://pan.baidu.com/s/1hrTscza 决策树的python实现     有完整程序     决策树(ID3.C4.5.CART ...

  8. Python 和 R 数据分析/挖掘工具互查

    如果大家已经熟悉python和R的模块/包载入方式,那下面的表查找起来相对方便.python在下表中以模块.的方式引用,部分模块并非原生模块,请使用 pip install * 安装:同理,为了方便索 ...

  9. Python 数据挖掘 工具包整理

    连接器与io 数据库 类别 Python R MySQL mysql-connector-python(官方) RMySQL Oracle cx_Oracle ROracle MongoDB pymo ...

随机推荐

  1. WPF读书笔记(第一天)

    今天开始学习WPF,大家都推荐<深入浅出WPF>这本书,一下是我觉得此书中重要的地方,记录下来以便以后回顾,也希望其他人看到了对你们有帮助. 1.XAML是可扩展应用程序标记语言 是WPF ...

  2. linux exec函数家族

    1.exec家族一共有六个函数,分别是: (1)int execl(const char *path, const char *arg, ......); (2)int execle(const ch ...

  3. android正在运行进程和后台缓存进程的区别

    正在运行的进程:需要占用一定的cpu资源和RAM(内存)空间,多少的话看是什么应用,要消耗一定的电量,影响手机速度等性能. 后台缓存的进程:不需要占用cpu资源,会在RAM中写入一部分数据,当下次打开 ...

  4. JLOI 2013 卡牌游戏

    问题描述: N个人坐成一圈玩游戏.一开始我们把所有玩家按顺时针从1到N编号.首先第一回合是玩家1作为庄家.每个回合庄家都会随机(即按相等的概率)从卡牌堆里选择一张卡片,假设卡片上的数字为X,则庄家首先 ...

  5. WPF 显示模态窗口和窗体

    <WPF编程宝典——使用C# 2008和.NET 3.5(第2版)>第25章与Windows窗体的互操作,本章将介绍用于集成Windows窗体和WPF内容的不同策略.还将分析如何在应用程序 ...

  6. swift版本hello

    import UIKit class ViewController: UIViewController { @IBOutlet var button : UIButton? //var alertVi ...

  7. 转:Java Annotation详解

    转载自:http://william750214.javaeye.com/blog/298104 元数据的作用 如果要对于元数据的作用进行分类,目前还没有明确的定义,不过我们可以根据它所起的作用,大致 ...

  8. AMH4.2免费版手动编译升级Nginx1.8版本方法

    从AMH免费版本停留在4.2版本之后就没有进行更新和升级,而且官方提供的解决文档也比较少,毕竟免费且没有盈利的产品还是没有多少兴趣的.但是,对于大部分网站环境来说,安装和使用AMH4.2免费版本还是够 ...

  9. eclipse中mavean的使用配置

    eclipse-jee-neon-R-win32 maven-3.3.9 JDK  jdk-8u101-windows-i586 eclipse中配置mavean的步骤就不说了,网上很多教程,也很简单 ...

  10. 性能测试_响应时间、并发、RPS的关系

    写这篇文章是为了帮自己理清一下性能测试中最最基本,却总是被人忽略的一些概念. 并发: 什么叫并发?并发不是我们理解的在loadrunner场景中设置并发数,而是正在系统中执行操作或者在系统的队列中排队 ...