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 相关文章推荐
Python3中常用的处理时间和实现定时任务的方法的介绍
Apr 07 Python
python2.7安装图文教程
Mar 13 Python
Python线程池模块ThreadPoolExecutor用法分析
Dec 28 Python
详解Django中CBV(Class Base Views)模型源码分析
Feb 25 Python
Python读取stdin方法实例
May 24 Python
解决Python3 控制台输出InsecureRequestWarning问题
Jul 15 Python
python fuzzywuzzy模块模糊字符串匹配详细用法
Aug 29 Python
python xlwt如何设置单元格的自定义背景颜色
Sep 03 Python
解决springboot yml配置 logging.level 报错问题
Feb 21 Python
python画图常规设置方式
Mar 05 Python
Python 制作查询商品历史价格的小工具
Oct 20 Python
python index() 与 rindex() 方法的使用示例详解
Dec 24 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 编程请选择正确的文本编辑软件
2006/12/21 PHP
PHP计划任务之关闭浏览器后仍然继续执行的函数
2010/07/22 PHP
PHP判断上传文件类型的解决办法
2015/10/20 PHP
php strftime函数的详细用法
2018/06/21 PHP
PHP检测一个数组有没有定义的方法步骤
2019/07/20 PHP
一直复略了的一个问题,关于表单重复提交
2007/02/15 Javascript
javascript动画效果类封装代码
2007/08/28 Javascript
Javascript 篱式条件判断
2008/08/22 Javascript
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
JS 拼图游戏 面向对象,注释完整。
2009/06/18 Javascript
Firefox+FireBug使JQuery的学习更加轻松愉快
2010/01/01 Javascript
javascript中parentNode,childNodes,children的应用详解
2013/12/17 Javascript
javascript正则匹配汉字、数字、字母、下划线
2014/04/10 Javascript
用jquery.sortElements实现table排序
2014/05/04 Javascript
AngularJS实现表单验证
2015/01/28 Javascript
举例详解AngularJS中ngShow和ngHide的使用方法
2015/06/19 Javascript
jquery validate.js表单验证入门实例(附源码)
2015/11/10 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
jQuery 中的 DOM 操作
2016/04/26 Javascript
深入浅析AngularJS中的一次性数据绑定 (bindonce)
2017/05/11 Javascript
python实现连连看辅助(图像识别)
2020/03/25 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
python 比较2张图片的相似度的方法示例
2019/12/18 Python
Python使用QQ邮箱发送邮件报错smtplib.SMTPAuthenticationError
2019/12/20 Python
pyinstaller将含有多个py文件的python程序做成exe
2020/04/29 Python
python属于解释语言吗
2020/06/11 Python
Python第三方库安装缓慢的解决方法
2021/02/06 Python
纯CSS和jQuery实现的在页面顶部显示的进度条效果2例(仿手机浏览器进度条效果)
2014/04/16 HTML / CSS
英国最大的电子产品和家电零售企业:Currys PC World
2016/09/24 全球购物
缅甸网上购物:Shop.com.mm
2017/12/05 全球购物
计算机专业职业规划
2014/02/28 职场文书
活动总结书
2014/05/08 职场文书
大学生安全责任书
2014/07/25 职场文书
党小组鉴定意见
2015/06/02 职场文书
学困生帮扶工作总结
2015/08/13 职场文书
苹果macOS 13开发者预览版Beta 8发布 正式版10月发布
2022/09/23 数码科技