我们可以利用 graphviz 模块读取这个文件并将其可视化(你也可以使用任何能够读取 .dot文件的程序),见图 2-27:
import graphviz with open("tree.dot") as f: dot_graph = f.read() graphviz.Source(dot_graph) 图 2-27:基于乳腺癌数据集构造的决策树的可视化树的可视化有助于深入理解算法是如何进行预测的,也是易于向非专家解释的机器学习算法的优秀示例。不过,即使这里树的深度只有 4 层,也有点太大了。深度更大的树(深度为 10 并不罕见)更加难以理解。一种观察树的方法可能有用,就是找出大部分数据的实际路径。图 2-27 中每个结点的 samples 给出了该结点中的样本个数, values 给出的是每个类别的样本个数。观察 worst radius <= 16.795 分支右侧的子结点,我们发现它只包含8 个良性样本,但有 134 个恶性样本。树的这一侧的其余分支只是利用一些更精细的区别将这 8 个良性样本分离出来。在第一次划分右侧的 142 个样本中,几乎所有样本(132 个)最后都进入最右侧的叶结点中。
再来看一下根结点的左侧子结点,对于 worst radius > 16.795 ,我们得到 25 个恶性样本和 259 个良性样本。几乎所有良性样本最终都进入左数第二个叶结点中,大部分其他叶结点都只包含很少的样本。
4. 树的特征重要性查看整个树可能非常费劲,除此之外,我还可以利用一些有用的属性来总结树的工作原理。其中最常用的是特征重要性(feature importance),它为每个特征对树的决策的重要性进行排序。对于每个特征来说,它都是一个介于 0 和 1 之间的数字,其中 0 表示“根本没用到”,1 表示“完美预测目标值”。特征重要性的求和始终为 1:
print("Feature importances:\n{}".format(tree.feature_importances_))[out]:
Feature importances:
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.01
0.048 0. 0. 0.002 0. 0. 0. 0. 0. 0.727 0.046
0.014 0. 0.018 0.122 0.012 0. ]
我们可以将特征重要性可视化,与我们将线性模型的系数可视化的方法类似(图 2-28):
def plot_feature_importance_cancer(model): n_features = cancer.data.shape[1] plt.barh(range(n_features), model.feature_importances_, align=\'center\') plt.yticks(np.arange(n_features), cancer.feature_names) plt.xlabel("Feature importance") plt.ylabel("Feature") plot_feature_importance_cancer(tree) 图 2-28:在乳腺癌数据集上学到的决策树的特征重要性这里我们看到,顶部划分用到的特征(“worst radius”)是最重要的特征。这也证实了我们在分析树时的观察结论,即第一层划分已经将两个类别区分得很好。
但是,如果某个特征的 feature_importance_ 很小,并不能说明这个特征没有提供任何信息。这只能说明该特征没有被树选中,可能是因为另一个特征也包含了同样的信息。
与线性模型的系数不同,特征重要性始终为正数,也不能说明该特征对应哪个类别。特征重要性告诉我们“worst radius”(最大半径)特征很重要,但并没有告诉我们半径大表示样本是良性还是恶性。事实上,在特征和类别之间可能没有这样简单的关系,你可以在下面的例子中看出这一点(图 2-29 和图 2-30):
tree = mglearn.plots.plot_tree_not_monotone() 图 2-29:一个二维数据集( y 轴上的特征与类别标签是非单调的关系)与决策树给出的决策边界 图 2-30:从图 2-29 的数据中学到的决策树该图显示的是有两个特征和两个类别的数据集。这里所有信息都包含在 X[1] 中,没有用到X[0] 。但 X[1] 和输出类别之间并不是单调关系,即我们不能这么说:“较大的 X[1] 对应类别 0,较小的 X[1] 对应类别 1”(反之亦然)。
虽然我们主要讨论的是用于分类的决策树,但对用于回归的决策树来说,所有内容都是类似的,在 DecisionTreeRegressor 中实现。回归树的用法和分析与分类树非常类似。但在将基于树的模型用于回归时,我们想要指出它的一个特殊性质。 DecisionTreeRegressor(以及其他所有基于树的回归模型)不能外推(extrapolate),也不能在训练数据范围之外进行预测。