前言
本文主要说明 Python 的 sklearn 库中的决策树的常用接口、属性以及参数调优说明。
sklearn中的决策树
sklearn 中的决策树实现使用的是CART(Classification and Regression Trees)算法
sklearn中的决策树都在 sklearn.tree
这个模块下。
位置 | 说明 |
---|---|
tree.DecisionTreeClassifier | 分类树 |
tree.DecisionTreeRegressor | 回归树 |
tree.export_graphviz | 用于画图 |
tree.ExtraTreeClassifier | 高随机版本的分类树 |
tree.ExtraTreeRegressor | 高随机版本的回归树 |
基本使用
以红酒数据集和波士顿房价数据集为例,sklearn中的分类树和回归树的简单使用如下:
python
# 导包
from sklearn.datasets import load_wine, load_boston
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier, DecisionTreeRegressor
# 分类树
data_wine = load_wine() # 加载红酒数据集
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(data_wine.data, data_wine.target, test_size=0.3, random_state=42)
clf = DecisionTreeClassifier() # 分类树
clf.fit(X_train, y_train) # 拟合训练集
print(clf.predict(X_train)) # 输出测试集的预测结果
print(clf.score(X_test, y_test)) # 测试集上的准确率
# 回归树
data_boston = load_boston() # 加载波士顿房价数据集
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(data_boston.data, data_boston.target, test_size=0.3, random_state=42)
regressor = DecisionTreeRegressor() # 回归树
regressor.fit(X_train, y_train) # 拟合训练集
print(regressor.predict(X_train)) # 测试集的预测结果
print(regressor.score(X_test, y_test)) # 测试集上的决定系数 R2
常用属性和接口
.feature_importances_
:每个特征的特征重要性,总和为1.apply()
:与predict不同,例如输入为X_test,apply返回的则是测试样本所在叶子节点的索引
几乎每个模型都有的接口如训练和预测就不说明了.
决策树的 .score()
接口的计算方法:
- 分类树:使用Accuracy(准确度)作为指标, <math xmlns="http://www.w3.org/1998/Math/MathML"> 准确度 = 预测正确的样本数 总样本数 准确度=\frac{预测正确的样本数}{总样本数} </math>准确度=总样本数预测正确的样本数
- 回归树:使用决定系数系数 <math xmlns="http://www.w3.org/1998/Math/MathML"> R 2 R^2 </math>R2 作为指标,[0,1],越接近1表示效果越好,反之越差
本文主要讲解分类树和回归树的常用参数。
注:本文的说明都不是绝对的,不存在某种情况下某种说法一定就是正确的。
参数说明
以下参数说明是针对分类树的,对于回归树,几乎所有参数、属性及接口都和分类树一模一样。需要注意的是,在回归树中,没有标签分布是否均衡的问题,因此没有class_weight这样的参数。
sklearn中分类树和回归树的默认参数
- 分类树:
python
DecisionTreeClassifier(ccp_alpha=0.0, class_weight=None, criterion='gini',
max_depth=None, max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort='deprecated',
random_state=None, splitter='best')
- 回归树:
python
DecisionTreeRegressor(ccp_alpha=0.0, criterion='mse', max_depth=None,
max_features=None, max_leaf_nodes=None,
min_impurity_decrease=0.0, min_impurity_split=None,
min_samples_leaf=1, min_samples_split=2,
min_weight_fraction_leaf=0.0, presort='deprecated',
random_state=None, splitter='best')
本文涉及的参数和调优说明:
- criterion
- random_state
- splitter
- max_depth
- min_samples_leaf
- min_samples_split
- max_features
- min_impurity_decrease
- class_weight
- class_weight_fraction_leaf
本文主要就以上这十个常用参数进行说明和讲解.
criterion
criterion:规则,原则(英文直译)
criterion
:该参数用于决定决策树来计算不纯度的方法,共有两种选择
'entropy'
:信息熵'gini'
:Gini系数,默认值
参数说明:
- 信息熵和基尼系数的效果基本相同
- 使用信息熵速度会相对更慢一些,因为信息熵的计算(存在对数)比Gini系数的计算相对更复杂一些
- 信息熵对不纯度更加敏感,对不纯度的惩罚相对更强,使用信息熵作为指标时决策树的生长会更加 "精细",更容易过拟合
- 当模型欠拟合时(训练集测试集表现都差)可以尝试使用信息熵,当模型过拟合时(训练集好测试集差)可以尝试使用Gini系数
一般情况下使用Gini系数,当数据维度很高、噪音很大的时候使用Gini系数;维度低、数据相对清晰的时候信息熵和Gini系数区别不大;当决策树的拟合程度不够(欠拟合)时,使用信息熵。
对于回归树,criterion支持的标准为三种:
'mse'
(默认):均方误差mean squared error(MSE),父节点和叶子节点之间的均方误差的差额将被用来作为 特征选择的标准,这种方法通过使用叶子节点的均值来最小化损失'friedman_mse'
:使用费尔德曼均方误差,这种指标使用弗里德曼针对潜在分枝中的问题改进后的均方误差'mae'
:使用绝对平均误差MAE(mean absolute error),这种指标使用叶节点的中值来最小化损失在回归树中,MSE不只是我们的分枝质量衡量指标,也是我们最常用的衡量回归树回归质量的指标,我们往往选择均方误差作为我们的评估标准
虽然均方误差永远为正,但是sklearn当中使用均方误差作为评判标准时,却是计算 "负均方误差"(neg_mean_squared_error)。
- 这是因为sklearn在计算模型评估指标的时候,会考虑指标本身的性质,均 方误差本身是一种误差,所以被sklearn划分为模型的一种损失(loss),因此在sklearn当中,都以负数表示。真正的均方误差MSE的数值,其实就是neg_mean_squared_error去掉负号的数字。
random_state & splitter
splitter:分离器 (英文直译)
random_state
:用来设置分枝中的随机模式的参数,默认None,在高维度时随机性会表现更明显,对于低维度的数据,随机性几乎不会显现。输入任意整数,会一直长出同一棵树,让模型稳定下来。
sklearn中的决策树都是会先对原本所有的特征随机选取其中一部分用来建模,random_state的值不同,随机选取的情况可能也不同,当random_state为None时,每次都会重新进行随机选取。
splitter
:用来控制决策树中的随机选项,有两种输入值:
'best'
(默认值):决策树在分枝时虽然随机,但是还是会优先选择更重要的特征进行分枝(重要性可以通过属性feature_importances_查看)'random'
:决策树在分枝时会更加随机,树会因为含有更多的不必要信息而更深更大,并因这些不必要信息而降低对数据集的拟合程度。
控制决策树在选取特征时的随机程度也是防止过拟合的一种方式。当你预测到你的模型会过拟合,用这两个参数来帮助你降低树建成之后过拟合的可能性。
剪枝参数
在不加限制的情况下,一棵决策树会生长到衡量不纯度的指标最优的情况,或者没有更多的特征可用为止,这样的决策树模型往往会过拟合。为了让决策树有更好的泛化性,我们要对决策树进行剪枝。
剪枝策略对决策树的影响巨大,正确的剪枝策略是优化决策树算法的核心
max_depth
:限制树的最大深度,超过设定深度的树枝全部剪掉
- 默认值为 None,即不做限制
- 这是用得最广泛的剪枝参数,在高维度低样本量时非常有效。决策树多生长一层,对样本量的需求会增加近似一倍,所以限制树深度能够有效地限制过拟合。在集成算法中也非常实用。实际使用时,建议从 3 开始尝试,看看拟合的效 果再决定是否增加设定深度。
min_samples_leaf
:一个节点在分支后的每个子节点都必须包含至少 min_samples_leaf 个训练样本,否则分枝就不会发生。
- 默认值为 1
- 一般搭配 max_depth 使用,在回归树中有神奇的效果,可以让模型变得更加平滑。这个参数的数量设置得太小可能会引起过拟合,设置得太大可能会欠拟合,一般从 5 开始调整
- 如果叶节点中含有的样本量变化很大,建议输入浮点数作为样本量的百分比来使用:当输入为浮点数时,例如0.05,则表示 样本量*0.05 作为参数值
- 这个参数可以保证每个叶子的最小尺寸,可以在回归问题中避免高方差,过拟合的叶子节点出现。
- 对于类别不多的分类问题,1 通常就是最佳选择。
min_samples_split
:一个节点必须要包含至 少min_samples_split 个训练样本,这个节点才允许被分枝,否则分枝就不会发生。
- 注意这里的概念不要与 min_samples_leaf 进行混淆,若样本数量小于 min_samples_split 那么该节点就不会考虑进行分支,是前提条件。
max_features
:限制分枝时考虑的特征个数,超过限制个数的特征都会被舍弃。
- 默认值为 None
- 如果
max_features
是一个整数,则每个节点的拆分最多考虑max_features
个特征 - 如果
max_features
是一个浮点数,则每个节点的拆分最多考虑max_features * n_features
个特征,其中n_features
是总特征数量 - 如果
max_features
是一个字符串,则使用特定的方法选择特征。例如,"sqrt"表示每个节点的拆分最多考虑sqrt(n_features)
个特征,"log2"表示每个节点的拆分最多考虑log2(n_features)
个特征
max_features 用来限制高维度数据的过拟合的剪枝参数,但其方法比较暴力,是直接限制可以使用的特征数量 而强行使决策树停下的参数,在不知道决策树中的各个特征的重要性的情况下,强行设定这个参数可能会导致模型学习不足。
min_impurity_decrease
:限制信息增益的大小,信息增益小于设定数值的分枝不会发生
- 默认值为 None,即不做限制
- 可以尝试从一个相对较小的值开始调优,例如0.001或0.0001,并根据结果逐渐调整
如何确认最优的剪枝参数:
- 画曲线,横轴为超参数的值,纵轴为模型评估指标,观察曲线来选择超参数
剪枝参数的默认值会让树无尽地生长,这些树在某些数据集上可能非常巨大,对内存的消耗也非常巨 大。所以如果你手中的数据集非常巨大,你已经预测到无论如何你都是要剪枝的,那提前设定这些参数来控制树的 复杂性和大小会比较好。
目标权重参数
class_weight
:对样本标签进行一定的均衡,给少量的标签更多的权重,让模型更偏向少数类,向捕获少数类的方向建模。该参数默认None,此模式表示自动给 与数据集中的所有标签相同的权重。
None
(默认值):所有类别的权重都被视为相等,不进行特殊处理。'balanced'
:根据训练集中每个类别的样本数量自动调整权重。权重与类别中样本数量的反比成正比。- 字典(Dictionary):可以手动指定每个类别的权重。字典的键是类别标签,值是对应的权重。例如,
{0: 1, 1: 2}
表示类别0的权重为1,类别1的权重为2
样本不平衡:指在一组数据集中,标签的一类天生占有很大的比例。比如说,在银行要 判断 "一个办了信用卡的人是否会违约","是" 和 "否"(1%:99%)的比例。这种分类状况下,即便模型什么也不做,全把结果预测成 "否",正确率也能有99%。
min_weight_fraction_leaf
:用于控制叶子节点中样本权重的最小总和的比例。它可以用来限制决策树生成过程中叶子节点的最小权重
- 默认值为 0.0
- 类似于 min_samples_leaf,不过是权重版本的。在决策树的生成过程中,分裂节点时会考虑叶子节点中样本在指定权重下的总和。如果一个节点的权重总和低于 min_weight_fraction_leaf 指定的阈值,则不会进行分支。
class_weight 相当于给不同标签的样本的数量加上了权重,决策树在分支时会计算样本量等操作,对于不均衡的数据,class_weight 可以保证决策树在计算不同标签样本量时也会乘以不同的权重,一般对于不均衡数据参数使用 'balanced'
就可以了。
min_weight_fraction_leaf 就是权重版本的 min_samples_leaf 参数,需要注意的是,在设定 class_weight 参数后使用 min_samples_leaf 参数在计算样本量时是不会加上权重的。
Reference
- 菜菜的sklearn机器学习
- 相关网络资源和笔记