机器学习
1. GBDT
1.1 原理
GBDT(Gradient Boosting Decision Tree)通过串行的方式迭代训练多个相互依赖的决策树回归模型,最后综合多个简单模型共同作用产生输出,主要方法论与AdaBoost相似,其中不同的核心训练思想:
(1)AdaBoost中可使用多种(包含分类或回归)简单模型,如决策树,线性回归等;而GBDT中将简单模型限定为只能使用决策树回归模型
(2)AdaBoost利用前一轮简单模型的误差率来更新训练样本的权重用于下一轮的学习;而GBDT通过拟合前一轮决策树回归模型的残差,使残差尽可能的减少;其中为了方便优化残差的损失函数,GBDT采用损失函数的负梯度作为残差的近似值(梯度方向对残差下降快),因此GBDT可使用任意可微的损失函数来拟合残差
(3)采用抽样思想,即通过子采样比例(subsample)选择部分样本参与GBDT的迭代训练;可以有效的减少模型方差,防止过拟合提高模型泛化性
GBDT的算法流程如下:
假设给定一个大小为 n n n的数据集:
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . . . , ( x n , y n ) } \boldsymbol{D} = \{ (\pmb{x_1},y_1), (\pmb{x_2}, y_2),.....,(\pmb{x_n}, y_n) \} D={
(x1x1x1,y1),(x2x2x2,y2),.....,(xnxnxn,yn)}
L L L代表任意可微的损失函数
(1)初始化模型回归值:
f 0 ( x ) = arg min c ∑ i = 1 n L ( y i , c ) f_0(\pmb x)=\underset {c}{\argmin}\sum_{i = 1}^{n}L(y_i,c) f0(xxx)=cargmini=1∑nL(yi,c)
(2)计算每个样本的残差,即损失函数负梯度:
r t ( i ) = y i − f t − 1 ( x i ) ⇒ 近 似 r t ( i ) = − [ ∂ L ( y i , f t − 1 ( x i ) ) ∂ f t − 1 ( x i ) ] , t = 1 , 2 , . . . , m \begin{aligned} &r_t^{(i)} =y_i- f_{t - 1}(\pmb x_i) \\ \overset{近似}{\Rightarrow} &r_t^{(i)}=-\Big[\frac{\partial L(y_i , f_{t - 1}(\pmb x_i))}{\partial f_{t - 1}(\pmb x_i)}\Big], \quad t = 1,2, ...,m \end{aligned} ⇒近似rt(i)=yi−ft−1(xxxi)rt(i)=−[∂ft−1(xxxi)∂L(yi,ft−1(xxxi))],t=1,2,...,m
其中 m m m为决策树回归模型训练迭代次数
(3)通过 { ( x 1 , r t ( 1 ) ) , ( x 2 , r t ( 2 ) ) , . . . . . , ( x n , r t ( n ) ) } \{ (\pmb{x_1},r_t^{(1)}), (\pmb{x_2}, r_t^{(2)}),.....,(\pmb{x_n}, r_t^{(n)}) \} {
(x1x1x1,rt(1)),(x2x2x2,rt(2)),.....,(xnxnxn,rt(n))},拟合第t次决策树回归模型,得到对应的叶子节点区域 R t ( j ) R_t^{(j)} Rt(j),计算每个叶子节点区域的最佳拟合值:
c t ( j ) = arg min c ∑ x i ∈ R t ( j ) L ( y i , f t − 1 ( x i ) + c ) c_t^{(j)}=\underset {c}{\argmin}\sum_{\boldsymbol x_i \in R_t^{(j)}}L(y_i ,f_{t - 1}(\pmb x_i) + c) ct(j)=cargminxi∈Rt(j)∑L(yi,ft−1(xxxi)+c)
(4)更新第t次GBDT模型:
f t ( x ) = f t − 1 ( x ) + ∑ j = 1 J c t j I ( x ∈ R t j ) , j = 1 , 2 , . . . , J f_t(\pmb x) = f_{t - 1}(\pmb x) + \sum_{j=1}^{J}c_t^{j}I(x\in R_t^{j}), \quad j=1, 2,...,J ft(xxx)=ft−1(xxx)+j=1∑JctjI(x∈Rtj),j=1,2,...,J
其中 J J J为第t次决策树回归模型叶子节点的个数
(5)当达到指定残差或决策树回归模型训练的最大迭代次数,则组合得到最终的GBDT模型:
f ( x ) = f 0 ( x ) + ∑ t = 1 m ∑ j = 1 J c t ( j ) I ( x ∈ R t ( j ) ) f(\pmb x)=f_0(\pmb x) + \sum_{t=1}^{m}\sum_{j=1}^{J}c_t^{(j)}I(x\in R_t^{(j)}) f(xxx)=f0(xxx)+t=1∑mj=1∑Jct(j)I(x∈Rt(j))
说明:对于分类问题,GBDT可通过sign,sigmoid,softmax等函数输出分类结果
1.2 sklearn实现
参考官方文档:点击查看
GBDT分类可通过sklearn库中ensemble下的GradientBoostingClassifier类实现
有关参数:
- loss:拟合残差的损失函数,当使用指数损失函数时和AdaBoost相同
- learning_rate:每次迭代过程中更新决策树回归模型的附加权重(正则化方法)
- n_estimators:迭代更新次数,即决策树回归模型数量
- subsample:下采样比例,(0,1]之间,一种正则化方法
- criterion:回归决策树模型构建时特征选择的准则
- min_samples_split:节点拆分时需要的最少数据量
- min_samples_leaf:叶子节点需要的最少数据量
- min_weight_fraction_leaf:叶子节点的权重总和中需要的最小加权分数
- max_depth:决策树的最大深度
- min_impurity_decrease:递归生成决策树时相应准则数值减少量的最小阈值
- init:用来初始化GBDT首轮模型的求解器
- random_state:控制迭代更新决策树过程中的随机性
- max_features:决策树模型建立时考虑的特征数量
- verbose:控制输出的详细程度
- max_leaf_nodes:最大叶子节点数
- warm_start:是否使用上一次GBDT模型并添加更多决策树
- validation_fraction:当停止更新时,训练数据中用于测试集的比例
- n_iter_no_change:控制提前停止的迭代次数阈值,即在连续迭代更新中测试集精度没有提升的次数达到该阈值则停止更新
- tol:控制提前停止的拟合残差阈值,即在达到该阈值后拟合残差在n_iter_no_change次数内没有提升则停止更新
- ccp_alpha:控制最小化复杂度剪枝的阈值,默认不剪枝
有关属性:
- n_estimators_:迭代更新停止时决策树回归模型数量
- feature_importances_:基于特征计算准则的各特征重要程度
- oob_improvement_:在更新迭代过程中相较前一轮模型在包外样本(即非下采样样本)上损失函数的提升分数
- train_score_:各更新迭代过程中模型在包内样本(即下采样样本)上的损失函数分数
- loss_:已弃用
- init_:初始的决策树回归模型
- estimators_:GBDT中决策树回归模型列表集合
- classes_:各类别标签
- n_features_:已弃用
- n_features_in_:特征的个数
- feature_names_in_:特征的名称,仅当输入特征有(字符)名称时可用
- n_classes_:类别数量
- max_features_:参数max_feature的推断值
有关方法:
- apply:获取GBDT中各决策树模型上每个叶子节点对应输入数据的索引
- decision_function:计算输入数据在最终GBDT模型的预测值
- fit:生成GBDT模型
- get_params:获取对应模型参数
- predict:预测类别
- predict_log_proba:预测类别概率的对数
- predict_proba:预测类别概率
- score:获取给定数据集的平均准确度
- set_params:设置对应模型参数
- staged_decision_function:返回每一步迭代过程中决策树回归模型函数值的生成器
- staged_predict:返回每一步迭代过程中决策树回归模型预测类别的生成器
- staged_predict_proba:返回每一步迭代过程中决策树回归模型预测类别概率的生成器
使用案例
>>> import numpy as np
>>> from sklearn.ensemble import GradientBoostingClassifier
>>> clf = GradientBoostingClassifier() #实例化GBDT分类模型对象
>>> X = np.array([[1, 1], [1, 0], [0, 1]]) #数据
>>> y = np.array(['yes', 'no', 'no']) #类别
>>> clf.fit(X, y) #拟合求解
>>> clf.classes_
['no', 'yes']
>>> clf.n_features_in_
2
>>> clf.train_score_
[1.08..., 0.93...,...,0.00...]
>>> clf.decision_function(X)
[10.46...,-11.11...,-11.11...]
>>> clf.predict([[1, 0]])
['no']
>>> clf.score(X, y)
1.0
有关GBDT回归,点击查看官方文档