决策树

这是一篇《机器学习实战:基于Scikit-learn和TensorFlow》的学习笔记,如果有时间的话会考虑连课后题一起做一下。

决策树的训练与可视化

训练

from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier

iris = load_iris()
X = iris.data[:,2:]
y = iris.target

tree_clf = DecisionTreeClassifier(max_depth=2)
tree_clf.fit(X, y)

可视化

使用export_graphviz()方法输出一个图形定义文件

from sklearn.tree import export_graphviz

export_graphviz(
	tree_clf,
	out_file = image_path("iris_tree.dot"),
	feature_name = iris.target_names[2:],
	class_names = iris.target_names,
	rounded = True,
	failed = True
)

后续可以使用graphviz包的dot命令行工具将文件转为PDF或者PNG等格式。

$ dot -Tpng iris_tree.dot -o iris_tree.png

在这里插入图片描述
节点的samples属性统计它应用的训练实例数量,
value属性说明该节点上每个类别训练实例的数量,
gini属性衡量不纯度,又称基尼系数。 G i = 1 − ∑ k = 1 n p i , k 2 G_{i}=1-\sum^{n}_{k=1}p_{i,k}^{2} Gi=1k=1npi,k2
上图深度2左侧节点的基尼不纯度等于 1 − ( 0 54 ) 2 − ( 49 54 ) 2 − ( 5 54 ) 2 = 0.168 1-(\frac{0}{54})^{2}-(\frac{49}{54})^{2}-(\frac{5}{54})^{2}=0.168 1(540)2(5449)2(545)2=0.168

scikit-learn用的是CART算法,仅生成二叉树,即问题的答案只有是和否两种。

CART

CART, Classification And Regression Tree, 分类与回归树。
基本思想:使用单个特征k和阈值 t k t_{k} tk将训练集分成两个子集(如花瓣长度<=2.45厘米)

  • k和 t k t_{k} tk应该怎么选择?
    产生出最纯子集的k和 t k t_{k} tk就是经算法搜索得到的最优解。
  • 成本函数
    J ( k , t k ) = m l e f t m G l e f t + m r i g h t m G r i g h t J(k,t_{k})=\frac{m_{left}}{m}G_{left}+\frac{m_{right}}{m}G_{right} J(k,tk)=mmleftGleft+mmrightGright
    其中 G l e f t / r i g h t G_{left/right} Gleft/right衡量左/右子集的不纯度, m l e f t / r i g h t m_{left/right} mleft/right是左/右子集的实例数量。

一旦成功将训练集一分为二,它将使用相同的逻辑,继续分裂子集,以此循环,直到抵达最大深度(由超参数max_depth控制),或者是再也找不到能够降低不纯度的分裂,它才会停止。
还有一些超参数也用于控制停止条件:
min_samples_split, min_samples_leaf, min_weight_fraction_leaf, max_leaf_nodes)

  • CART是一种贪婪算法:从顶层开始搜索最优分裂,然后每层重复这个过程。几层分裂之后,它并不会检视这个分裂的不纯度是否为可能的最低值。贪婪算法通常会产生一个相当不错的解,但是不能保证是最优解。

基尼不纯度与信息熵

算法默认使用基尼不纯度来进行测量,但也可以通过设置超参数criterion=entropy来选择信息熵作为不纯度的测量方法。
熵的概念源于热力学,是一种分子混乱程度的测量:如果分子保持静止和良序,则熵接近于0。后来这个概念传播到各个领域,其中包括香农的信息理论,它衡量的是一条信息的平均内容:如果所有的信息都相同,则信息熵为0。在机器学习中,它也经常被用作一种不纯度的测量方式:如果数据集中包含一个类别的实例,其熵为0。
信息熵的计算 H i = − ∑ k = 1 , p i , k ! = 0 n p i , k l o g ( p i , k ) H_{i}=-\sum^{n}_{k=1,p_{i,k}!=0}p_{i,k}log(p_{i,k}) Hi=k=1,pi,k!=0npi,klog(pi,k)
同样以上图深度2左侧节点为例,它的信息熵为 − 49 54 l o g ( 49 54 ) − 5 54 l o g ( 5 54 ) = 0.31 -\frac{49}{54} log(\frac{49}{54})-\frac{5}{54} log(\frac{5}{54})=0.31 5449log(5449)545log(545)=0.31
至于选择基尼不纯度还是信息熵,其实大多数情况下这二者差异并不大,生成的树十分相似。基尼不纯度的计算速度相对快一些,所以作为默认配置。它们的不同处在于,基尼不纯度倾向于从树枝中分裂出最常见的类别,而信息熵则倾向于生产更平衡的树。

正则化超参数

决策树极少对训练数据做出假设,如果不加以限制,树的结构将跟随训练集变化,严密拟合,并且很可能过度拟合。这种模型通常被称为非参数模型,这不是说它不包含任何参数,而是指在训练之前没有确定参数的数量,导致模型结构自由而紧密地贴近数据。
为了避免过度拟合,需要在训练过程中降低决策树的自由度。这个过程被称为正则化。
正则化超参数的选择取决于所使用的模型,在这里,至少能够通过最大深度max_depth来使模型正则化,降低过度拟合的风险。
其他超参数:

  • min_samples_split:分裂前节点必须有的最小样本数
  • min_samples_leaf:也节点必须有的最小样本数
  • min_weight_fraction_leaf:最小加权实例总数
  • max_leaf_nodes:最大叶节点数量
  • max_features:分裂每个节点评估的最大特征数量

在这里插入图片描述

还可以:
先不加约束地训练模型,然后再对不必要的节点进行减枝。如果一个节点的子节点全部为叶节点,则该节点可被认为不必要,除非它所表示的纯度提升有重要的统计意义。
标准统计测试,比如 X 2 X^{2} X2测试,是用来估算“提升纯粹是出于偶然”(虚假设)的概率。如果这个概率(p)高于一个给定的阈值(通常为5%,由超参数控制),那么这个节点可被认为不必要,其子节点可被删除。直到所有不必要的节点都被删除,剪枝过程结束。

不稳定性

决策树青睐正交的决策边界,这导致它们对训练集的旋转非常敏感。如下图先是了一个简单的先行可分离数据集:左图中决策树可以轻松分裂,右图,数据集旋转45度后,决策边界产生了不必要的卷曲。虽然这两个模型都看似完美拟合,但是右侧模型很可能泛化不佳。限制这种问题的方法之一是PCA,让训练数据定位在一个更好的方向上。
在这里插入图片描述
决策树的主要问题是,它们对训练数据中的小变化非常敏感。

事实上scikit-learn使用的算法是随机的,也就是说,即使在相同的训练数据上,也可能会得到不同的模型(除非对random_state进行设置)
随机森林通过对许多树的预测进行平均来限制了这种不稳定性。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值