机器学习实战之树回归

“回归”与“树”

在讲解树回归之前,我们看看回归和树巧妙结合的原因。

线性回归的弊端
  • 线性回归需要拟合所有样本点,在特征多且特征关系复杂时,构建全局模型的想法就显得太难。
  • 实际生活中,问题很大程度上不是线性的,而是非线性的,所以线性回归的很容易欠拟合。
传统决策树弊端与改进

决策树可以解决数据的非线性问题,而且直观易懂,是否可以通过决策树来实现回归任务?

我们来回顾下之前讲过的决策树方法,其在划分子集的时候使用的方法是信息增益(我们也叫ID3方法),其方法只针对标称型(离散型)数据有效,很难用于回归;而且ID3算法切分过于迅速,容易过拟合,例如:一个特征有4个值,数据就会被切为四份,切分过后的特征在后面的过程中不再起作用。

CART(分类回归树)算法可以解决掉ID3的问题,该算法可用于分类和回归。我们来看看针对ID3算法的问题,CART算法是怎样解决的。

  • 信息增益无法切分连续型数据,如何计算连续型数据的混乱程度?其实,连续型的数据计算混乱程度很简单,根本不需要信息熵的理论。我们只需要计算平方误差的总值即可(先计算数据的均值,然后计算每条数据到均值的差值,进行平方求和)。
  • ID3方法切分太快,CART算法采用二元切分。

回归树

基于CART算法,当叶节点是分类值,就会是分类算法;如果是常数值(也就是回归需要预测的值),就可以实现回归算法。这里的常数值的求解很简单,就是该划分数据的均值。

数据情况

首先,利用代码带入数据,数据情况如图所示。

from numpy import \*



def loadDataSet(filename):

    dataMat = []

    fr = open(filename)

    for line in fr.readlines():

        curLine = line.strip().split('\t')

        fltLine = list(map(float,curLine))

        dataMat.append(fltLine)

    return dataMat
代码

其实CART算法直观(代码却比较多。。。),其实只用做两件事:切分数据和构造树。我们以这个数据为例:首先切分数据,找到一个中心点(平方误差的总值最小),这样就完成了划分(左下和右上),然后构造树(求左下和右上的均值为叶子节点)。我们来看代码:

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:

        return None, leafType(dataSet)

    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].T.tolist())[0]):

            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)

    mat0, mat1 = binSplitDataSet(dataSet, bestIndex, bestValue)

    if (shape(mat0)[0] < tolN) or (shape(mat1)[0] < tolN):

        return None, leafType(dataSet)

    return bestIndex, bestValue



def binSplitDataSet(dataSet, feature, value):

    mat0 = dataSet[nonzero(dataSet[:, feature] > value)[0], :]

    mat1 = dataSet[nonzero(dataSet[:, feature] <= value)[0], :]

    return mat0,mat1



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 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 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('错误')

    ws = xTx.I \* (X.T \* Y)

    return ws, X, Y

结果如图所示:

算法优缺点

  • 优点:可对复杂数据进行建模
  • 缺点:容易过拟合

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

Logistic回归模型、应用建模案例

一、logistic回归模型概述 广义线性回归是探索“响应变量的期望”与“自变量”的关系,以实现对非线性关系的某种拟合。这里面涉及到一个“连接...

3114
来自专栏社区的朋友们

机器学习概念总结笔记(一)

本部分介绍了机器学习算法的四大分类,即:监督学习、半监督学习、无监督学习和增强学习以及包括最小二乘回归、岭回归、LASSO回归、LARS回归在内的26大常见算法...

1.3K4
来自专栏ml

机器学习之最小二乘法

1.背景:      1801年,意大利天文学家朱赛普·皮亚齐发现了第一颗小行星谷神星。经过40天的跟踪观测后,由于谷神星运行至太阳背后,使得皮亚齐失去了谷神星...

3336
来自专栏机器学习算法全栈工程师

随机采样方法——蒙特卡罗方法

地址:http://www.cnblogs.com/pinard/p/6625739.html

733
来自专栏机器学习算法与Python学习

机器学习(12)之决策树总结与python实践(~附源码链接~)

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第二 【Python】:排名第三 【算法】:排名第四 前言 在(机器学习(9)之ID3算法...

78711
来自专栏机器学习原理

机器学习(7)——聚类算法聚类算法

聚类算法 前面介绍的集中算法都是属于有监督机器学习方法,这章和前面不同,介绍无监督学习算法,也就是聚类算法。在无监督学习中,目标属性是不存在的,也就是所说的不存...

1.2K7
来自专栏null的专栏

简单易学的机器学习算法——分类回归树CART

引言     分类回归树(Classification and Regression Tree,CART)是一种典型的决策树算法,CART算法不仅可以应用于分类...

2744
来自专栏有趣的Python和你

机器学习实战之树回归

1275
来自专栏智能算法

初识支持向量机原理

支持向量机作为机器学习中最为难于理解的算法,小编将以三篇的篇幅去讲解小编自己理解的SVM算法。主要包括:初识支持向量机原理、SVM如何解决线性不可分、SVM实践...

3136
来自专栏机器学习算法全栈工程师

支持向量机原理篇之手撕线性SVM

Python版本: Python3.x 运行平台: Windows IDE: Sublime text3 一、前言 说来惭愧,断更快半个月了,本打算是一...

4377

扫码关注云+社区