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中的fileinput模块的简单实用示例
Jul 09 Python
python 类对象和实例对象动态添加方法(分享)
Dec 31 Python
python读取文本中数据并转化为DataFrame的实例
Apr 10 Python
Python实现的NN神经网络算法完整示例
Jun 19 Python
Sanic框架Cookies操作示例
Jul 17 Python
Windows 安装 Anaconda3+PyCharm的方法步骤
Jun 13 Python
Django Admin中增加导出Excel功能过程解析
Sep 04 Python
详解python的super()的作用和原理
Oct 29 Python
pandas针对excel处理的实现
Jan 15 Python
Appium+Python实现简单的自动化登录测试的实现
Jan 26 Python
使用python如何删除同一文件夹下相似的图片
May 07 Python
Python3 多线程(连接池)操作MySQL插入数据
Jun 09 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
用Zend Encode编写开发PHP程序
2006/10/09 PHP
Discuz 模板引擎的封装类代码
2008/07/18 PHP
php数组保存文本与文本反编成数组实例
2014/11/13 PHP
php通过session防url攻击方法
2014/12/10 PHP
php实现的Curl封装类Curl.class.php用法实例分析
2015/09/25 PHP
PHP接收json 并将接收数据插入数据库的实现代码
2015/12/01 PHP
google地图的路线实现代码
2009/08/20 Javascript
jquery获取自定义属性(attr和prop)实例介绍
2013/04/21 Javascript
js使用for循环与innerHTML获取选中tr下td值
2014/09/26 Javascript
DOM 事件流详解
2015/01/20 Javascript
jquery实现叠层3D文字特效代码分享
2015/08/21 Javascript
微信小程序 闭包写法详细介绍
2016/12/14 Javascript
详解jQuery的表单验证插件--Validation
2016/12/21 Javascript
JavaScript中数据类型转换总结
2016/12/25 Javascript
vue中post请求以a=a&amp;b=b 的格式写遇到的问题
2018/04/27 Javascript
jQuery中each遍历的三种方法实例分析
2018/09/07 jQuery
刷新页面后让控制台的js代码继续执行
2019/09/20 Javascript
ES6中的Javascript解构的实现
2020/10/30 Javascript
解决Python 爬虫URL中存在中文或特殊符号无法请求的问题
2018/05/11 Python
Python之csv文件从MySQL数据库导入导出的方法
2018/06/21 Python
Numpy之文件存取的示例代码
2018/08/03 Python
python3 爬取图片的实例代码
2018/11/06 Python
Python3 执行Linux Bash命令的方法
2019/07/12 Python
对Tensorflow中tensorboard日志的生成与显示详解
2020/02/04 Python
使用Pycharm在运行过程中,查看每个变量的操作(show variables)
2020/06/08 Python
Django前后端分离csrf token获取方式
2020/12/25 Python
浅谈CSS3 box-sizing 属性 有趣的盒模型
2019/04/02 HTML / CSS
HTML5 本地存储 LocalStorage详解
2016/06/24 HTML / CSS
新西兰购物网站:TheMarket NZ
2020/09/19 全球购物
如何让Java程序执行效率更高
2014/06/25 面试题
《动手做做看》教学反思
2014/04/09 职场文书
群众路线教育实践活动调研报告
2014/11/03 职场文书
同事去世追悼词
2015/06/23 职场文书
Python 如何实现文件自动去重
2021/06/02 Python
vue+elementui 实现新增和修改共用一个弹框的完整代码
2021/06/08 Vue.js
mysql联合索引的使用规则
2021/06/23 MySQL