当最大深度加到 2 时,我们迫使输算法不需要分割的情况下强行分割。结果是,X1 属性在左右叉上被使用了两次来分割这个本已经完美分割的数据。 [X1 < 6.642] [X1 < 2.771] [0] [0] [X1 < 7.498] [1] [1] 最后,我们可以试试最大深度为 3 的情况: [X1 < 6.642] [X1 < 2.771] [0] [X1 < 2.771] [0] [0] [X1 < 7.498] [X1 < 7.445] [1] [1] [X1 < 7.498] [1] [1] 这些测试表明,我们可以优化代码来避免不必要的分割。请参见延伸章节的相关内容。 现在我们已经可以(完整地)创建一棵决策树了,那么我们来看看如何用它来在新数据上做出预测吧。 2.4 利用模型进行预测 使用决策树模型进行决策,需要我们根据给出的数据遍历整棵决策树。 与前面相同,我们仍需要使用一个递归函数来实现该过程。其中,基于某分割点对给出数据的影响,相同的预测规则被应用到左子节点或右子节点上。 我们需要检查对某子节点而言,它是否是一个可以被作为预测结果返回的终端节点,又或是他是否含有下一层的分割节点需要被考虑。 如下是实现上述过程的名为 predict() 函数,你可以看到它是如何处理给定节点的下标与数值的。
接着,我们使用合成的数据集来测试该函数。如下是一个使用仅有一个节点的硬编码树(即决策树桩)的案例。该案例中对数据集中的每个数据进行了预测。
运行该例子,它将按照预期打印出每个数据的预测结果。 Expected=0, Got=0 Expected=0, Got=0 Expected=0, Got=0 Expected=0, Got=0 Expected=0, Got=0 Expected=1, Got=1 Expected=1, Got=1 Expected=1, Got=1 Expected=1, Got=1 Expected=1, Got=1 现在,我们不仅掌握了如何创建一棵决策树,同时还知道如何用它进行预测。那么,我们就来试试在实际数据集上来应用该算法吧。 2.5 对钞票数据集的案例研究 该节描述了在钞票数据集上使用了 CART 算法的流程。 第一步是导入数据,并转换载入的数据到数值形式,使得我们能够用它来计算分割点。对此,我们使用了辅助函数 load_csv() 载入数据及 str_column_to_float() 以转换字符串数据到浮点数。 我们将会使用 5 折交叉验证法(5-fold cross validation)来评估该算法的表现。这也就意味着,对一个记录,将会有 1273/5=274.4 即 270 个数据点。我们将会使用辅助函数 evaluate_algorithm() 来评估算法在交叉验证集上的表现,用 accuracy_metric() 来计算预测的准确率。 完成的代码如下:
上述使用的参数包括:max_depth 为 5,min_size 为 10。经过了一些实现后,我们确定了上述 CART 算法的使用的参数,但这不代表所使用的参数就是最优的。 运行该案例,它将会 print 出对每一部分数据的平均分类准确度及对所有部分数据的平均表现。 从数据中你可以发现,CART 算法选择的分类设置,达到了大约 83% 的平均分类准确率。其表现远远好于只有约 50% 正确率的零规则算法(Zero Rule algorithm)。 Scores: [83.57664233576642, 84.30656934306569, 85.76642335766424, 81.38686131386861, 81.75182481751825] Mean Accuracy: 83.358% 三、延伸 本节列出了关于该节的延伸项目,你可以根据此进行探索。 1. 算法调参(Algorithm Tuning):在钞票数据集上使用的 CART 算法未被调参。你可以尝试不同的参数数值以获取更好的更优的结果。 2. 交叉熵(Cross Entropy):另一个用来评估分割点的成本函数是交叉熵函数(对数损失)。你能够尝试使用该成本函数作为替代。 3. 剪枝(Tree Pruning):另一个减少在训练过程中过拟合程度的重要方法是剪枝。你可以研究并尝试实现一些剪枝的方法。 (责任编辑:本港台直播) |