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

来源:互联网 发布:php如何加密源码软件 编辑:程序博客网 时间:2024/05/21 20:26

上面的蓝字关注我们!


作者:alg-flody

编辑:Emily


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算法的理解。


谢谢您的阅读!

交流思想,注重分析,看重过程,包含但不限于:经典算法,机器学习,深度学习,LeetCode 题解,Kaggle 实战,英语沙龙,定期邀请专家发推。期待您的到来!

原创粉丝点击