机器学习决策树:sklearn分类和回归

1 逻辑回归和决策树分类比较

昨天的推送机器学习:对决策树剪枝,分析了决策树需要剪枝,今天再就这个话题,借助 sklearn 进一步分析决策树分类和回归时过拟合发生后,该如何解决的问题。

上周推送的机器学习:谈谈决策树,介绍了利用逻辑回归算法,二分类一个拥有2个特征的数据集,模拟的结果如下所示:

从结果中可以看出,逻辑回归的分类效果是不错的,那么我们尝试用决策树分类这个数据集,看看效果是怎么样的。

通过上图分类的结果,黄色点为0类,相应的它们所在的区域为淡黄色区域,蓝色点为1类,相应的区域为右下区域。得到上图的代码:

def decisionTreeBoundary(data,n_classes=2,plot_colors = "yb",plot_step = 0.02):
  #特征的列index
    pairidx,pair = [1,2],[1,2]
    X = data[:,[1,2]]
    y = data[:,3]
    # Train
  #构造的无参数构造函数
    clf = tree.DecisionTreeClassifier()
    clf.fit(X, y)
    # 绘制决策边界
    x_min, x_max = X[:, 0].min(), X[:, 0].max()
    y_min, y_max = X[:, 1].min(), X[:, 1].max()
    xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),
                         np.arange(y_min, y_max, plot_step))
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    cs = plt.contourf(xx, yy, Z, cmap=plt.cm.BrBG)
    # 绘制训练点
    for i, color in zip(range(n_classes), plot_colors):
        idx = np.where(y == i)
        clabel=np.array(i,dtype=np.str)
        plt.scatter(X[idx, 0], X[idx, 1], c=color,label = clabel,
                   cmap=plt.cm.RdYlBu, edgecolor='black', s=15)
    plt.legend(loc='lower right', borderpad=0, handletextpad=0)
    plt.axis("tight")
    plt.xlabel("w1")
    plt.ylabel("w2")
    plt.title("using decision tree to binary classification")
    plt.show()

比较决策树和逻辑回归得到的决策边界:

  • 逻辑回归得到的决策边界更直接简洁,相应的泛化能力更好些。
  • 决策树得到的边界弯弯曲曲,好像被切了很多刀,泛化能力没有逻辑回归好。

可视化下决策树,

可以看到,决策树的枝枝叶叶有点茂盛,做一下剪枝操作。因此,让我们看下对未经剪枝的决策树,进行剪枝操作后,得到的决策边界是不是会好些,设置每个分裂点的最小样本数不能小于10,clf = tree.DecisionTreeClassifier(max_depth=3)

得到的分类边界切分了5刀,过拟合减轻了一些,在训练集上可以看到有些蓝点被错误地分类了,中间部位区域划分的不够合理。

同时可以可视化出对应的决策树深度为3层,共切分了6段。

由以上论述在样本数较少的情况下,可以看到逻辑分类的效果更满意一些,泛化能力可能更好些,决策树很容易过拟合,并且想要减轻过拟合时,准确率上又难以保证。

2 决策树做回归

我们首先生成一些需要模拟的数据,可以看到大部分的点(一维,只有一个特征)都位于一条曲线附件,但是有10个噪音点,偏离比较大。

生成这部分点的代码如下所示:

import numpy as np
from sklearn.tree import DecisionTreeRegressor
import matplotlib.pyplot as plt
    # Create a random dataset
rng = np.random.RandomState(100)
X = np.sort(rng.rand(100, 1), axis=0)
y = np.cos(X).ravel()
y[::10] += (0.5 - rng.rand(10))
 # Plot the results
plt.scatter(X, y, s=20, edgecolor="black",
            c="darkorange", label="data")
plt.scatter(X,y)
plt.show()

下面看下直接调用sklearn的API之决策树回归,得到的结果是怎样的。

首先不设置树的最大深度,这样决策树在做回归的时候会考虑所有的样本点,而发生过拟合,如下图所示,噪音点也被纳入到了回归曲线上,这是不好的,考虑对决策树进行剪枝,降低过拟合风险。

取树的最大深度等于5,看下模拟结果,部分降低了过拟合,但是还是考虑了某些噪音点,考虑继续减小树的深度,

取树的最大深度等于2时的模拟结果,可以看到所有噪音点都被排除在外,不再过拟合。

因此在做决策树回归时,和分类一样,也要考虑过拟合的问题,如果发生过拟合,一般通过调整决策树的超参数来降低过拟合。上面模拟用到的代码如下:

# Import the necessary modules and libraries
def dtr(maxdepth=2):
    import numpy as np
    from sklearn.tree import DecisionTreeRegressor
    import matplotlib.pyplot as plt
 # Create a random dataset
    rng = np.random.RandomState(100)
    X = np.sort(rng.rand(100, 1), axis=0)
    y = np.cos(X).ravel()
    y[::10] += (0.5 - rng.rand(10))
    # Fit regression model
    regr = DecisionTreeRegressor(max_depth=5)
    regr.fit(X, y)
    # Predict
    X_test = np.arange(0.0, 1.0, 0.01)[:, np.newaxis]
    y_predict = regr.predict(X_test)
    # Plot the results
    plt.scatter(X, y, s=20, edgecolor="black",
                c="darkorange", label="data")
    plt.plot(X_test, y_predict, color="blue", linewidth=2)
    plt.xlabel("data")
    plt.ylabel("target")
    plt.title("decision tree regression")
    plt.show()

3 总结

以上分析可以看出,决策树不仅可以做分类,还可以做回归。但是不管做分类还是回归,决策树都要考虑的问题是可能的过拟合发生,如果一旦出现,要考虑通过树的常见的超参数来降低,通常这些超参数包括:

1. criterion gini or entropy,选择哪个特征作为分裂点的判断公式。

2. splitter best or random:选择spitter best的话,是说从所有特征中找最好的切分点, random在数据量大的时候,特征多的时候,在部分特征中找最好的切分点。

3. max_features or None :max_features < 50是一般选择None,即使用所有的特征。

4. max_depth: 树的最大深度

5. min_samples_split:如果节点的样本数小于min_samples_split,则不再对这个节点分裂,这个值是在样本数很大时才用的。

6. min_samples_leaf:叶子节点的样本少于min_samples_leaf,则它和它的兄弟都会被裁剪。

7. max_leaf_nodes:决策树最大的叶子节点数,如果叶子节点大于max_leaf_nodes,则可能发生过拟合了,考虑调小这个值。

8. min_weight_fraction_leaf:这个值限制了叶子节点所有样本权重和的最小值,则会和兄弟节点一起被裁剪。

9. class_weight:调整某个类别的权重,主要考虑到某个类别的样本数所占比例大,导致偏向它,用户可以配置使这个类别权重小一些。

通过调整这些超参数,会得到最优化的结果。

决策树用于分类的优点如上文所述,我们可以解释它,比如在某个特征取值小于多少的时候,它一分为二了哪两个类,这些我们可以通过graphviz模块可视化地观察到,而不像复杂的神经元网络那样,只能得到参数,而无法解释每个参数为什么取这个值。

好了,这三天笔记了决策树的一些基本理论:特征选取方法,如何防止过拟合的发生,以及sklearn中的API直接调用模拟了决策树的分类和回归。

接下来,是否准备自己手动编写一个决策树分类器和回归器,进一步加深对决策树CART算法的理解。

原文发布于微信公众号 - 算法channel(alg-channel)

原文发表时间:2017-11-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏MelonTeam专栏

深度学习简易入门

深度学习是机器学习中的一个重要的方向,深度学习其实就是神经网络学习,这里“深度”就是说神经网络中众多的层。

2267
来自专栏AI研习社

从编程实现角度学习 Faster R-CNN(附极简实现)

Faster R-CNN 的极简实现: github: simple-faster-rcnn-pytorch(http://t.cn/RHCDoPv ) 本文插...

9815
来自专栏人工智能头条

如何使用TensorFlow实现卷积神经网络

811
来自专栏人工智能

神经网络与反向传播算法

1、前言 先简单的说下神经网络吧。 简单来说就是模拟大脑的神经元。 前端会有一大批数据输入,例如,前端输入了一张图像的所有像素点。 中间层会有成千上万个网络数据...

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

机器学习中防止过拟合的处理方法

我们都知道,在进行数据挖掘或者机器学习模型建立的时候,因为在统计学习中,假设数据满足独立同分布(i.i.d,independently and...

3465
来自专栏AI深度学习求索

传统特征:HOG特征原理

为了减少光照因素的影响,首先需要将整个图像进行规范化(归一化),有效地降低图像局部的阴影和光照变化。

1443
来自专栏大数据文摘

小白学数据:教你用Python实现简单监督学习算法

1894
来自专栏林欣哲

图像扩张

机器视觉中的图像识别问题,常常需要大量的数据,而带标签的数据需要人工标注,很难得到较多的数据。因此,我们需要使用图像扩张的方法,人工生成各种变换后的数据,扩大我...

36710
来自专栏IT派

手把手教你使用TensorFlow生成对抗样本 | 附源码

摘要: 本文使用TensorFlow一步一步生成对抗样本,步骤明确清晰。首先生成的对抗样本不具有旋转鲁棒性,后面使用同样的方法生成具有鲁棒性的对抗样本,适合初学...

6745
来自专栏和蔼的张星的图像处理专栏

3. 经典卷积网络之GooleInceptionNet

GooleInceptionNet首次出现是在2014年的ILSVRC的比赛中,当时是第一名,最大的特点就是控制计算量的同时获得了比较好的分类性能--top-5...

1462

扫码关注云+社区