一、前向分布算法介绍:
前向分步算法是构建集成学习的一个非常重要的框架,可以从前面学习的Adaboost算法的整体逻辑框架中抽象得出。这个框架包含加法模型和前向分步算法两个部分,有了这个框架,既可以解决分类问题,也可以解决回归问题。
1.1 加法模型:
在Adaboost模型中,我们把每个基本分类器合成一个复杂分类器的方法是每个基本分类器的加权和,即: f ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right) f(x)=∑m=1Mβmb(x;γm),其中, b ( x ; γ m ) b\left(x ; \gamma_{m}\right) b(x;γm)为即基本分类器, γ m \gamma_{m} γm为基本分类器的参数, β m \beta_m βm为基本分类器的权重。
在给定训练数据以及损失函数 L ( y , f ( x ) ) L(y, f(x)) L(y,f(x))的条件下,学习加法模型 f ( x ) f(x) f(x) 就是:
min β m , γ m ∑ i = 1 N L ( y i , ∑ m = 1 M β m b ( x i ; γ m ) ) \min _{\beta_{m}, \gamma_{m}} \sum_{i=1}^{N} L\left(y_{i}, \sum_{m=1}^{M} \beta_{m} b\left(x_{i} ; \gamma_{m}\right)\right) βm,γmmini=1∑NL(yi,m=1∑Mβmb(xi;γm))
基本思路是: 因为学习的是加法模型,如果从前向后,每一步只优化一个基函数及其系数,逐步逼近目标函数,那么就可以降低优化的复杂度。具体而言,每一步只需要优化:
min β , γ ∑ i = 1 N L ( y i , β b ( x i ; γ ) ) \min _{\beta, \gamma} \sum_{i=1}^{N} L\left(y_{i}, \beta b\left(x_{i} ; \gamma\right)\right) β,γmini=1∑NL(yi,βb(xi;γ))
1.2 前向分步算法:
给定数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\} T={(x1,y1),(x2,y2),⋯,(xN,yN)}, x i ∈ X ⊆ R n x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n} xi∈X⊆Rn, y i ∈ Y = { + 1 , − 1 } y_{i} \in \mathcal{Y}=\{+1,-1\} yi∈Y={+1,−1}。损失函数 L ( y , f ( x ) ) L(y, f(x)) L(y,f(x)),基函数集合 { b ( x ; γ ) } \{b(x ; \gamma)\} {b(x;γ)},我们需要输出加法模型 f ( x ) f(x) f(x)。
- 初始化: f 0 ( x ) = 0 f_{0}(x)=0 f0(x)=0
- 对m = 1,2,…,M:
- (a) 极小化损失函数:
( β m , γ m ) = arg min β , γ ∑ i = 1 N L ( y i , f m − 1 ( x i ) + β b ( x i ; γ ) ) \left(\beta_{m}, \gamma_{m}\right)=\arg \min _{\beta, \gamma} \sum_{i=1}^{N} L\left(y_{i}, f_{m-1}\left(x_{i}\right)+\beta b\left(x_{i} ; \gamma\right)\right) (βm,γm)=argβ,γmini=1∑NL(yi,fm−1(xi)+βb(xi;γ))
得到参数 β m \beta_{m} βm与 γ m \gamma_{m} γm- (b) 更新:
f m ( x ) = f m − 1 ( x ) + β m b ( x ; γ m ) f_{m}(x)=f_{m-1}(x)+\beta_{m} b\left(x ; \gamma_{m}\right) fm(x)=fm−1(x)+βmb(x;γm)- 得到加法模型: f ( x ) = f M ( x ) = ∑ m = 1 M β m b ( x ; γ m ) f(x)=f_{M}(x)=\sum_{m=1}^{M} \beta_{m} b\left(x ; \gamma_{m}\right) f(x)=fM(x)=m=1∑Mβmb(x;γm)
这样,前向分步算法将同时求解从m=1到M的所有参数 β m \beta_{m} βm, γ m \gamma_{m} γm的优化问题简化为逐次求解各个 β m \beta_{m} βm, γ m \gamma_{m} γm的问题。
1.3 前向分步算法与Adaboost的关系
二、梯度提升决策树(GBDT)
2.1 基于残差学习的提升树算法
2.1.1 基于残差学习的提升树算法原理介绍
使用加法模型+前向分步算法框架,以决策树分类器为基函数,以残差为评判拟合程度指标,解决回归问题。
问题1: 为什么采用残差(平方误差)作为分类指标?
答: 回归树中的样本标签是连续值,再使用分类树中熵之类的指标不合适,故使用平方误差来评判拟合程度。
问题2: 提升的标准是什么?(前向分步算法中更新学习器 f ( x ) f(x) f(x)的依据)
答: 模仿Adaboost中的分类误差率,使用每个样本的残差表示每次使用基函数预测时没有解决的那部分问题。
算法推导:
输入数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } , x i ∈ X ⊆ R n , y i ∈ Y ⊆ R T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\}, x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n}, y_{i} \in \mathcal{Y} \subseteq \mathbf{R} T={(x1,y1),(x2,y2),⋯,(xN,yN)},xi∈X⊆Rn,yi∈Y⊆R,输出最终的提升树 f M ( x ) f_{M}(x) fM(x)
- 初始化 f 0 ( x ) = 0 f_0(x) = 0 f0(x)=0
- 对m = 1,2,…,M:(利用学习器 f m − 1 ( x ) f_{m-1}(x) fm−1(x)的预测值,计算第m次的残差 r m i r_{mi} rmi,并使用该残差估计学习器 f m ( x ) f_m(x) fm(x),此处的学习器指回归树)。
- 计算每个样本的残差: r m i = y i − f m − 1 ( x i ) , i = 1 , 2 , ⋯ , N r_{m i}=y_{i}-f_{m-1}\left(x_{i}\right), \quad i=1,2, \cdots, N rmi=yi−fm−1(xi),i=1,2,⋯,N
- 拟合残差 r m i r_{mi} rmi学习一棵回归树,得到 T ( x ; Θ m ) T\left(x ; \Theta_{m}\right) T(x;Θm)
- 更新 f m ( x ) = f m − 1 ( x ) + T ( x ; Θ m ) f_{m}(x)=f_{m-1}(x)+T\left(x ; \Theta_{m}\right) fm(x)=fm−1(x)+T(x;Θm)
- 得到最终的回归问题的提升树: f M ( x ) = ∑ m = 1 M T ( x ; Θ m ) f_{M}(x)=\sum_{m=1}^{M} T\left(x ; \Theta_{m}\right) fM(x)=∑m=1MT(x;Θm)
2.1.2 基于残差学习的提升树算法-实际案例计算
有时间再手写补充
2.2 梯度提升决策树算法(GBDT)
梯度提升决策树算法(GBDT)是利用最速下降法的近似方法,也就是利用损失函数的负梯度在当前模型的值 − [ ∂ L ( y , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) -\left[\frac{\partial L\left(y, f\left(x_{i}\right)\right)}{\partial f\left(x_{i}\right)}\right]_{f(x)=f_{m-1}(x)} −[∂f(xi)∂L(y,f(xi))]f(x)=fm−1(x)作为回归问题提升树算法中的残差的近似值,拟合回归树。
解决的问题:
提升树算法只有在损失函数为平方损失和指数损失时每一步的优化是简单的,故需要解决一般的损失函数每一步的优化并不容易的问题。
2.2.1 梯度提升决策树算法(GBDT)原理
输入训练数据集 T = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , ⋯ , ( x N , y N ) } , x i ∈ X ⊆ R n , y i ∈ Y ⊆ R T=\left\{\left(x_{1}, y_{1}\right),\left(x_{2}, y_{2}\right), \cdots,\left(x_{N}, y_{N}\right)\right\}, x_{i} \in \mathcal{X} \subseteq \mathbf{R}^{n}, y_{i} \in \mathcal{Y} \subseteq \mathbf{R} T={(x1,y1),(x2,y2),⋯,(xN,yN)},xi∈X⊆Rn,yi∈Y⊆R和损失函数 L ( y , f ( x ) ) L(y, f(x)) L(y,f(x)),输出回归树 f ^ ( x ) \hat{f}(x) f^(x)。( c m j c_{mj} cmj为使得损失最小时学习器的参数, c c c为常数)。
- 初始化 f 0 ( x ) = arg min c ∑ i = 1 N L ( y i , c ) f_{0}(x)=\arg \min _{c} \sum_{i=1}^{N} L\left(y_{i}, c\right) f0(x)=argminc∑i=1NL(yi,c)
- 对于m=1,2,…,M:
对i = 1,2,…,N计算: r m i = − [ ∂ L ( y i , f ( x i ) ) ∂ f ( x i ) ] f ( x ) = f m − 1 ( x ) r_{m i}=-\left[\frac{\partial L\left(y_{i}, f\left(x_{i}\right)\right)}{\partial f\left(x_{i}\right)}\right]_{f(x)=f_{m-1}(x)} rmi=−[∂f(xi)∂L(yi,f(xi))]f(x)=fm−1(x)
对 r m i r_{mi} rmi拟合一个回归树,得到第m棵树的叶结点区域 R m j , j = 1 , 2 , ⋯ , J R_{m j}, j=1,2, \cdots, J Rmj,j=1,2,⋯,J
对j=1,2,…J,计算: c m j = arg min c ∑ x i ∈ R m j L ( y i , f m − 1 ( x i ) + c ) c_{m j}=\arg \min _{c} \sum_{x_{i} \in R_{m j}} L\left(y_{i}, f_{m-1}\left(x_{i}\right)+c\right) cmj=argminc∑xi∈RmjL(yi,fm−1(xi)+c) (这一部分没看懂)
更新 f m ( x ) = f m − 1 ( x ) + ∑ j = 1 J c m j I ( x ∈ R m j ) f_{m}(x)=f_{m-1}(x)+\sum_{j=1}^{J} c_{m j} I\left(x \in R_{m j}\right) fm(x)=fm−1(x)+∑j=1JcmjI(x∈Rmj)
- 得到回归树: f ^ ( x ) = f M ( x ) = ∑ m = 1 M ∑ j = 1 J c m j I ( x ∈ R m j ) \hat{f}(x)=f_{M}(x)=\sum_{m=1}^{M} \sum_{j=1}^{J} c_{m j} I\left(x \in R_{m j}\right) f^(x)=fM(x)=∑m=1M∑j=1JcmjI(x∈Rmj)
2.2.2 梯度提升决策树算法(GBDT)-实际案例计算
有时间再手写补充
2.3 GBDT代码实例介绍(sklearn库)
2.3.1 GradientBoostingRegressor参数介绍
GradientBoostingRegressor参数解释:
loss:{‘ls’, ‘lad’, ‘huber’, ‘quantile’}, default=’ls’:‘ls’ 指最小二乘回归. ‘lad’ (最小绝对偏差)是仅基于输入变量的顺序信息的高度鲁棒的损失函数。. ‘huber’ 是两者的结合.‘quantile’允许分位数回归(用于alpha指定分位数)
learning_rate: 学习率缩小了每棵树的贡献learning_rate。在learning_rate和 n_estimators之间需要权衡。
n_estimators: 要执行的提升次数。
subsample: 指定采样出 subsample * n_samples 个样本用于训练弱学习器。此处非放回采样。
criterion: {‘friedman_mse’,‘mse’,‘mae’},默认=‘friedman_mse’:“mse”是均方误差,“ mae”是平均绝对误差。默认值“ friedman_mse”通常是最好的,因为在某些情况下它可以提供更好的近似值。
max_depth: 各个回归模型的最大深度。最大深度限制了树中节点的数量。调整此参数以获得最佳性能;最佳值取决于输入变量的相互作用。
min_samples_leaf: 在叶节点处需要的最小样本数。
min_impurity_split: 提前停止树木生长的阈值。如果节点的杂质高于阈值,则该节点将分裂
max_features{‘auto’, ‘sqrt’, ‘log2’},int或float: 寻找最佳分割时要考虑的功能数量:
- 如果为int,则max_features在每个分割处考虑特征。
- 如果为float,max_features则为小数,并 在每次拆分时考虑要素。int(max_features * n_features)
- 如果“auto”,则max_features=n_features。
- 如果是“ sqrt”,则max_features=sqrt(n_features)。
- 如果为“ log2”,则为max_features=log2(n_features)。
- 如果没有,则max_features=n_features。
2.3.2 GradientBoostingClassifier参数介绍
GradientBoostingClassifier参数解释:
参数:
loss:{‘deviance’, ‘exponential’}, default=’deviance’,‘deviance’:对数损失函数;‘exponential’:指数损失函数,只能用于二分类。
subsample: 指定采样出 subsample * n_samples 个样本用于训练弱学习器。此处非放回采样。
learning_rate: 学习率缩小了每棵树的贡献learning_rate。在learning_rate和 n_estimators之间需要权衡。
n_estimators: 数值型参数,默认值为100,指定弱分类器的个数。
criterion: 字符串类型,默认值为 ‘gini’。‘entropy’,使用基于信息熵的方法,即计算信息增益;‘gini’,使用基尼系数。
max_depth: 数值型,默认值3。最大深度限制了树中节点的数量。调整此参数以获得最佳性能;最佳值取决于输入变量的相互作用。
min_samples_leaf: 在叶节点处需要的最小样本数。此参数设置的过小会导致过拟合,反之就会欠拟合。
min_samples_split: 拆分内部节点所需的最少样本数。数值型,默认值2,指定每个内部节点(非叶子节点)包含的最少的样本数。与min_samples_leaf这个参数类似,可以是整数也可以是浮点数。
min_impurity_split: 提前停止树木生长的阈值。如果节点的杂质高于阈值,则该节点将分裂
max_features{‘auto’, ‘sqrt’, ‘log2’},int或float: 寻找最佳分割时要考虑的功能数量:
- 如果为int,则max_features在每个分割处考虑特征。
- 如果为float,max_features则为小数,并 在每次拆分时考虑要素。int(max_features * n_features)
- 如果“auto”,则max_features=n_features。
- 如果是“ sqrt”,则max_features=sqrt(n_features)。
- 如果为“ log2”,则为max_features=log2(n_features)。
- 如果没有,则max_features=n_features。
属性:
feature_importances_ : 各个特征对模型的重要性。
estimators_: 一个数组,给出每个弱学习器。方法:
fit(X, y) : 训练模型。
predict(X) : 用模型预测,返回预测值。
predict_proba(X) : 返回数组,数组元素依次为各个样本属于各个类别的概率值。
score(X, y) : 返回在(X, y)上预测的准确率(accuracy)。
参考文献:sklearn中GBDT的一些参数、属性、方法的理解
2.3.3 GradientBoostingRegressor代码实例(基于sklearn)
from sklearn.metrics import mean_squared_error
from sklearn.datasets import make_friedman1
from sklearn.ensemble import GradientBoostingRegressor
X, y = make_friedman1(n_samples=1200, random_state=0, noise=1.0)
X_train, X_test = X[:200], X[200:]
y_train, y_test = y[:200], y[200:]
est = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1,
max_depth=1, random_state=0, loss='ls').fit(X_train, y_train)
print("均方误差:",mean_squared_error(y_test, est.predict(X_test)))
from sklearn.datasets import make_regression
from sklearn.model_selection import train_test_split
X, y = make_regression(random_state=0)
X_train, X_test, y_train, y_test = train_test_split(
X, y, random_state=0)
reg = GradientBoostingRegressor(random_state=0)
reg.fit(X_train, y_train)
print("准确率:",reg.score(X_test, y_test))
2.3.2 GradientBoostingClassifier代码实例(基于sklearn)
from sklearn import datasets
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn import datasets # 导入库
cancer = datasets.load_breast_cancer() # 导入乳腺癌数据
X = cancer.data
y = cancer.target
#划分数据集
X_train, X_test, y_train, y_test = train_test_split(
X, y, random_state=0)
#GBDT分类树
clf = GradientBoostingClassifier()
clf.fit(X_train,y_train)
print("准确率",clf.score(X_test,y_test))