GBDT模型
SWOT分析
优势(Strengths) | 劣势(Weaknesses) | 机会(Opportunities) | 威胁(Threats) |
---|---|---|---|
高预测精度 | 训练速度慢 | 集成学习 | 竞争对手 |
能处理各种类型的数据 | 容易过拟合 | 多任务学习 | 算法改进 |
鲁棒性强 | 对缺失值敏感 | 大数据场景 | 数据隐私 |
可解释性强 | 不支持在线学习 | ||
可进行特征选择 |
预测原理
在 GBDT 中,每棵回归树的构建都是基于损失函数的梯度下降,即每次迭代会计算出损失函数的负梯度,然后通过拟合一棵回归树来近似这个负梯度。在每次迭代结束后,根据拟合出的回归树,更新模型的预测值,并计算出新的损失函数值。通过不断迭代,最小化损失函数,可以得到最优的回归树和权重,从而得到最优的预测模型。
可以理解为当前步骤的预测值F是由上一步的预测值Ft-1加上学习率ρt乘以损失函数Lt-1关于预测值Ft-1的负梯度-∇F(L|F=Ft-1)得到的。
在 GBDT 中,默认情况下,第一棵回归树(即 i = 1 i=1 i=1)是一个常数值,通常取决于训练集的平均值。这棵树被称为初始估计器(initial estimator),记作 F 0 ( x ) F_0(x) F0(x)。因此,整个模型的预测公式可以表示为:
y p r e d = F 0 ( x ) + ∑ i = 1 n e s t i m a t o r s γ i F i ( x ) , i = 1 , 2 , ⋯ , n e s t i m a t o r s y_{pred} = F_0(x) + \sum_{i=1}^{n_{estimators}} \gamma_i F_i(x), \ \ i=1,2,\cdots,n_{estimators} ypred=F0(x)+i=1∑nestimatorsγiFi(x), i=1,2,⋯,nestimators
其中, F 0 ( x ) F_0(x) F0(x) 表示初始估计器对输入样本 x x x 的预测结果, γ i \gamma_i γi 表示第 i i i 棵回归树的权重, F i ( x ) F_i(x) Fi(x) 表示第 i i i 棵回归树对输入样本 x x x 的预测结果。
模型定义
参数
GradientBoostingRegressor函数是一个基于梯度提升树模型的回归器。以下是GradientBoostingRegressor()
函数的所有参数及其默认值和描述的表格,按照参数顺序排列:
参数 | 默认值 | 描述 |
---|---|---|
loss | 'ls' | 损失函数类型,可选值为'ls' (最小二乘回归)、'lad' (最小绝对偏差回归)、'huber' (Huber回归)、'quantile' (分位数回归) |
learning_rate | 0.1 | 学习率,每个弱学习器的权重缩减系数 |
n_estimators | 100 | 弱学习器的数量 |
subsample | 1.0 | 每个弱学习器使用的样本比例 |
criterion | 'friedman_mse' | 分裂特征的质量评估准则,可选值为'mse' (均方误差)、'friedman_mse' (Friedman均方误差)、'mae' (平均绝对误差) |
min_samples_split | 2 | 内部节点拆分所需的最小样本数 |
min_samples_leaf | 1 | 叶节点所需的最小样本数 |
min_weight_fraction_leaf | 0.0 | 叶节点所需的最小加权样本数 |
max_depth | 3 | 树的最大深度 |
min_impurity_decrease | 0.0 | 最小不纯度减少量 |
min_impurity_split | None | 最小不纯度拆分 |
init | None | 弱学习器的初始化,可选值为None 或一个估计器对象 |
random_state | None | 控制随机性的种子 |
max_features | None | 每个弱学习器使用的最大特征数,可选值为None 或'sqrt' 或'log2' 或整数 |
alpha | 0.9 | Huber回归中,控制离群值的影响程度的超参数 |
verbose | 0 | 控制输出详细程度的标志 |
max_leaf_nodes | None | 树的最大叶节点数 |
warm_start | False | 是否使用前一次调用fit() 的结果进行初始化 |
presort | 'deprecated' | 是否预先分拣数据以加速训练,已弃用 |
validation_fraction | 0.1 | 用于早期停止的验证集的比例 |
n_iter_no_change | None | 用于提前停止的迭代次数,设定后,如果一段时间内验证集的得分没有提高,则停止训练 |
tol | 1e-4 | 提前停止标准 |
ccp_alpha | 0.0 | 计算成本复杂度剪枝(CCP)时的复杂度复杂度参数 |
模型数据格式
regressor = GradientBoostingRegressor().fit(X,y)
参数名 | 类型 | 描述 |
---|---|---|
X | array-like 或稀疏矩阵 | 输入样本。形状为 (n_samples, n_features)。内部会被转换为 dtype=np.float32,如果输入为稀疏矩阵,则转换为 csr_matrix。 |
y | array-like | 目标值。形状为 (n_samples,)。对于分类问题,标签必须对应类别。 |
sample_weight | array-like | 每个样本的权重。形状为 (n_samples,)。如果为 None,则所有样本权重相等。如果某个样本的子节点权重为零或负,则在搜索每个节点的分裂时将忽略该样本。对于分类问题,如果某个子节点中任何一个类别的权重为负,则也将忽略该分裂。 |
monitor | callable | 监控函数。在每次迭代时调用该函数,传入当前迭代次数、估计器对象和 _fit_stages 的本地变量作为关键字参数 callable(i, self, locals())。如果该函数返回 True,则停止拟合过程。监控函数可用于计算保留估计、早期停止、模型内省和快照等各种任务。 |
返回值:
- self: 已拟合的估计器对象。
模型属性方法
以下是GradientBoostingRegressor模型中所有属性的官方解释:
属性 | 类型 | 描述 |
---|---|---|
feature_importances_ | ndarray of shape (n_features,) | 每个特征的重要性分数。重要性分数表示该特征对模型的性能贡献程度。 |
oob_improvement_ | ndarray of shape (n_estimators,) | 每个弱学习器的袋外(out-of-bag)误差改善量。这个属性只有在使用子采样时才会有值。 |
train_score_ | ndarray of shape (n_estimators,) | 每个弱学习器在训练集上的性能得分。 |
loss_ | LossFunction | 损失函数对象。 |
init_ | BaseEstimator | 初始模型对象。 |
estimators_ | ndarray of DecisionTreeRegressor | 训练过程中生成的所有弱学习器对象。 |
n_features_ | int | 数据集中的特征数量。 |
n_outputs_ | int | 输出变量的数量。 |
feature_importances_ | ndarray of shape (n_features,) | 每个特征的重要性分数。重要性分数表示该特征对模型的性能贡献程度。 |
train_score_ | ndarray of shape (n_estimators,) | 每个弱学习器在训练集上的性能得分。 |
oob_improvement_ | ndarray of shape (n_estimators,) | 每个弱学习器的袋外(out-of-bag)误差改善量。这个属性只有在使用子采样时才会有值。 |
init_ | BaseEstimator | 初始模型对象。 |
loss_ | LossFunction | 损失函数对象。 |
train_score_ | ndarray of shape (n_estimators,) | 每个弱学习器在训练集上的性能得分。 |
valid_score_ | ndarray of shape (n_estimators,) | 每个弱学习器在验证集上的性能得分。仅在使用早期停止时才有值。 |
n_features_ | int | 数据集中的特征数量。 |
n_outputs_ | int | 输出变量的数量。 |
train_loss_ | ndarray of shape (n_estimators,) | 每个弱学习器在训练集上的损失值。 |
validation_fraction_ | float | 用于早期停止的验证集的比例。 |
n_iter_no_change_ | int | 在验证集上连续n_iter_no_change次迭代中模型没有改善时,训练过程将提前停止。 |
feature_importances_ | ndarray of shape (n_features,) | 每个特征的重要性分数。重要性分数表示该特征对模型的性能贡献程度。 |
max_features_ | int | 每个节点在分裂时要考虑的特征数量。 |
n_estimators_ | int | 弱学习器(决策树)的数量。 |
classes_ | ndarray of shape (n_classes,) | 目标变量的类别。仅在使用分类损失函数时才有值。 |
n_classes_ | int | 目标变量的类别数量。仅在使用分类损失函数时才有值。 |
warm_start_ | bool | 是否启用热启动。 |
presort_ | bool | 是否在拟合前对数据进行排序。已弃用。 |
criterion_ | str | 用于衡量特征分裂质量的指标。 |
splitter_ | str | 用于决策树节点分裂的策略。 |
max_depth_ | int | 决策树的最大深度。 |
min_samples_split_ | int | 决策树节点分裂所需的最小样本数量。 |
min_samples_leaf_ | int | 决策树节点最小样本数量。 |
min_weight_fraction_leaf_ | float | 叶子节点的最小权重分数。 |
max_leaf_nodes_ | int | 决策树的最大叶子节点数量。 |
min_impurity_decrease_ | float | 如果分裂节点导致的不纯度减少量小于该值,则该分裂将被视为不必要的并被删除。 |
ccp_alpha_ | float | 决策树剪枝的复杂性参数。 |
以下是GradientBoostingRegressor模型中所有方法:
方法 | 方法描述 | 进一步描述 | 适用情况 | 参数描述 | 返回值 |
---|---|---|---|---|---|
fit(X, y[, sample_weight, monitor]) | 拟合模型。 | 训练一个基于决策树的梯度提升模型来拟合数据。 | 训练模型时使用。 | X:训练数据集, y:目标变量, sample_weight:样本权重, monitor:将在训练期间监视的指标。 | self |
apply(X) | 对新数据集进行预测,并返回每个样本所在叶子节点的索引。 | 返回每个样本所在的叶子节点索引,每个元素对应于X中的相应样本。 | 预测时使用。 | X:新数据集。 | ndarray of shape (n_samples, n_estimators) |
decision_function(X) | 对新数据集进行预测,并返回每个样本的预测值。 | 返回每个样本的预测值。 | 回归问题时使用。 | X:新数据集。 | ndarray of shape (n_samples,) |
predict(X) | 对新数据集进行预测,并返回每个样本的预测值。 | 返回每个样本的预测值。 | 回归问题时使用。 | X:新数据集。 | ndarray of shape (n_samples,) |
score(X, y[, sample_weight]) | 返回模型在给定测试数据集上的性能得分。 | 返回基于给定测试数据集的R-squared分数。 | 回归问题时使用。 | X:测试数据集, y:目标变量, sample_weight:样本权重。 | float |
staged_decision_function(X) | 针对训练过程中的每个弱学习器,对新数据集进行预测,并返回每个样本的预测值。 | 返回一个生成器,每个元素都是针对训练过程中的每个弱学习器的预测结果。 | 回归问题时使用。 | X:新数据集。 | generator |
staged_predict(X) | 针对训练过程中的每个弱学习器,对新数据集进行预测,并返回每个弱学习器的预测结果。 | 返回一个生成器,每个元素都是针对训练过程中的每个弱学习器的预测结果。 | 回归问题时使用。 | X:新数据集。 | generator |
staged_predict_proba(X) | 针对训练过程中的每个弱学习器,对新数据集进行分类概率预测,并返回每个弱学习器的预测结果。仅在使用分类损失函数时才有值。 | 返回一个生成器,每个元素都是针对训练过程中的每个弱学习器的预测结果。 | 分类问题时使用。 | X:新数据集。 | generator |
set_params(**params) | 设置模型参数。 | 设置模型的参数,如学习率、树的深度等。 | 训练模型时使用。 | **params:要设置的参数。 | self |
get_params([deep]) | 获取模型参数。 | 获取当前模型的参数设置。 | 训练模型时使用。 | deep:是否递归返回嵌套参数。 | dict |
损失函数
默认为ls,即平方误差, LAD(最小绝对误差)和Huber(平滑平方误差)是GBDT回归模型中可选的两个损失函数。它们分别适用于不同的情况。
LAD适用于对异常值较为敏感的情况,公式如下:
L
(
y
,
f
(
x
)
)
=
∑
i
=
1
n
∣
y
i
−
f
(
x
i
)
∣
L(y,f(x))=\sum_{i=1}^{n} |y_i-f(x_i)|
L(y,f(x))=∑i=1n∣yi−f(xi)∣
其中,
y
i
y_i
yi是样本i的真实值,
f
(
x
i
)
f(x_i)
f(xi)是模型对样本i的预测值。LAD的损失函数是绝对值误差的总和,也称为L1误差,它对样本点误差较大的情况更为敏感,因此可以更好地处理异常值。
Huber适用于对异常值不敏感的情况,公式如下:
L
(
y
,
f
(
x
)
)
=
∑
i
=
1
n
1
2
(
y
i
−
f
(
x
i
)
)
2
{
i
f
∣
y
i
−
f
(
x
i
)
∣
⩽
δ
}
L(y,f(x))=\sum_{i=1}^{n} \frac{1}{2}(y_i-f(x_i))^2 \left \{ \right. if|y_i-f(x_i)|\leqslant \delta \left. \right \}
L(y,f(x))=∑i=1n21(yi−f(xi))2{if∣yi−f(xi)∣⩽δ}
∣
y
i
−
f
(
x
i
)
∣
−
1
2
δ
2
o
t
h
e
r
w
i
s
e
|y_i-f(x_i)|-\frac{1}{2}\delta^2 \ otherwise
∣yi−f(xi)∣−21δ2 otherwise
其中,
δ
\delta
δ是一个阈值,
∣
y
i
−
f
(
x
i
)
∣
⩽
δ
|y_i-f(x_i)|\leqslant \delta
∣yi−f(xi)∣⩽δ用于平衡绝对误差和平方误差之间的影响。如果,则采用平方误差;否则采用绝对误差。Huber的损失函数是平滑平方误差,它对样本点误差较小的情况更为敏感,因此可以更好地处理异常值。
分裂标准
friedman_mse,即使用Friedman改进的均方误差,公式如下
M
S
E
F
r
i
e
d
m
a
n
=
∑
i
=
1
n
(
y
i
−
y
ˉ
)
2
n
−
2
k
(
n
−
1
)
∑
j
=
1
k
∑
i
=
1
n
(
y
i
j
−
y
j
ˉ
)
2
MSE_{Friedman} = \frac{\sum_{i = 1}^{n}(y_i - \bar{y})^2}{n} - \frac{2}{k(n-1)}\sum_{j = 1}^{k}\sum_{i = 1}^{n}(y_{ij} - \bar{y_j})^2
MSEFriedman=n∑i=1n(yi−yˉ)2−k(n−1)2∑j=1k∑i=1n(yij−yjˉ)2
其中: n 是所有观察值的总数。 k 是组数(或处理数)。
y
i
y_i
yi是第 i 个观察值。
y
ˉ
\bar{y}
yˉ是所有观察值的总平均数。 是第 i 组中的第 j 个观察值。 是第 j 个组的平均数。 公式中的第一项表示所有观察值的方差,而第二项表示由分组产生的方差。因此,Friedman的MSE度量了观察值在组内和组间方差之间的差异。Friedman的MSE值越小,说明分组算法的性能越好。
优化器
GradientBoostingRegressor是一种使用梯度提升算法的回归模型,它并不涉及任何优化器。在该模型中,每一次迭代都是基于前一次迭代的残差,对残差进行拟合得到一个新的模型,再将新的模型添加到原模型中,得到一个更好的模型。因此,GradientBoostingRegressor的优化过程是通过不断迭代来实现的,而不是通过优化器来实现的。
防止过拟合
可以对以下参数进行设置,防止过拟合
gbr = GradientBoostingRegressor(
n_estimators=100,
learning_rate=0.1,
max_depth=3,
subsample=0.8,
loss='squared_error'
)
模型评估指标
R²
regressor.score(X_test, y_test)
决定系数 R²定义为 ( 1 − u v ) (1-\frac{u}{v}) (1−vu) ,其中 u 是平方 ((y_true - y_pred)** 2).sum() 的残差和, v是平方 ((y_true - y_true.mean()) ** 2).sum() 的总和。可能的最佳分数是 1.0,它可以是负数(因为模型可以任意差)。始终预测期望值 y (不考虑输入特征)的常量模型将获得分 0.0。
模型可视化
代码示例
# 调用需要的库
import numpy as np # 矩阵计算库
import pydotplus # 绘图库
from sklearn.ensemble import GradientBoostingRegressor # 导入GBDT回归模型
from IPython.display import Image # IPython核心库中的Image库,可以用于在Jupyter Notebook中显示图片
from sklearn.tree import export_graphviz # 将决策树可视化的函数
# 生成数据
X = np.arange(1, 11).reshape(-1, 1) # 生成自变量
y = np.array([5.16, 4.73, 5.95, 6.42, 6.88, 7.15, 8.95, 8.71, 9.50, 9.15]) # 生成因变量
print(x.shape)
# 定义GBDT模型并拟合数据
gbdt = GradientBoostingRegressor(max_depth=4, criterion ='squared_error').fit(X, y)
# 可视化某一颗树
sub_tree = gbdt.estimators_[4, 0] # 获取GBDT模型中第5棵树(序号从0开始)
dot_data = export_graphviz(sub_tree, out_file=None, filled=True, rounded=True, special_characters=True, precision=2) # 将树导出为Graphviz格式(在控制台中显示)
graph = pydotplus.graph_from_dot_data(dot_data) # 用pydotplus将Graphviz格式的树转化为图像
graph_png=graph.create_png()
with open('graph.png','wb') as f:
f.write(graph_png)