用通俗易懂的方式讲解: GBDT算法及案例(Python 代码)

1 GBDT算法核心思想

GBDT是Gradient Boosting Decision Tree(梯度提升树)的缩写。

GBDT算法也是一种非常实用的Boosting算法,它与AdaBoost算法的区别在于:AdaBoost算法根据分类效果调整权重并不断迭代,最终生成强学习器;GBDT算法则将损失函数的负梯度作为残差的近似值,不断使用残差迭代和拟合回归树,最终生成强学习器。

简单来说,AdaBoost算法是调整权重,而GBDT算法则是拟合残差。通过一个简单案例理解GBDT算法的核心思想。

下表中有4个样本客户的数据,特征变量X1为年龄,X2为月收入(元),目标变量y是实际信用卡额度(元)。现在要利用GBDT算法根据样本数据构造模型,用于预测信用卡额度。
在这里插入图片描述

假设建立的第1棵决策树如下图所示。

在这里插入图片描述

A、C被划分到左节点,A的实际信用卡额度为8000,而预测值为10000,因此,A的残差为8000-10000=-2000,同理,C的残差为25000-20000=5000。B、D被划分到右节点,B的残差为30000-35000=-5000,D的残差为40000-35000=5000。

接下来就是GBDT算法的核心思想:构造第2棵决策树来拟合第1棵树产生的残差,注意这里拟合的是残差,构造的拟合残差的决策树如下图所示。
在这里插入图片描述

在这棵树中,A、B被划分到左节点,A的实际残差为-2000,而预测的残差为-3000,那么此时A的新残差,即残差的残差为-2000-(-3000)=1000,同理,B的新残差为-5000-(-5000)=0。C、D被划分到右节点,C的新残差为5000-5000=0,D的新残差为5000-5000=0。继续用第2棵树产生的新残差去拟合第3棵树,并不断重复此步骤,使残差变小。

因此,最终的模型就是如下图所示的集成在一起的多个模型,这也充分体现了集成算法的集成思想。

在这里插入图片描述

2 GBDT算法的数学原理

简单介绍GBDT算法的数学原理。迭代模型为:

在这里插入图片描述

  • fm-1(x)是第m-1次迭代模型,即上一次的迭代模型;

  • Tm(x)是本次待搭建的决策树,其实也是拟合上一个模型残差值的决策树;

  • fm(x)是本次迭代后产生的新模型。

对GBDT算法来说,只需要简单地拟合当前模型的残差,算法步骤如下。

  • 步骤1:初始化f0(x)=0

  • 步骤2:当m=1,2,…,M,计算残差rmi=yi-fm-1(x);拟合残差,得到决策树Tm(x);更新fm(x)=fm-1(x)+Tm(x)。

  • 步骤3:当误差或迭代次数达到指定要求时,得到回归问题提升树,如下所示。

在这里插入图片描述

3 GBDT算法数学原理举例

结合具体的回归问题,详细讲解GBDT算法的数学计算步骤。给定的训练数据见下表,其中x为特征变量,y为目标变量,因为y为连续值,所以这是一个回归预测问题。

在这里插入图片描述

1.构造第一个模型

首先初始化f0(x)=0,然后构造第1个回归决策树模型f1(x),其实也就是T1(x)。

回归决策树模型的划分标准。回归决策树模型与分类决策树模型最大的不同就是其划分标准不是信息熵或基尼系数,而是均方误差MSE,其计算公式如下。

在这里插入图片描述

(1)寻找合适的初始切分点

构造第1棵决策树时,我们需要判断在x=1.5、x=2.5、x=3.5、x=4.5这4个位置中的哪个位置“切一刀”,才能使整体的均方误差MSE最小。

先在x=1.5处“切一刀”划分类别,即设置阈值v=1.5,意味着弱学习器f1(x)如下。
在这里插入图片描述

其实这就是如下图所示的一棵深度为1的回归决策树。

回归决策树中某个节点的预测值是该节点中所有数据的均值,因此,在上图右边的节点中,所有满足x>1.5的值都被预测为(0+2+2+4)/4=2。

此时的残差yi-f(xi)见下表。

在这里插入图片描述

此时的均方误差MSE为:

在这里插入图片描述

仿照上面的方法,计算出4种阈值下的均方误差MSE,见下表。

在这里插入图片描述

由上表可知,当v=2.5时均方误差MSE取得最小值,此时第1棵决策树f1(x)如下图所示。

在这里插入图片描述

(2)查看此时的残差

前面已经求得了第1棵决策树f1(x),因此可以获得其对应的残差,见下表。

在这里插入图片描述

获得残差之后,接着就需要构建新的决策树来拟合残差,此时整个系统的均方误差MSE为0.53。

2.拟合残差获得第2个模型

现在需要根据下表中的**x(特征变量)和残差(目标变量)**拟合出决策树T2(x)。

注意:此时第二棵树的实际值y为上一棵树的残差值。

在这里插入图片描述

(1)寻找合适的初始切分点

使用与前面相同的计算方法计算出4种阈值下的均方误差MSE,见下表。

在这里插入图片描述

由上表可知,当v=4.5时均方误差MSE取得最小值,此时第2棵决策树T2(x)如下图所示。

在这里插入图片描述

(2)查看此时的残差

此时残差的预测值T(x)及残差的残差(残差-T(x))见下表

在这里插入图片描述

注意上表中“残差的残差”即系统的残差,此时该拟合残差的决策树的均方误差MSE为0.088,这也是整个系统的均方误差MSE。

(3)集成模型

此时的集成模型f2(x)如下。

在这里插入图片描述

或者:

在这里插入图片描述

有了新模型的残差后,便可以继续构造新的决策树来拟合残差,直到系统的均方误差MSE达到指定要求或者迭代次数达到指定条件时,便停止迭代,形成最终模型。最终模型如下图所示。

在这里插入图片描述

因为GBDT算法是不停地拟合新模型的残差,所以随着新的迭代,整个系统的残差会越来越小,或者更精确地说,系统的均方误差MSE会越来越小,从而使得模型更加准确。

梯度提升树中梯度的理解

之前定义的残差为y-f(xi),而实际应用中,GBDT(Gradient Boosting DecisionTree)梯度提升树使用损失函数的负梯度在当前模型的值作为残差近似值。负梯度的定义如下,其中L(y,f(xi))为损失函数。

在这里插入图片描述

其实这个负梯度在特定损失函数的情况下,就是之前定义的残差y-f(xi),令损失函数为:

在这里插入图片描述

此时对损失函数求负梯度:

在这里插入图片描述

此时负梯度就等于残差y-f(xi),也就是说,当损失函数是平方函数时,负梯度就是残差。

不过当损失函数不是平方函数时,负梯度只是残差的近似值,并不完全等于残差。

4 使用sklearn实现GBDT算法

GBDT算法既能做分类分析,又能做回归分析。对应的模型分别为GBDT分类模型(GradientBoostingClassifier)和GBDT回归模型(GradientBoostingRegressor)。

GBDT分类模型的弱学习器是分类决策树模型,GBDT回归模型的弱学习器则是回归决策树模型。

代码如下:

# GBDT分类模型
from sklearn.ensemble import GradientBoostingRegressor
X = [[1,2],[3,4],[5,6],[7,8],[9,10]]
y = [1,2,3,4,5]
model = GradientBoostingRegressor(random_state=123)
model.fit(X,y)
model.predict([[5,5]])

# 输出
# array([2.54911351])

5 案例:产品定价模型

5.1 模型搭建

5.1.1 读取数据

首先读取1000种图书的数据,这里为了方便演示,只选取了4个特征变量,包括图书的页数、类别、彩印和纸张,目标变量是图书的价格。

在这里插入图片描述

查看图书类别以及纸张分类情况:

在这里插入图片描述

5.1.2 分类型文本变量的处理

因为“类别”和“纸张”两列是分类型文本变量,所以可以用LabelEncoder()函数进行数值化处理,便于后续进行模型拟合。

在这里插入图片描述

可以看到,“类别”列中的“技术类”被转换为数字1,“教辅类”被转换为数字2,“办公类”被转换为数字0。

在这里插入图片描述

此时df的前5行见下表。

在这里插入图片描述

5.1.3 提取特征变量和目标变量

在这里插入图片描述

5.1.4 划分训练集的测试集

from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=123)

5.1.5 模型训练及搭建

在这里插入图片描述

5.2 模型预测及评估

模型搭建完毕后,就可以对测试集数据进行预测,代码如下。

在这里插入图片描述

通过如下代码汇总预测值和实际值,以便进行对比。

在这里插入图片描述

用模型自带的score()函数查看模型的预测效果,代码如下。

在这里插入图片描述

获得的模型准确度评分score为0.874,说明模型的预测效果不错。

也可以通过如下代码查看模型的R-squared值,来评估模型的拟合程度。

在这里插入图片描述

为了更科学合理地进行产品定价,可以通过如下代码查看各个特征变量的特征重要性,以便筛选出对价格影响最大的特征变量。

在这里插入图片描述

6 模型参数介绍

GBDT回归模型参数,更多查看可以在Jupyter Notebook中输入并运行如下代码:

from sklearn.ensemble import GradientBoostingRegressor
GradientBoostingRegressor ?

在这里插入图片描述

知识拓展

猜你喜欢

转载自blog.csdn.net/qq_34160248/article/details/127171043
今日推荐