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

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

#-*- 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 "回归回归树效果优于模型普通树" 

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

时间: 2017-12-20

Python scikit-learn 做线性回归的示例代码

一.概述 机器学习算法在近几年大数据点燃的热火熏陶下已经变得被人所"熟知",就算不懂得其中各算法理论,叫你喊上一两个著名算法的名字,你也能昂首挺胸脱口而出.当然了,算法之林虽大,但能者还是有限,能适应某些环境并取得较好效果的算法会脱颖而出,而表现平平者则被历史所淡忘.随着机器学习社区的发展和实践验证,这群脱颖而出者也逐渐被人所认可和青睐,同时获得了更多社区力量的支持.改进和推广. 以最广泛的分类算法为例,大致可以分为线性和非线性两大派别.线性算法有著名的逻辑回归.朴素贝叶斯.最大熵等,

python利用sklearn包编写决策树源代码

本文实例为大家分享了python编写决策树源代码,供大家参考,具体内容如下 因为最近实习的需要,所以用python里的sklearn包重新写了一次决策树. 工具:sklearn,将dot文件转化为pdf格式(是为了将形成的决策树可视化)graphviz-2.38,下载解压之后将其中的bin文件的目录添加进环境变量 源代码如下: from sklearn.feature_extraction import DictVectorizer import csv from sklearn import

Python机器学习之K-Means聚类实现详解

本文为大家分享了Python机器学习之K-Means聚类的实现代码,供大家参考,具体内容如下 1.K-Means聚类原理 K-means算法是很典型的基于距离的聚类算法,采用距离作为相似性的评价指标,即认为两个对象的距离越近,其相似度就越大.其基本思想是:以空间中k个点为中心进行聚类,对最靠近他们的对象归类.通过迭代的方法,逐次更新各聚类中心的值,直至得到最好的聚类结果.各聚类本身尽可能的紧凑,而各聚类之间尽可能的分开. 算法大致流程为:(1)随机选取k个点作为种子点(这k个点不一定属于数据集)

Python机器学习之决策树算法实例详解

本文实例讲述了Python机器学习之决策树算法.分享给大家供大家参考,具体如下: 决策树学习是应用最广泛的归纳推理算法之一,是一种逼近离散值目标函数的方法,在这种方法中学习到的函数被表示为一棵决策树.决策树可以使用不熟悉的数据集合,并从中提取出一系列规则,机器学习算法最终将使用这些从数据集中创造的规则.决策树的优点为:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可以处理不相关特征数据.缺点为:可能产生过度匹配的问题.决策树适于处理离散型和连续型的数据. 在决策树中最重要的就是如何选取

Python机器学习库scikit-learn安装与基本使用教程

本文实例讲述了Python机器学习库scikit-learn安装与基本使用.分享给大家供大家参考,具体如下: 引言 scikit-learn是Python的一个开源机器学习模块,它建立在NumPy,SciPy和matplotlib模块之上能够为用户提供各种机器学习算法接口,可以让用户简单.高效地进行数据挖掘和数据分析. scikit-learn安装 python 中安装许多模板库之前都有依赖关系,安装 scikit-learn 之前需要以下先决条件: Python(>= 2.6 or >= 3

基于Python和Scikit-Learn的机器学习探索

你好,%用户名%! 我叫Alex,我在机器学习和网络图分析(主要是理论)有所涉猎.我同时在为一家俄罗斯移动运营商开发大数据产品.这是我第一次在网上写文章,不喜勿喷. 现在,很多人想开发高效的算法以及参加机器学习的竞赛.所以他们过来问我:"该如何开始?".一段时间以前,我在一个俄罗斯联邦政府的下属机构中领导了媒体和社交网络大数据分析工具的开发.我仍然有一些我团队使用过的文档,我乐意与你们分享.前提是读者已经有很好的数学和机器学习方面的知识(我的团队主要由MIPT(莫斯科物理与技术大学)和

用Python从零实现贝叶斯分类器的机器学习的教程

朴素贝叶斯算法简单高效,在处理分类问题上,是应该首先考虑的方法之一. 通过本教程,你将学到朴素贝叶斯算法的原理和Python版本的逐步实现. 更新:查看后续的关于朴素贝叶斯使用技巧的文章"Better Naive Bayes: 12 Tips To Get The Most From The Naive Bayes Algorithm" 朴素贝叶斯分类器,Matt Buck保留部分版权 关于朴素贝叶斯 朴素贝叶斯算法是一个直观的方法,使用每个属性归属于某个类的概率来做预测.你可以使用这

Python 机器学习库 NumPy入门教程

NumPy是一个Python语言的软件包,它非常适合于科学计算.在我们使用Python语言进行机器学习编程的时候,这是一个非常常用的基础库. 本文是对它的一个入门教程. 介绍 NumPy是一个用于科技计算的基础软件包,它是Python语言实现的.它包含了: 强大的N维数组结构 精密复杂的函数 可集成到C/C++和Fortran代码的工具 线性代数,傅里叶变换以及随机数能力 除了科学计算的用途以外,NumPy也可被用作高效的通用数据的多维容器.由于它适用于任意类型的数据,这使得NumPy可以无缝和

python机器学习之决策树分类详解

决策树分类与上一篇博客k近邻分类的最大的区别就在于,k近邻是没有训练过程的,而决策树是通过对训练数据进行分析,从而构造决策树,通过决策树来对测试数据进行分类,同样是属于监督学习的范畴.决策树的结果类似如下图: 图中方形方框代表叶节点,带圆边的方框代表决策节点,决策节点与叶节点的不同之处就是决策节点还需要通过判断该节点的状态来进一步分类. 那么如何通过训练数据来得到这样的决策树呢? 这里涉及要信息论中一个很重要的信息度量方式,香农熵.通过香农熵可以计算信息增益. 香农熵的计算公式如下: p(xi)

python机器学习库常用汇总

汇总整理一套Python网页爬虫,文本处理,科学计算,机器学习和数据挖掘的兵器谱. 1. Python网页爬虫工具集 一个真实的项目,一定是从获取数据开始的.无论文本处理,机器学习和数据挖掘,都需要数据,除了通过一些渠道购买或者下载的专业数据外,常常需要大家自己动手爬数据,这个时候,爬虫就显得格外重要了,幸好,Python提供了一批很不错的网页爬虫工具框架,既能爬取数据,也能获取和清洗数据,也就从这里开始了: 1.1 Scrapy 鼎鼎大名的Scrapy,相信不少同学都有耳闻,课程图谱中的很多课

python机器学习实战之K均值聚类

本文实例为大家分享了python K均值聚类的具体代码,供大家参考,具体内容如下 #-*- coding:utf-8 -*- #!/usr/bin/python ''''' k Means K均值聚类 ''' # 测试 # K均值聚类 import kMeans as KM KM.kMeansTest() # 二分K均值聚类 import kMeans as KM KM.biKMeansTest() # 地理位置 二分K均值聚类 import kMeans as KM KM.clusterClu

Python机器学习算法之k均值聚类(k-means)

一开始的目的是学习十大挖掘算法(机器学习算法),并用编码实现一遍,但越往后学习,越往后实现编码,越发现自己的编码水平低下,学习能力低.这一个k-means算法用Python实现竟用了三天时间,可见编码水平之低,而且在编码的过程中看了别人的编码,才发现自己对numpy认识和运用的不足,在自己的代码中有很多可以优化的地方,比如求均值的地方可以用mean直接对数组求均值,再比如去最小值的下标,我用的是argsort排序再取列表第一个,但是有argmin可以直接用啊.下面的代码中这些可以优化的并没有改,

python机器学习案例教程——K最近邻算法的实现

K最近邻属于一种分类算法,他的解释最容易,近朱者赤,近墨者黑,我们想看一个人是什么样的,看他的朋友是什么样的就可以了.当然其他还牵着到,看哪方面和朋友比较接近(对象特征),怎样才算是跟朋友亲近,一起吃饭还是一起逛街算是亲近(距离函数),根据朋友的优秀不优秀如何评判目标任务优秀不优秀(分类算法),是否不同优秀程度的朋友和不同的接近程度要考虑一下(距离权重),看几个朋友合适(k值),能否以分数的形式表示优秀度(概率分布). K最近邻概念: 它的工作原理是:存在一个样本数据集合,也称作为训练样本集,并

K均值聚类算法的Java版实现代码示例

1.简介 K均值聚类算法是先随机选取K个对象作为初始的聚类中心.然后计算每个对象与各个种子聚类中心之间的距离,把每个对象分配给距离它最近的聚类中心.聚类中心以及分配给它们的对象就代表一个聚类.一旦全部对象都被分配了,每个聚类的聚类中心会根据聚类中现有的对象被重新计算.这个过程将不断重复直到满足某个终止条件.终止条件可以是没有(或最小数目)对象被重新分配给不同的聚类,没有(或最小数目)聚类中心再发生变化,误差平方和局部最小. 2.什么是聚类 聚类是一个将数据集中在某些方面相似的数据成员进行分类组织

python实现k均值算法示例(k均值聚类算法)

简单实现平面的点K均值分析,使用欧几里得距离,并用pylab展示. 复制代码 代码如下: import pylab as pl #calc Euclid squiredef calc_e_squire(a, b):    return (a[0]- b[0]) ** 2 + (a[1] - b[1]) **2 #init the 20 pointa = [2,4,3,6,7,8,2,3,5,6,12,10,15,16,11,10,19,17,16,13]b = [5,6,1,4,2,4,3,1,

python机器学习实战之最近邻kNN分类器

K近邻法是有监督学习方法,原理很简单,假设我们有一堆分好类的样本数据,分好类表示每个样本都一个对应的已知类标签,当来一个测试样本要我们判断它的类别是, 就分别计算到每个样本的距离,然后选取离测试样本最近的前K个样本的标签累计投票, 得票数最多的那个标签就为测试样本的标签. 源代码详解: #-*- coding:utf-8 -*- #!/usr/bin/python # 测试代码 约会数据分类 import KNN KNN.datingClassTest1() 标签为字符串 KNN.datingC

Python机器学习logistic回归代码解析

本文主要研究的是Python机器学习logistic回归的相关内容,同时介绍了一些机器学习中的概念,具体如下. Logistic回归的主要目的:寻找一个非线性函数sigmod最佳的拟合参数 拟合.插值和逼近是数值分析的三大工具 回归:对一直公式的位置参数进行估计 拟合:把平面上的一些系列点,用一条光滑曲线连接起来 logistic主要思想:根据现有数据对分类边界线建立回归公式.以此进行分类 sigmoid函数:在神经网络中它是所谓的激励函数.当输入大于0时,输出趋向于1,输入小于0时,输出趋向0

Python聚类算法之基本K均值实例详解

本文实例讲述了Python聚类算法之基本K均值运算技巧.分享给大家供大家参考,具体如下: 基本K均值 :选择 K 个初始质心,其中 K 是用户指定的参数,即所期望的簇的个数.每次循环中,每个点被指派到最近的质心,指派到同一个质心的点集构成一个.然后,根据指派到簇的点,更新每个簇的质心.重复指派和更新操作,直到质心不发生明显的变化. # scoding=utf-8 import pylab as pl points = [[int(eachpoint.split("#")[0]), in