决策树及其python实现
剪枝
由于悲观错误剪枝 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实现的更多相关文章
- scikit-learn决策树的python实现以及作图
decsion tree(决策树) 其中每个内部结点表示在一个属性上的测试,每个分支代表一个属性的输出,而每个树叶结点代表类或类的分布.树的最顶层是根节点 连续变量要离散化 机器学习中分类方法的一个重 ...
- 100天搞定机器学习|Day23-25 决策树及Python实现
算法部分不再细讲,之前发过很多: [算法系列]决策树 决策树(Decision Tree)ID3算法 决策树(Decision Tree)C4.5算法 决策树(Decision Tree)CART算法 ...
- 决策树的python实现
决策树 算法优缺点: 优点:计算复杂度不高,输出结果易于理解,对中间值缺失不敏感,可以处理不相关的特征数据 缺点:可能会产生过度匹配的问题 适用数据类型:数值型和标称型 算法思想: 1.决策树构造的整 ...
- 3.1决策树理论--python深度机器学习
参考彭亮老师的视频教程:转载请注明出处及彭亮老师原创 视频教程: http://pan.baidu.com/s/1kVNe5EJ 0. 机器学习中分类和预测算法的评估: 准确率 速度 强壮行 ...
- 【机器学习笔记之二】决策树的python实现
本文结构: 是什么? 有什么算法? 数学原理? 编码实现算法? 1. 是什么? 简单地理解,就是根据一些 feature 进行分类,每个节点提一个问题,通过判断,将数据分为几类,再继续提问.这些问题是 ...
- python实现决策树
1.决策树的简介 http://www.cnblogs.com/lufangtao/archive/2013/05/30/3103588.html 2.决策是实现的伪代码 “读入训练数据” “找出每个 ...
- 决策树ID3算法--python实现
参考: 统计学习方法>第五章决策树] http://pan.baidu.com/s/1hrTscza 决策树的python实现 有完整程序 决策树(ID3.C4.5.CART ...
- Python 和 R 数据分析/挖掘工具互查
如果大家已经熟悉python和R的模块/包载入方式,那下面的表查找起来相对方便.python在下表中以模块.的方式引用,部分模块并非原生模块,请使用 pip install * 安装:同理,为了方便索 ...
- Python 数据挖掘 工具包整理
连接器与io 数据库 类别 Python R MySQL mysql-connector-python(官方) RMySQL Oracle cx_Oracle ROracle MongoDB pymo ...
随机推荐
- Logback 简单使用
1.Logback为取代log4j而生 Logback是由log4j创始人Ceki Gülcü设计的又一个开源日志组件.logback当前分成三个模块:logback-core,logback- cl ...
- Oracle分析函数之LEAD和LAG
LAG 访问结果集中当前行之前的行 LAG (value_expr [,offset] [,default])OVER ( [ partition_by_clause ] order_by_claus ...
- 【Scala 】Akka库
简介编辑 Akka 是一个用 Scala 编写的库,用于简化编写容错的.高可伸缩性的 Java 和 Scala 的 Actor 模型应用.它已经成功运用在电信行业.系统几乎不会宕机(高可用性 99.9 ...
- 常用后台frame框架
一般后台框架结构: top:左边显示logo,右边显示模块信息. left:对应模块的菜单信息. content:具体的内容. bottom:版权.时间等一些碎屑信息. Html代码: <htm ...
- MVC5添加控制器总是报“Multiple object sets per type are not supported”
http://www.asp.net/mvc/tutorials/mvc-5/introduction/creating-a-connection-string 按照上面的指导做练习, 总报小面的错 ...
- Nhibernate配置和访问数据问题
今天开始用Nhibernate做为自己的ORM,但是做的过程中确实遇到了好多问题,现在将问题收集起来以防日后出现相同的问题, 总结下: 这就是我的整个项目,现在配置下hibernate.cfg.xml ...
- C#正则表达式之字符替换
string strTest= "www.BaiDu.com",strRst=""; //忽略大小写,将strTest中的BaiDu替换为baidu Regex ...
- linux awk命令详解(转)
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html 简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编 ...
- jmeter linux使用经验小结
1. 确认务必安装了JDK,并且把路径配置OK.否则执行会报错. 2. 当做负载机时,在hosts 配置上 你的ip 你的hostname 或者使用./bin/jmeter-server ...
- mjpg-streamer on raspberrypi
http://sourceforge.net/projects/mjpg-streamer/ svn address svn checkout svn://svn.code.sf.net/p/mjpg ...