python机器学习实战之树回归详解


Posted in Python onDecember 20, 2017

本文实例为大家分享了树回归的具体代码,供大家参考,具体内容如下

#-*- coding:utf-8 -*- 
#!/usr/bin/python 
''''' 
回归树  连续值回归预测 的 回归树 
''' 
# 测试代码 
# import regTrees as RT RT.RtTreeTest() RT.RtTreeTest('ex0.txt') RT.RtTreeTest('ex2.txt') 
# import regTrees as RT RT.RtTreeTest('ex2.txt',ops=(10000,4)) 
# import regTrees as RT RT.pruneTest() 
# 模型树 测试 
# import regTrees as RT RT.modeTreeTest(ops=(1,10) 
# 模型回归树和普通回归树 效果比较 计算相关系数  
# import regTrees as RT RT.MRTvsSRT() 
from numpy import * 
 
 
# Tab 键值分隔的数据 提取成 列表数据集 成浮点型数据 
def loadDataSet(fileName):   #   
  dataMat = []        # 目标数据集 列表 
  fr = open(fileName) 
  for line in fr.readlines(): 
    curLine = line.strip().split('\t') 
    fltLine = map(float,curLine) #转换成浮点型数据 
    dataMat.append(fltLine) 
  return dataMat 
 
# 按特征值 的数据集二元切分  特征(列)  对应的值 
# 某一列的值大于value值的一行样本全部放在一个矩阵里,其余放在另一个矩阵里 
def binSplitDataSet(dataSet, feature, value): 
  mat0 = dataSet[nonzero(dataSet[:,feature] > value)[0],:][0] # 数组过滤 
  mat1 = dataSet[nonzero(dataSet[:,feature] <= value)[0],:][0] #  
  return mat0,mat1 
 
# 常量叶子节点 
def regLeaf(dataSet):# 最后一列为标签 为数的叶子节点 
  return mean(dataSet[:,-1])# 目标变量的均值 
# 方差 
def regErr(dataSet): 
  return var(dataSet[:,-1]) * shape(dataSet)[0]# 目标变量的平方误差 * 样本个数(行数)的得到总方差 
 
# 选择最优的 分裂属性和对应的大小 
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: # 特征剩余数量为1 则返回 
    return None, leafType(dataSet)       #### 返回 1 ####  
  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 = binSplitDataSet(dataSet, featIndex, splitVal)# 进行二元分割 
      if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN): continue #样本数量 小于设定值,则不切分 
      newS = errType(mat0) + errType(mat1)# 二元分割后的 均方差 
      if newS < bestS: # 弱比分裂前小 则保留这个分类 
        bestIndex = featIndex 
        bestValue = splitVal 
        bestS = newS 
  if (S - bestS) < tolS: # 弱分裂后 比 分裂前样本方差 减小的不多 也不进行切分 
    return None, leafType(dataSet)       #### 返回 2 ####  
  mat0, mat1 = binSplitDataSet(dataSet, bestIndex, bestValue) 
  if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN): #样本数量 小于设定值,则不切分 
    return None, leafType(dataSet)       #### 返回 3 ####  
  return bestIndex,bestValue # 返回最佳的 分裂属性 和 对应的值 
 
# 创建回归树 numpy数组数据集 叶子函数  误差函数  用户设置参数(最小样本数量 以及最小误差下降间隔) 
def createTree(dataSet, leafType=regLeaf, errType=regErr, ops=(1,4)): 
 # 找到最佳的待切分特征和对应 的值 
  feat, val = chooseBestSplit(dataSet, leafType, errType, ops)# 
 # 停止条件 该节点不能再分,该节点为叶子节点 
  if feat == None: return val  
  retTree = {} 
  retTree['spInd'] = feat #特征 
  retTree['spVal'] = val #值 
 # 执行二元切分  
  lSet, rSet = binSplitDataSet(dataSet, feat, val)# 二元切分 左树 右树 
 # 创建左树 
  retTree['left'] = createTree(lSet, leafType, errType, ops)  # 左树 最终返回子叶子节点 的属性值 
 # 创建右树 
  retTree['right'] = createTree(rSet, leafType, errType, ops) # 右树 
  return retTree  
 
# 未进行后剪枝的回归树测试  
def RtTreeTest(filename='ex00.txt',ops=(1,4)): 
  MyDat = loadDataSet(filename) # ex00.txt y = w*x 两维  ex0.txt y = w*x+b 三维 
  MyMat = mat(MyDat) 
  print createTree(MyMat,ops=ops) 
# 判断是不是树 (按字典形式存储) 
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(tree, testData): 
  if shape(testData)[0] == 0:  
  return getMean(tree) #没有测试数据 返回 
  if (isTree(tree['right']) or isTree(tree['left'])): # 如果回归树的左右两边是树 
    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 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 
   
def pruneTest(): 
  MyDat = loadDataSet('ex2.txt')  
  MyMat = mat(MyDat) 
  MyTree = createTree(MyMat,ops=(0,1))  # 为了得到 最大的树 误差设置为0 个数设置为1 即不进行预剪枝 
  MyDatTest = loadDataSet('ex2test.txt') 
  MyMatTest = mat(MyDatTest) 
  print prune(MyTree,MyMatTest) 
 
 
######叶子节点为线性模型的模型树######### 
# 线性模型 
def linearSolve(dataSet):   
  m,n = shape(dataSet) # 数据集大小 
  X = mat(ones((m,n))) # 自变量 
  Y = mat(ones((m,1))) # 目标变量  
  X[:,1:n] = dataSet[:,0:n-1]# 样本数据集合 
  Y = dataSet[:,-1]     # 标签 
  # 线性模型 求解 
  xTx = X.T*X         
  if linalg.det(xTx) == 0.0: 
    raise NameError('行列式值为零,不能计算逆矩阵,可适当增加ops的第二个值') 
  ws = xTx.I * (X.T * Y) 
  return ws,X,Y 
 
# 模型叶子节点 
def modelLeaf(dataSet):  
  ws,X,Y = linearSolve(dataSet) 
  return ws 
 
# 计算模型误差 
def modelErr(dataSet): 
  ws,X,Y = linearSolve(dataSet) 
  yHat = X * ws 
  return sum(power(Y - yHat,2)) 
 
# 模型树测试 
def modeTreeTest(filename='ex2.txt',ops=(1,4)): 
  MyDat = loadDataSet(filename) #  
  MyMat = mat(MyDat) 
  print createTree(MyMat,leafType=modelLeaf, errType=modelErr,ops=ops)#带入线性模型 和相应 的误差计算函数 
 
 
# 模型效果计较 
# 线性叶子节点 预测计算函数 直接返回 树叶子节点 值 
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 
 
# 常量回归树和线性模型回归树的预测结果比较 
def MRTvsSRT(): 
  TestMat = mat(loadDataSet('bikeSpeedVsIq_test.txt')) 
  TrainMat = mat(loadDataSet('bikeSpeedVsIq_train.txt')) 
# 普通回归树 预测结果 
  # 得到普通回归树树 
  StaTree = createTree(TrainMat, ops=(1,20)) 
  # 得到预测结果 
  StaYHat = createForeCast(StaTree, TestMat[:,0], regTreeEval)# 第一列为 自变量 
  # 预测结果和真实标签的相关系数 
  StaCorr = corrcoef(StaYHat, TestMat[:,1], rowvar=0)[0,1] # NumPy 库函数  
# 模型回归树 预测结果 
  # 得到模型回归树 
  ModeTree = createTree(TrainMat,leafType=modelLeaf, errType=modelErr, ops=(1,20)) 
  # 得到预测结果 
  ModeYHat = createForeCast(ModeTree, TestMat[:,0], modelTreeEval)  
  # 预测结果和真实标签的相关系数 
  ModeCorr = corrcoef(ModeYHat, TestMat[:,1], rowvar=0)[0,1] # NumPy 库函数   
  print "普通回归树 预测结果的相关系数R2: %f" %(StaCorr)                        
  print "模型回归树 预测结果的相关系数R2: %f" %(ModeCorr) 
  if ModeCorr>StaCorr: 
  print "模型回归树效果优于普通回归树" 
  else: 
  print "回归回归树效果优于模型普通树"

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
在Python中居然可以定义两个同名通参数的函数
Jan 31 Python
python 提取文件指定列的方法示例
Aug 07 Python
Django对models里的objects的使用详解
Aug 17 Python
python3.7通过thrift操作hbase的示例代码
Jan 14 Python
基于Python获取照片的GPS位置信息
Jan 20 Python
python实现全排列代码(回溯、深度优先搜索)
Feb 26 Python
Python实现计算图像RGB均值方式
Jun 04 Python
python基于opencv实现人脸识别
Jan 04 Python
python正则表达式re.match()匹配多个字符方法的实现
Jan 27 Python
2021年pycharm的最新安装教程及基本使用图文详解
Apr 03 Python
python 命令行传参方法总结
May 25 Python
基于Pygame实现简单的贪吃蛇游戏
Dec 06 Python
使用python 和 lint 删除项目无用资源的方法
Dec 20 #Python
python机器学习实战之K均值聚类
Dec 20 #Python
Python绘制3d螺旋曲线图实例代码
Dec 20 #Python
python机器学习实战之最近邻kNN分类器
Dec 20 #Python
python3.6 +tkinter GUI编程 实现界面化的文本处理工具(推荐)
Dec 20 #Python
浅谈Python实现Apriori算法介绍
Dec 20 #Python
利用Python如何生成hash值示例详解
Dec 20 #Python
You might like
PHP版国家代码、缩写查询函数代码
2011/08/14 PHP
php在项目中寻找代码的坏味道(综艺命名)
2012/07/19 PHP
thinkphp实现发送邮件密码找回功能实例
2014/12/01 PHP
Yii视图CGridView列表用法实例分析
2016/07/12 PHP
PHP入门教程之表单与验证实例详解
2016/09/11 PHP
PHP入门教程之上传文件实例详解
2016/09/11 PHP
详解yii2实现分库分表的方案与思路
2017/02/03 PHP
laravel自定义分页的实现案例offset()和limit()
2019/10/15 PHP
在线游戏大家来找茬II
2006/09/30 Javascript
JavaScript 脚本将当地时间转换成其它时区
2009/03/19 Javascript
基于Jquery的简单图片切换效果
2011/01/06 Javascript
c#和Javascript操作同一json对象的实现代码
2012/01/17 Javascript
setInterval,setTimeout与jquery混用的问题
2013/04/08 Javascript
原始的js代码和jquery对比体会
2013/09/10 Javascript
js动态往表格的td中添加图片并注册事件
2014/06/12 Javascript
jquery使用正则表达式验证email地址的方法
2015/01/22 Javascript
js判断所有表单项不为空则提交表单的实现方法
2016/09/09 Javascript
微信小程序实现页面跳转传值以及获取值的方法分析
2017/12/18 Javascript
jQuery+Datatables实现表格批量删除功能【推荐】
2018/10/24 jQuery
[41:13]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第一场 11.20
2020/11/20 DOTA
python实现求解列表中元素的排列和组合问题
2018/03/15 Python
Django web框架使用url path name详解
2019/04/29 Python
对Python中画图时候的线类型详解
2019/07/07 Python
基于python全局设置id 自动化测试元素定位过程解析
2019/09/04 Python
TensorFlow索引与切片的实现方法
2019/11/20 Python
Python持续监听文件变化代码实例
2020/07/22 Python
Python3爬虫中识别图形验证码的实例讲解
2020/07/30 Python
10个很棒的 CSS3 开发工具 推荐
2011/05/16 HTML / CSS
英国街头品牌:Bee Inspired Clothing
2018/02/12 全球购物
德国排名第一的主题公园门票网站:Attraction Tickets Direct
2019/09/09 全球购物
机械专业应届生求职信
2013/09/21 职场文书
成立公司计划书
2014/05/07 职场文书
企业优秀员工事迹材料
2014/05/28 职场文书
房屋授权无偿使用证明
2014/11/29 职场文书
大学生实习证明
2015/06/16 职场文书
父亲去世追悼词
2015/06/23 职场文书