【sklearn】GradientBoosting(GBDT)

GBDT

  • GBDT
    • 1. 原理改进及特点
    • 2. 导包 & 数据
    • 3. sklearn.ensemble.GradientBoostingRegressor
      • 3.1 参数
      • 3.2 接口使用
    • 4. sklearn.ensemble.GradientBoostingClassifier
      • 4.1 回归器完成分类任务原理
      • 4.2 参数
      • 4.3 接口使用

GBDT

1. 原理改进及特点

  • GBDT的弱评估器一定是回归器;
    GBDT通过sigmoid或softmax函数输出分类结果;
    AdaBoost、随机森林, 执行回归任务则弱评估器是回归器, 执行分类任务则弱评估器是分类器。
  • GBDT的损失函数可用任意可微函数
    不局限于固定或单一的损失函数。
    AdaBoost损失函数知识点未整理
  • ⭐GBDT通过拟合残差影响后续弱评估器结构
    每次用于建立弱评估器的拟合目标是样本X和当下集成输出H(xi)与真实标签y的差异(y - H(xi) ), 称为残差
    AdaBoost修改样本权重, 拟合目标是真实标签y。
  • GBDT建树前允许对样本和特征进行抽样;
    GBDT加入随机森林中随机抽样的思想, 增大评估器的独立性(因此可有袋外数据集);

Boosting算法不会大规模依赖Bagging的方式降低方差,但其输出结果是弱评估器结果的加权求和,因此Boosting原则上也可获得由“平均”带来的小方差红利。
当弱评估器表现不稳定时,采用与随机森林相似的方式可以进一步增加Boosting算法的稳定性。

2. 导包 & 数据

from sklearn.ensemble import GradientBoostingClassifier
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import cross_validate, KFold
from sklearn.datasets import load_digits

data = load_digits()
X = data.data
y = data.target
# 定义交叉验证方式
cv = KFold(n_splits=5, shuffle=True, random_state=1)
print(X.shape,y.shape)
'''
    (1797, 64) (1797,)
'''

3. sklearn.ensemble.GradientBoostingRegressor

3.1 参数

【sklearn】Adaboost 参考建树过程原理

'''
n_estimators 迭代次数,最终形成弱评估器数量
learning_rate 学习率η 
'''
'''
init 输入计算初始预测结果H0的评估器对象
    H1(xi)=H0(xi)+η*ф1*f1(xi) H0值需要单独确定
    输入None或默认 类似输入随机数
    输入字符串"zero" 代表H0=0开始迭代
    输入评估器 
    	具备fit、predict_proba功能
    	如决策树、逻辑回归等可以输出概率的模型
    GBR().fit(X,y).init_ 返回查看H0
    一般不主动调节init,算力足够超参数搜索可调节。
    
'''
'''
loss 回归器中的损失函数 https://www.bilibili.com/video/BV1AZ4y1Z79H
    "squared_error"默认值 回归的平方误差,适用于预测离群值
    "absolute_error" 回归的绝对误差,适用于排除离群值影响
    "huber" 以上两者结合,适用于没有偏好
        alpha 决定阈值,默认0.9
    "quantile" 分位数回归中的弹球损失pinball_loss
        alpha 公式中辅助计算损失函数的输出结果,默认0.9
    .loss_ 查看损失函数对象
'''

3.2 接口使用

gbr = GradientBoostingRegressor(random_state=1412) # 默认100弱评估器
# https://blog.csdn.net/qq_45249685/article/details/125937140
result_gbdt = cross_validate(gbr
                            ,X,y
                            ,cv = cv
                             # 评估指标 负根均方误差
                            ,scoring="neg_root_mean_squared_error"
                            ,return_train_score=True # 返回验证集交叉验证分数
                            ,verbose=True # 打印建模流程
                            ,n_jobs=-1 # 调用所有cpu 
                            )
'''
    [Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
    [Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed:    3.1s remaining:    4.6s
    [Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:    3.1s finished
'''   
result_gbdt
'''
    {'fit_time': array([0.77227807, 0.76629114, 0.77031326, 0.74335098, 0.7691946 ]),
     'score_time': array([0.00099397, 0.00099778, 0.00199771, 0.00099778, 0.00202942]),
     'test_score': array([-1.17380397, -1.23704352, -1.18860127, -1.19422147, -1.22940202]),
     'train_score': array([-0.87929556, -0.86166957, -0.85336338, -0.90142607, -0.87496085])}
'''

def RMSE(result, name):
    return abs(result[name].mean()) # 不该**0.5吗??
# abs(result_gbdt['test_score'])**0.5
RMSE(result_gbdt, 'test_score')
'''
    1.2046144510500025
'''

4. sklearn.ensemble.GradientBoostingClassifier

4.1 回归器完成分类任务原理

GBDT中所有弱评估器都是回归树,需要借助softmax函数或sigmoid函数将输出结果转为[0, 1]概率值。

  • 二分类 sigmoid
    将集成算法对样本xi的输出H(xi)输出到sigmoid函数,即
    p(yi^=1 | xi) = δ(H(xi)),大于0.5预测类别为1。
  • 多分类 softmax
    类别[1, 2, 3…, k],按照y=1,y=2,…,y=k建模,每次迭代建立K棵树,每棵树输出为:H1(xi),H2(xi)…,Hk(xi)
    softmax函数接受K个连续型结果,输出K个相对概率。
    H1(xi),H2(xi)…,Hk(xi)作为softmax函数输入,输出K个类别标签的概率

4.2 参数

'''
GBDT所有弱评估器都是回归树,分类问题借助softmax实现
多分类任务时,要求迭代次数n_estimators=10,多分类标签数n_classes个,实际建立10*n_classes个弱评估器
n_estimators 实际迭代次数
    GBC().fit(x,y).n_estimators_ 查看
estimators_ 实际建立弱分类器数
    GBC().fit(x,y).estimators_.shape 返回(n_estimators, n_classes),(迭代次数,每次迭代建立弱评估器数)
'''
'''
loss 分类器中的损失函数
    "deviance" 默认值,交叉熵损失
    "exponential" 指数损失,AdaBoost也使用,相当于执行没有权重调整的AdaBoost
    都分别包含二分类损失函数和多分类损失函数  
'''

4.3 接口使用

clf = GradientBoostingClassifier(n_estimators=10
                                 ,random_state=1)

result_clf = cross_validate(clf
                           ,X,y
                           ,cv = cv
                           ,return_train_score=True
                           ,verbose=True
                           ,n_jobs=-1
                           )
'''
    [Parallel(n_jobs=-1)]: Using backend LokyBackend with 8 concurrent workers.
    [Parallel(n_jobs=-1)]: Done   2 out of   5 | elapsed:    2.8s remaining:    4.3s
    [Parallel(n_jobs=-1)]: Done   5 out of   5 | elapsed:    2.9s finished
'''
# 分类默认用准确率评估
print(result_clf['train_score'].mean(),
result_clf['test_score'].mean())
'''
    0.9600722220125183 0.9037310430207366
'''    

clf.fit(X,y).estimators_.shape
'''
    (10, 10)
'''

你可能感兴趣的:(Python,sklearn,python)