关于决策树的那些事

决策树(DT)是用于分类和回归的非参数监督学习方法。目标是创建一个模型,通过学习从数据特征推断出的简单决策规则来预测目标变量的价值。

例如,在下面的例子中,决策树从数据中学习使用一组if-then-else决策规则来逼近正弦曲线。树越深,决策规则越复杂,模型也越复杂。

用决策树进行1D回归。

该决策树来拟合与另外嘈杂观察正弦曲线。结果,它学习了近似正弦曲线的局部线性回归。我们可以看到,如果树的最大深度(由max_depth参数控制 )设置得太高,那么决策树会学习过细的训练数据细节,并从噪声中学习,即它们会过度训练。关于决策树的那些事_第1张图片

 
   
  1. print(__doc__)

  2. # Import the necessary modules and libraries

  3. import numpy as np

  4. from sklearn.tree import DecisionTreeRegressor

  5. import matplotlib.pyplot as plt

  6. # Create a random dataset

  7. rng = np.random.RandomState(1)

  8. X = np.sort(5 * rng.rand(80, 1), axis=0)

  9. y = np.sin(X).ravel()

  10. y[::5] += 3 * (0.5 - rng.rand(16))

  11. # Fit regression model

  12. regr_1 = DecisionTreeRegressor(max_depth=2)

  13. regr_2 = DecisionTreeRegressor(max_depth=5)

  14. regr_1.fit(X, y)

  15. regr_2.fit(X, y)

  16. # Predict

  17. X_test = np.arange(0.0, 5.0, 0.01)[:, np.newaxis]

  18. y_1 = regr_1.predict(X_test)

  19. y_2 = regr_2.predict(X_test)

  20. # Plot the results

  21. plt.figure()

  22. plt.scatter(X, y, s=20, edgecolor="black",

  23.            c="darkorange", label="data")

  24. plt.plot(X_test, y_1, color="cornflowerblue",

  25.         label="max_depth=2", linewidth=2)

  26. plt.plot(X_test, y_2, color="yellowgreen", label="max_depth=5", linewidth=2)

  27. plt.xlabel("data")

  28. plt.ylabel("target")

  29. plt.title("Decision Tree Regression")

  30. plt.legend()

  31. plt.show()

决策树的一些优点是:

  • 很容易理解和解释。树可以被可视化。

  • 只需很少的数据准备。其他技术通常需要数据标准化,需要创建虚拟变量并删除空白值。但请注意,此模块不支持缺少的值。

  • 使用树的成本(即预测数据)是用于训练树的数据点的数量的对数。

  • 能够处理数字和分类数据。其他技术通常专门用于分析只有一种类型变量的数据集。

  • 能够处理多输出问题。

  • 使用白盒模型。如果给定的情况在模型中是可观察的,则条件的解释很容易通过布尔逻辑来解释。相比之下,在黑盒模型(例如,在人工神经网络中),结果可能更难以解释。

  • 可以使用统计测试来验证模型。这可以说明模型的可靠性。

  • 即使其假设受到数据生成的真实模型的某种程度的侵犯,也能很好地执行。

决策树的缺点包括:

  • 决策树学习者可以创建过于复杂的树,不能很好地概括数据。这被称为过度拟合。诸如修剪(目前不支持)等机制,设置叶节点所需的最小样本数或设置树的最大深度是避免此问题所必需的。

  • 决策树可能不稳定,因为数据中的小变化可能会导致生成完全不同的树。通过在集合中使用决策树可以缓解这个问题。

  • 学习最优决策树的问题在最优化的几个方面甚至简单的概念下已知是NP完全的。因此,实际决策树学习算法基于启发式算法,例如在每个节点进行局部最优决策的贪心算法。这样的算法不能保证返回全局最优决策树。这可以通过在集合学习器中训练多棵树来缓解,其中特征和样本随机地用替换采样。

  • 有些概念很难学,因为决策树不能很容易地表达它们,例如XOR,奇偶校验或多路复用器问题。

  • 如果某些类占主导地位,决策树学习者会创建偏向性树。因此,建议在拟合决策树之前平衡数据集。

分类

DecisionTreeClassifier 是一个能够对数据集进行多级分类的类。 与其他分类器一样, DecisionTreeClassifier将两个数组作为输入:一个数组X,稀疏或密集,其大小 保持训练样本,以及一个整数值数组Y,其中包含训练样本的类标签: [n_samples,n_features][n_samples]

pythonfromsklearnimporttree X=[[0,0],[1,1]]Y=[0,1]clf=tree.DecisionTreeClassifier()clf=clf.fit(X,Y)

经过拟合后,该模型可用于预测样本的类别

 
   
  1. >>> clf.predict([[2., 2.]])

  2. array([1])

或者,可以预测每个类的概率,这是叶中同一类的训练样本的分数:

 
   
  1. >>> clf.predict_proba([[2., 2.]])

  2. array([[ 0.,  1.]])

DecisionTreeClassifier 能够同时具有二元(其中标签是[-1,1])分类和多类别(其中标签是[0,...,K-1])分类。 使用Iris数据集,我们可以构建一棵树,如下所示

 
   
  1. >>> from sklearn.datasets import load_iris

  2. >>> from sklearn import tree

  3. >>> iris = load_iris()

  4. >>> clf = tree.DecisionTreeClassifier()

  5. >>> clf = clf.fit(iris.data, iris.target)

一旦训练完成,我们可以使用导出器以Graphviz格式导出树export_graphviz 。如果您使用conda软件包管理器,则可以使用graphviz二进制文件和python软件包进行安装conda安装python-graphviz或者,可以从graphviz项目主页下载graphviz的二进制文件,并使用pip安装graphviz从pypi安装Python包装程序。

以下是在整个虹膜数据集上训练的上述树的graphviz导出示例; 结果保存在一个输出文件iris.pdf中:

 
   
  1. >>> import graphviz

  2. >>> dot_data = tree.export_graphviz(clf, out_file=None)

  3. >>> graph = graphviz.Source(dot_data)

  4. >>> graph.render("iris")

export_graphviz出口也支持多种美学选项,包括可以通过类着色节点(或值回归)和如果需要的话使用显式的变量和类名称。Jupyter笔记本也自动内联这些图表

 
   
  1. >>> dot_data = tree.export_graphviz(clf, out_file=None,

  2.                         feature_names=iris.feature_names,  

  3.                         class_names=iris.target_names,  

  4.                         filled=True, rounded=True,  

  5.                         special_characters=True)  

  6. >>> graph = graphviz.Source(dot_data)  

  7. >>> graph

关于决策树的那些事_第2张图片

经过拟合后,该模型可用于预测样本的类别:

 
   
  1. >>> clf.predict(iris.data[:1, :])

  2. array([0])

或者,可以预测每个类的概率,这是叶中同一类的训练样本的分数:

 
   
  1. >>> clf.predict_proba(iris.data[:1, :])

  2. array([[ 1.,  0.,  0.]])

例子:绘制虹膜数据集上决策树的决策表面

关于决策树的那些事_第3张图片

 
   
  1. print(__doc__)

  2. import numpy as np

  3. import matplotlib.pyplot as plt

  4. from sklearn.datasets import load_iris

  5. from sklearn.tree import DecisionTreeClassifier

  6. # Parameters

  7. n_classes = 3

  8. plot_colors = "ryb"

  9. plot_step = 0.02

  10. # Load data

  11. iris = load_iris()

  12. for pairidx, pair in enumerate([[0, 1], [0, 2], [0, 3],

  13.                                [1, 2], [1, 3], [2, 3]]):

  14.    # We only take the two corresponding features

  15.    X = iris.data[:, pair]

  16.    y = iris.target

  17.    # Train

  18.    clf = DecisionTreeClassifier().fit(X, y)

  19.    # Plot the decision boundary

  20.    plt.subplot(2, 3, pairidx + 1)

  21.    x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1

  22.    y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1

  23.    xx, yy = np.meshgrid(np.arange(x_min, x_max, plot_step),

  24.                         np.arange(y_min, y_max, plot_step))

  25.    plt.tight_layout(h_pad=0.5, w_pad=0.5, pad=2.5)

  26.    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])

  27.    Z = Z.reshape(xx.shape)

  28.    cs = plt.contourf(xx, yy, Z, cmap=plt.cm.RdYlBu)

  29.    plt.xlabel(iris.feature_names[pair[0]])

  30.    plt.ylabel(iris.feature_names[pair[1]])

  31.    # Plot the training points

  32.    for i, color in zip(range(n_classes), plot_colors):

  33.        idx = np.where(y == i)

  34.        plt.scatter(X[idx, 0], X[idx, 1], c=color, label=iris.target_names[i],

  35.                    cmap=plt.cm.RdYlBu, edgecolor='black', s=15)

  36. plt.suptitle("Decision surface of a decision tree using paired features")

  37. plt.legend(loc='lower right', borderpad=0, handletextpad=0)

  38. plt.axis("tight")

  39. plt.show()

多输出问题

多输出问题是一个监督学习问题,有几个输出可以预测,也就是说当Y是一个二维数组时。 [n_samples,n_outputs]当输出之间不存在关联时,解决这类问题的一种非常简单的方法是构建n个独立模型,即每个输出一个模型,然后使用这些模型独立预测n个输出中的每一个。但是,因为与同一输入相关的输出值可能本身是相互关联的,所以通常更好的方法是建立能够同时预测所有n个输出的单个模型。首先,由于只建立一个估计器,所以它需要较短的训练时间。其次,结果估计量的泛化精度往往会增加。

关于决策树,这个策略可以很容易地用来支持多输出问题。这需要进行以下更改:

将n个输出值存储在树叶中,而不是1; 使用分裂标准计算所有n个输出的平均减少量。

该模块通过实现双方这一战略提供了多路输出的问题,支持DecisionTreeClassifier和 DecisionTreeRegressor。如果决策树适合输出数组Y的大小,那么得到的估计器将:[nsamples, noutputs]

输出noutput值predict; 输出类概率的noutput数组列表 predict_proba。

多输出树进行回归演示。

在这个例子中,输入X是单个实数值,输出Y是X的正弦和余弦。

关于决策树的那些事_第4张图片

 
   
  1. print(__doc__)

  2. import numpy as np

  3. import matplotlib.pyplot as plt

  4. from sklearn.tree import DecisionTreeRegressor

  5. # Create a random dataset

  6. rng = np.random.RandomState(1)

  7. X = np.sort(200 * rng.rand(100, 1) - 100, axis=0)

  8. y = np.array([np.pi * np.sin(X).ravel(), np.pi * np.cos(X).ravel()]).T

  9. y[::5, :] += (0.5 - rng.rand(20, 2))

  10. # Fit regression model

  11. regr_1 = DecisionTreeRegressor(max_depth=2)

  12. regr_2 = DecisionTreeRegressor(max_depth=5)

  13. regr_3 = DecisionTreeRegressor(max_depth=8)

  14. regr_1.fit(X, y)

  15. regr_2.fit(X, y)

  16. regr_3.fit(X, y)

  17. # Predict

  18. X_test = np.arange(-100.0, 100.0, 0.01)[:, np.newaxis]

  19. y_1 = regr_1.predict(X_test)

  20. y_2 = regr_2.predict(X_test)

  21. y_3 = regr_3.predict(X_test)

  22. # Plot the results

  23. plt.figure()

  24. s = 50

  25. s = 25

  26. plt.scatter(y[:, 0], y[:, 1], c="navy", s=s,

  27.            edgecolor="black", label="data")

  28. plt.scatter(y_1[:, 0], y_1[:, 1], c="cornflowerblue", s=s,

  29.            edgecolor="black", label="max_depth=2")

  30. plt.scatter(y_2[:, 0], y_2[:, 1], c="red", s=s,

  31.            edgecolor="black", label="max_depth=5")

  32. plt.scatter(y_3[:, 0], y_3[:, 1], c="orange", s=s,

  33.            edgecolor="black", label="max_depth=8")

  34. plt.xlim([-6, 6])

  35. plt.ylim([-6, 6])

  36. plt.xlabel("target 1")

  37. plt.ylabel("target 2")

  38. plt.title("Multi-output Decision Tree Regression")

  39. plt.legend(loc="best")

  40. plt.show()

面对多输出估计器完成

在这个例子中,输入X是面的上半部分的像素,输出Y是这些面的下半部分的像素。关于决策树的那些事_第5张图片

 
   
  1. print(__doc__)

  2. import numpy as np

  3. import matplotlib.pyplot as plt

  4. from sklearn.datasets import fetch_olivetti_faces

  5. from sklearn.utils.validation import check_random_state

  6. from sklearn.ensemble import ExtraTreesRegressor

  7. from sklearn.neighbors import KNeighborsRegressor

  8. from sklearn.linear_model import LinearRegression

  9. from sklearn.linear_model import RidgeCV

  10. # Load the faces datasets

  11. data = fetch_olivetti_faces()

  12. targets = data.target

  13. data = data.images.reshape((len(data.images), -1))

  14. train = data[targets < 30]

  15. test = data[targets >= 30]  # Test on independent people

  16. # Test on a subset of people

  17. n_faces = 5

  18. rng = check_random_state(4)

  19. face_ids = rng.randint(test.shape[0], size=(n_faces, ))

  20. test = test[face_ids, :]

  21. n_pixels = data.shape[1]

  22. # Upper half of the faces

  23. X_train = train[:, :(n_pixels + 1) // 2]

  24. # Lower half of the faces

  25. y_train = train[:, n_pixels // 2:]

  26. X_test = test[:, :(n_pixels + 1) // 2]

  27. y_test = test[:, n_pixels // 2:]

  28. # Fit estimators

  29. ESTIMATORS = {

  30.    "Extra trees": ExtraTreesRegressor(n_estimators=10, max_features=32,

  31.                                       random_state=0),

  32.    "K-nn": KNeighborsRegressor(),

  33.    "Linear regression": LinearRegression(),

  34.    "Ridge": RidgeCV(),

  35. }

  36. y_test_predict = dict()

  37. for name, estimator in ESTIMATORS.items():

  38.    estimator.fit(X_train, y_train)

  39.    y_test_predict[name] = estimator.predict(X_test)

  40. # Plot the completed faces

  41. image_shape = (64, 64)

  42. n_cols = 1 + len(ESTIMATORS)

  43. plt.figure(figsize=(2. * n_cols, 2.26 * n_faces))

  44. plt.suptitle("Face completion with multi-output estimators", size=16)

  45. for i in range(n_faces):

  46.    true_face = np.hstack((X_test[i], y_test[i]))

  47.    if i:

  48.        sub = plt.subplot(n_faces, n_cols, i * n_cols + 1)

  49.    else:

  50.        sub = plt.subplot(n_faces, n_cols, i * n_cols + 1,

  51.                          title="true faces")

  52.    sub.axis("off")

  53.    sub.imshow(true_face.reshape(image_shape),

  54.               cmap=plt.cm.gray,

  55.               interpolation="nearest")

  56.    for j, est in enumerate(sorted(ESTIMATORS)):

  57.        completed_face = np.hstack((X_test[i], y_test_predict[est][i]))

  58.        if i:

  59.            sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j)

  60.        else:

  61.            sub = plt.subplot(n_faces, n_cols, i * n_cols + 2 + j,

  62.                              title=est)

  63.        sub.axis("off")

  64.        sub.imshow(completed_face.reshape(image_shape),

  65.                   cmap=plt.cm.gray,

  66.                   interpolation="nearest")

  67. plt.show()



更多精彩内容

机器学习术语一览表

机器学习~零基础学习路线

长文 | LSTM和循环神经网络基础教程(PDF下载)

如何构建行业知识图谱

关于决策树的那些事_第6张图片

有时候你以为天塌下来了,其实是自己站歪了。

640?wx_fmt=png

每一次阅读 我都当成是喜欢

你可能感兴趣的:(关于决策树的那些事)