详解机器学习经典模型(原理及应用)——GBDT

一、什么是GBDT

        梯度提升决策树(Gradient Boosting Decision Tree, GBDT)是一种集成学习算法,它通过迭代地训练决策树来最小化损失函数,从而提高模型的预测性能。GBDT的核心思想是将多个弱学习器(通常是决策树)的结果累加起来,形成强学习器,即Boosting。与随机森林相同,弱学习器可以是分类树也可以是回归树(有的观点说GBDT只能由回归树构成,这可能是由于GBDT通常使用回归树解决问题从而给人造成了误解,实际上分类指标同样能够用来计算负梯度,具体使用的是回归树还是分类树,主要看损失函数的构造以及任务的目标值类型)。

二、GBDT算法原理

        GBDT的工作原理如下:

1、初始化

        首先,GBDT使用一个初始预测器(通常是一个常数值)对所有样本进行预测。

2、迭代训练

        在每次迭代中,GBDT会计算损失函数的负梯度,这个负梯度将作为残差,用于训练下一棵决策树。损失函数的负梯度可以被视为当前模型预测值与真实值之间差异的度量。对于不同的损失函数,负梯度的计算方式也会有所不同。例如,对于均方误差损失函数(回归问题),负梯度的计算公式为:

r_{ti} = -\left [ \frac{\partial L(y_{i},f(x_{i}))}{\partial f(x_{i})} \right ]_{f(x)=f_{t-1}(x)}=y_{i}-f_{t-1}(x_{i})

        其中,r_{ti}是第t轮迭代中第i个样本的残差,y_{i}是真实值,f_{t-1}(x_{i})是前一轮迭代的预测值。

3、更新模型

        在每次迭代中,新的决策树被添加到模型中,模型的预测值更新为:

\hat{y_{i}}^{(t+1)} = \hat{y_{i}}^{(t)}-\eta h_{t}(x_{i})

        其中h_{t}(x_{i})是第t轮迭代中训练的决策树对样本x_{i}的预测值。\eta是学习率。而对于每一颗决策树(即弱学习器),有:

h_{t}(x) = argmin_{h}\sum_{i=1}^{n}L(y_{i}, \hat{y}_{i}^{(t)}+h (x_{i}))

        这里,h为决策树模型,L是损失函数。

4、终止条件

        最终的GBDT模型是所有弱学习器的加权和:

\hat{y}(x) = \hat{y}^{(0)}+\sum_{t-1}^{T}\eta _{t}\times \alpha_{t} \times h_{t}(x)

        其中,T是迭代次数,\hat{y}^{(0)}是初始预测值,\alpha_{t}是第t轮迭代中决策树的权重(通常与当前决策树的复杂度成反比)。当达到预设的迭代次数或模型性能不再显著提升时,GBDT停止迭代。

三、梯度提升与梯度下降

        梯度下降是一种优化算法,用于最小化损失函数。它通过计算损失函数相对于模型参数的梯度(即损失函数在参数空间中的斜率),然后沿着梯度的反方向更新参数,以此减小损失函数的值。

        梯度提升是一种集成学习算法,“提升”指的是通过添加一个新的弱学习器迭代改进模型的方法),以此来最小化损失函数。在每一步迭代中,梯度提升算法计算当前模型的残差(即损失函数的负梯度),然后将一个新的弱学习器拟合到这些残差上。这个过程可以看作是在每一步迭代中,模型都在尝试修正前一步的预测误差。

        两者都是在每一轮迭代中,利用损失函数相对于模型的负梯度方向的信息来对当前模型进行更新,只不过在梯度下降中直接使用损失函数的负梯度来更新参数,而在梯度提升中使用损失函数的负梯度作为残差的近似值,而不是直接用于更新参数。

四、GBDT应用

1、分类

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import accuracy_score

# 加载数据集
iris = load_iris()
X, y = iris.data, iris.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建GBDT分类器
gbdt_clf = GradientBoostingClassifier(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)

# 训练模型
gbdt_clf.fit(X_train, y_train)

# 预测测试集
y_pred = gbdt_clf.predict(X_test)

# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.2f}")

2、回归

from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.metrics import mean_squared_error

# 加载波士顿房价数据集
boston = load_boston()
X, y = boston.data, boston.target

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建GBDT回归器
gbdt_reg = GradientBoostingRegressor(n_estimators=100, learning_rate=0.1, max_depth=3, random_state=42)

# 训练模型
gbdt_reg.fit(X_train, y_train)

# 预测测试集
y_pred = gbdt_reg.predict(X_test)

# 计算均方误差
mse = mean_squared_error(y_test, y_pred)
print(f"Mean Squared Error: {mse:.2f}")

# 计算R^2分数
r2_score = gbdt_reg.score(X_test, y_test)
print(f"R^2 Score: {r2_score:.2f}")

五、总结

        虽然实际业务工作中,考虑GBDT模型的时候我们基本都会使用其工程优化版本——XGBoost以及LightGBM,但它仍然是值得深入学习的经典机器学习模型之一。以下是GBDT的一些优缺点:

1、优点

        (1)高准确性:GBDT能够处理高维度、稀疏特征以及非线性关系等复杂问题,因此在训练集和测试集上都表现良好。

        (2)强大的泛化能力:通过组合多个弱分类器形成一个强分类器,减少了过拟合的风险。

        (3)对缺失值的鲁棒性:GBDT能够自动处理缺失值,无需额外的处理步骤。

        (4)可并行化的预测阶段:虽然训练过程是串行的,但预测时可以并行计算,提高了预测速度。

2、缺点

        (1)训练时间较长:GBDT是串行算法,需要按顺序构建每棵决策树,因此训练时间较长。

        (2)对异常值敏感:GBDT在训练过程中容易受到异常值的影响,可能导致模型性能下降。

        (3)无法并行化训练:GBDT的训练过程无法并行化,工程加速只能体现在单颗树构建过程中。

### 帆软面试题及相关准备 帆软是一家专注于商业智能和数据分析领域的企业,其产品主要包括 FineReport 和 FineBI。以下是关于帆软相关的面试问题及其解答。 #### 1. 维度建模的核心理念 维度建模是一种面向分析型数据库的设计方法,旨在支持高效的多维数据分析。它从用户的实际分析需求出发,构建易于理解的数据模型,从而帮助用户快速完成复杂的业务分析[^1]。 - **特点**: 数据仓库中的维度建模通常涉及大量数据预处理和冗余存储,以优化查询性能并减少计算开销。 - **目标**: 提供直观的业务视图,便于发现潜在的业务问题。 #### 2. HTTP 请求方式的区别 HTTP 协议定义了几种常见的请求方法,包括 GET、POST、DELETE 和 PUT 等。这些方法各有用途,适用于不同的场景[^2]: - **GET**: 获取资源,不应改变服务器状态,适合用于读取数据。 - **POST**: 发送数据至服务器,可能引发副作用(如创建新记录)。 - **PUT**: 替换指定资源的内容,通常是幂等操作。 - **DELETE**: 删除指定资源。 此外,重定向与转发也存在显著差异: - **重定向**: 浏览器发起新的请求,地址栏会发生变化,可能导致数据丢失。 - **转发**: 在服务器内部完成跳转,客户端感知不到具体过程,地址栏保持不变。 #### 3. Spring Boot 打包机制 Spring Boot 应用程序可以通过 Maven 插件轻松打包为可执行 JAR 文件。命令如下: ```bash mvn clean package ``` 此命令会清理旧版本的项目包,并重新生成最新的 JAR 文件[^3]。需要注意的是,Spring Boot 的 JAR 结构特殊,无法像传统 JAR 那样被其他项目直接依赖。 #### 4. 外部链接属性的关键字 在 C/C++ 编程中,`extern` 和 `static` 关键字分别表示变量或函数的作用域特性[^4]: - **extern**: 表明该对象具有外部链接属性,可在多个源文件间共享。 - **static**: 断绝外部链接关系,仅限于当前编译单元内使用。 #### 5. 数据结构基础——堆栈与队列 堆栈和队列是两种基本的数据结构形式,它们的主要区别在于存取顺序: - **堆栈 (Stack)**: 先进后出 (FILO),所有操作均发生在顶部位置。 - **队列 (Queue)**: 先进先出 (FIFO),插入位于尾端,移除则发生于前端。 --- ### 示例代码:FineReport 报告设计模板 以下是一个简单的 FineReport 设计脚本示例,展示如何动态加载数据集: ```java // 定义数据集名称 String datasetName = "SalesData"; // 设置过滤条件 Map<String, Object> params = new HashMap<>(); params.put("year", 2023); params.put("region", "North"); // 加载报表模板 FRDesigner.loadTemplate("template.cpt"); FRDesigner.setDatasetParameters(datasetName, params); // 输出结果 System.out.println(FRDesigner.renderHTML()); ``` 上述代码片段展示了如何利用参数化查询功能定制报表内容。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值