3.2 目标函数 (Objective Functions)


文档摘要

3.2 目标函数 (Objective Functions) LightGBM 参数详解:3.2 目标函数 (Objective Functions) 在梯度提升框架(Gradient Boosting Framework)如 LightGBM 中,目标函数 (Objective Function) 是模型学习的核心驱动力。它定义了模型需要优化的目标,指导模型如何调整自身参数以更好地拟合数据,最终实现预测任务。目标函数的选择直接影响模型的性能、训练速度以及泛化能力。 3.2.1 目标函数的核心概念 目标函数,也称为损失函数 (Loss Function) 或代价函数 (Cost Function),在机器学习中扮演着至关重要的角色。

3.2 目标函数 (Objective Functions)

LightGBM 参数详解:3.2 目标函数 (Objective Functions)

在梯度提升框架(Gradient Boosting Framework)如 LightGBM 中,目标函数 (Objective Function) 是模型学习的核心驱动力。它定义了模型需要优化的目标,指导模型如何调整自身参数以更好地拟合数据,最终实现预测任务。目标函数的选择直接影响模型的性能、训练速度以及泛化能力。

3.2.1 目标函数的核心概念

目标函数,也称为损失函数 (Loss Function) 或代价函数 (Cost Function),在机器学习中扮演着至关重要的角色。对于监督学习算法,特别是梯度提升机,目标函数主要完成以下任务:

  1. 衡量预测值与真实值之间的差距:目标函数量化了模型预测结果与实际观测值之间的差异程度。这种差异通常被称为“损失”或“误差”。

  2. 指导模型优化方向:在训练过程中,优化算法(如梯度下降)会根据目标函数的梯度信息来调整模型参数,目标是最小化(或最大化)目标函数的值,从而使模型的预测结果更接近真实值。

  3. 定义学习任务类型:不同的目标函数适用于不同的机器学习任务。例如,回归任务通常使用均方误差 (Mean Squared Error, MSE),而分类任务则常用交叉熵损失 (Cross-Entropy Loss)。

在 LightGBM 中,目标函数通过 objective 参数进行设置。LightGBM 内置了多种常用的目标函数,同时也支持用户自定义目标函数以满足特定需求。

3.2.2 LightGBM 内置目标函数详解与代码实践

LightGBM 提供了丰富的内置目标函数,涵盖了回归、二分类、多分类以及排序等多种常见的机器学习任务。下面我们将分类详解这些内置目标函数,并结合代码示例进行演示。

3.2.2.1 回归 (Regression) 目标函数

回归任务的目标是预测连续数值型的目标变量。LightGBM 提供了多种适用于回归任务的目标函数:

1. L2 损失 (L2 Loss / Mean Squared Error, MSE) - objective="l2", objective="regression"
  • 公式L(y, \hat{y}) = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2

    • y_i:第 i 个样本的真实值

    • \hat{y}_i:第 i 个样本的模型预测值

    • n:样本总数

  • 特点

    • 平方误差:L2 损失计算预测值与真实值之差的平方,对误差进行平方放大会放大较大误差的影响,使得模型更关注减少大误差。

    • 光滑可导:L2 损失函数光滑且处处可导,便于梯度优化。

    • 对异常值敏感:由于平方操作,L2 损失对异常值非常敏感,异常值会显著增加损失值,可能导致模型向异常值方向偏移。

  • 适用场景

    • 适用于目标变量服从正态分布,且对异常值不敏感的场景。

    • 是回归任务中最常用的目标函数之一。

  • 代码实践 (Python)

import lightgbm as lgb from sklearn.model_selection import train_test_split from sklearn.datasets import make_regression from sklearn.metrics import mean_squared_error # 1. 生成回归数据集 X, y = make_regression(n_samples=1000, n_features=10, noise=0.1, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 2. LightGBM 数据集 lgb_train = lgb.Dataset(X_train, y_train) lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train) # 3. 设置参数 - 使用 L2 损失 params_l2 = { 'objective': 'l2', # 或 'regression' 'metric': 'l2', # 或 'mse' 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9 } # 4. 训练模型 (L2 损失) gbm_l2 = lgb.train(params_l2, lgb_train, num_boost_round=100, valid_sets=lgb_eval, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_l2 = gbm_l2.predict(X_test, num_iteration=gbm_l2.best_iteration) mse_l2 = mean_squared_error(y_test, y_pred_l2) print(f"L2 Loss MSE: {mse_l2:.4f}")
2. L1 损失 (L1 Loss / Mean Absolute Error, MAE) - objective="l1", objective="mae", objective="regression_l1"
  • 公式L(y, \hat{y}) = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|

  • 特点

    • 绝对误差:L1 损失计算预测值与真实值之差的绝对值。

    • 对异常值鲁棒:与 L2 损失相比,L1 损失对异常值不敏感,因为绝对值函数不会像平方函数那样放大异常值的影响。

    • 非光滑:在零点处不可导,可能影响优化过程的收敛速度,但实际应用中通常影响不大。

    • 预测结果更接近中位数:使用 L1 损失训练的模型,其预测结果更倾向于接近训练集中目标变量的中位数。

  • 适用场景

    • 适用于数据集中存在较多异常值,或者希望模型对异常值不敏感的场景。

    • 当关注预测误差的绝对值大小时,L1 损失是一个合适的选择。

  • 代码实践 (Python)

# ... (数据集和数据准备代码与 L2 损失示例相同) ... # 3. 设置参数 - 使用 L1 损失 params_l1 = { 'objective': 'l1', # 或 'mae' 或 'regression_l1' 'metric': 'l1', # 或 'mae' 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9 } # 4. 训练模型 (L1 损失) gbm_l1 = lgb.train(params_l1, lgb_train, num_boost_round=100, valid_sets=lgb_eval, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_l1 = gbm_l1.predict(X_test, num_iteration=gbm_l1.best_iteration) mae_l1 = mean_absolute_error(y_test, y_pred_l1) # 注意评估指标也应使用 MAE print(f"L1 Loss MAE: {mae_l1:.4f}")
3. Huber 损失 - objective="huber"
  • 公式:Huber 损失是介于 L1 损失和 L2 损失之间的一种损失函数。它使用一个阈值 \delta 来控制损失函数的行为。

    $L_{\delta}(y, \hat{y}) = \begin{cases}

    \frac{1}{2}(y - \hat{y})^2 & \text{for } |y - \hat{y}| \le \delta \

    \delta|y - \hat{y}| - \frac{1}{2}\delta^2 & \text{for } |y - \hat{y}| > \delta

    \end{cases}$

  • 特点

    • 结合 L1 和 L2 的优点:当误差较小时(小于 \delta),Huber 损失类似于 L2 损失,具有光滑性和良好的导数特性;当误差较大时(大于 \delta),Huber 损失类似于 L1 损失,对异常值不敏感。

    • 参数可调\delta 是 Huber 损失的超参数,控制着损失函数从 L2 向 L1 过渡的阈值。较小的 \delta 值使得 Huber 损失更接近 L2 损失,反之则更接近 L1 损失。

    • 对异常值相对鲁棒:相比 L2 损失,Huber 损失对异常值更鲁棒,但又不像 L1 损失那样完全忽略异常值的影响。

  • 适用场景

    • 适用于数据集中可能存在异常值,但又希望在误差较小时保持 L2 损失的光滑性和优化特性的场景。

    • 需要平衡模型对异常值的鲁棒性和对正常数据的拟合能力时,Huber 损失是一个不错的选择。

  • 代码实践 (Python)

# ... (数据集和数据准备代码与 L2 损失示例相同) ... # 3. 设置参数 - 使用 Huber 损失 params_huber = { 'objective': 'huber', 'metric': 'l2', # 或其他回归指标 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9, 'huber_delta': 1.0 # 可选参数,调整 delta 值,默认 1.0 } # 4. 训练模型 (Huber 损失) gbm_huber = lgb.train(params_huber, lgb_train, num_boost_round=100, valid_sets=lgb_eval, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_huber = gbm_huber.predict(X_test, num_iteration=gbm_huber.best_iteration) mse_huber = mean_squared_error(y_test, y_pred_huber) print(f"Huber Loss MSE: {mse_huber:.4f}")
4. Fair 损失 - objective="fair"
  • 公式:Fair 损失也是一种对异常值鲁棒的损失函数,其形式如下:

    L_c(y, \hat{y}) = c^2 \left( \frac{|y - \hat{y}|}{c} - \ln\left(1 + \frac{|y - \hat{y}|}{c}\right) \right)

  • 特点

    • 参数 c 控制鲁棒性:参数 c 决定了 Fair 损失对异常值的敏感程度。c 值越大,损失函数对大误差越不敏感,鲁棒性越强。

    • 渐近线性:当误差 |y - \hat{y}| 远大于 c 时,Fair 损失趋近于线性函数,类似于 L1 损失。

    • 处处可导:Fair 损失函数处处可导,便于优化。

  • 适用场景

    • 适用于数据集中存在异常值,且需要通过调整参数 c 来控制模型对异常值的鲁棒性的场景。

    • 在需要比 Huber 损失更强的鲁棒性,但又希望损失函数保持光滑可导性的情况下,Fair 损失是一个选择。

  • 代码实践 (Python)

# ... (数据集和数据准备代码与 L2 损失示例相同) ... # 3. 设置参数 - 使用 Fair 损失 params_fair = { 'objective': 'fair', 'metric': 'l2', # 或其他回归指标 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9, 'fair_c': 1.0 # 可选参数,调整 c 值,默认 1.0 } # 4. 训练模型 (Fair 损失) gbm_fair = lgb.train(params_fair, lgb_train, num_boost_round=100, valid_sets=lgb_eval, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_fair = gbm_fair.predict(X_test, num_iteration=gbm_fair.best_iteration) mse_fair = mean_squared_error(y_test, y_pred_fair) print(f"Fair Loss MSE: {mse_fair:.4f}")
5. Poisson 回归 - objective="poisson"
  • 适用场景:Poisson 回归用于目标变量为计数型数据(非负整数)的回归问题,例如预测网站的点击次数、某地区的交通事故发生次数等。它假设目标变量服从 Poisson 分布。

  • 特点

    • 处理计数数据:专门为计数型数据设计,能够更好地拟合这类数据的分布特征。

    • 对数链接函数:Poisson 回归使用对数链接函数将线性预测值转换为期望的计数。

  • 代码实践 (Python)

from sklearn.datasets import make_poisson_regression from sklearn.metrics import mean_poisson_deviance # 1. 生成 Poisson 回归数据集 X_poisson, y_poisson = make_poisson_regression(n_samples=1000, n_features=10, random_state=42) X_train_p, X_test_p, y_train_p, y_test_p = train_test_split(X_poisson, y_poisson, test_size=0.2, random_state=42) # 2. LightGBM 数据集 lgb_train_p = lgb.Dataset(X_train_p, y_train_p) lgb_eval_p = lgb.Dataset(X_test_p, y_test_p, reference=lgb_train_p) # 3. 设置参数 - 使用 Poisson 损失 params_poisson = { 'objective': 'poisson', 'metric': 'poisson', # 或 'mean_poisson_deviance' 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9 } # 4. 训练模型 (Poisson 损失) gbm_poisson = lgb.train(params_poisson, lgb_train_p, num_boost_round=100, valid_sets=lgb_eval_p, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_poisson = gbm_poisson.predict(X_test_p, num_iteration=gbm_poisson.best_iteration) poisson_deviance = mean_poisson_deviance(y_test_p, y_pred_poisson) print(f"Poisson Loss Mean Poisson Deviance: {poisson_deviance:.4f}")
6. Quantile 回归 - objective="quantile"
  • 适用场景:Quantile 回归用于预测目标变量的特定分位数,例如预测房价的中位数、90% 分位数等。它不关注平均预测误差,而是关注特定分位点的预测精度。

  • 特点

    • 预测分位数:能够直接预测目标变量的指定分位数。

    • 对分布假设宽松:Quantile 回归对数据分布的假设较少,适用于数据分布未知或非正态的情况。

    • 参数 alphaalpha 参数指定要预测的分位数,取值范围为 (0, 1)。例如,alpha=0.5 预测中位数,alpha=0.9 预测 90% 分位数。

  • 代码实践 (Python)

# ... (回归数据集和数据准备代码与 L2 损失示例相同) ... # 3. 设置参数 - 使用 Quantile 损失 (预测中位数) params_quantile = { 'objective': 'quantile', 'metric': 'l1', # 或其他回归指标 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9, 'alpha': 0.5 # 预测中位数 (Median) } # 4. 训练模型 (Quantile 损失) gbm_quantile = lgb.train(params_quantile, lgb_train, num_boost_round=100, valid_sets=lgb_eval, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_quantile = gbm_quantile.predict(X_test, num_iteration=gbm_quantile.best_iteration) mae_quantile = mean_absolute_error(y_test, y_pred_quantile) print(f"Quantile Loss (alpha=0.5) MAE: {mae_quantile:.4f}") # 可以尝试不同的 alpha 值,例如 alpha=0.9 预测 90% 分位数 params_quantile_90 = params_quantile.copy() params_quantile_90['alpha'] = 0.9 gbm_quantile_90 = lgb.train(params_quantile_90, lgb_train, num_boost_round=100, valid_sets=lgb_eval, callbacks=[lgb.early_stopping(stopping_rounds=10)]) y_pred_quantile_90 = gbm_quantile_90.predict(X_test, num_iteration=gbm_quantile_90.best_iteration) print(f"Quantile Loss (alpha=0.9) Predictions (first 5):\n{y_pred_quantile_90[:5]}")
7. 其他回归目标函数

LightGBM 还提供了其他一些回归目标函数,例如:

  • mape (Mean Absolute Percentage Error):均值绝对百分比误差,适用于目标变量具有比例意义的场景。

  • rmse (Root Mean Squared Error):均方根误差,是 L2 损失的平方根,评估指标常用。

  • l2_root:与 rmse 相同。

  • logcosh (Log-Cosh Loss):类似于 Huber 损失,但处处二阶可导,优化更稳定。

  • tweedie (Tweedie Loss):用于 Tweedie 分布的回归,可以处理不同类型的目标变量分布,通过 tweedie_variance_power 参数调整分布类型。

这些目标函数的使用方法与上述示例类似,只需修改 objective 参数的值即可。

3.2.2.2 二分类 (Binary Classification) 目标函数

二分类任务的目标是将样本分为两个类别(通常标记为 0 和 1)。LightGBM 提供了以下常用的二分类目标函数:

1. 二元 Logistic 回归 (Binary Logistic Regression) - objective="binary", objective="binary_logistic"
  • 公式:使用 Logistic 损失函数(也称为二元交叉熵损失)。

    L(y, p) = - \frac{1}{n} \sum_{i=1}^{n} [y_i \log(p_i) + (1 - y_i) \log(1 - p_i)]

    • y_i \in \{0, 1\}:第 i 个样本的真实标签

    • p_i = \sigma(\hat{y}_i) = \frac{1}{1 + e^{-\hat{y}_i}}:模型预测的第 i 个样本属于类别 1 的概率(经过 Sigmoid 函数 \sigma 转换)

    • \hat{y}_i:模型原始输出 (logit)

  • 特点

    • 概率输出:Logistic 回归输出样本属于正类别的概率,范围在 [0, 1] 之间。

    • 常用分类损失:是二分类任务中最常用的目标函数之一。

    • 梯度稳定:Logistic 损失函数具有良好的梯度特性,优化过程相对稳定。

  • 适用场景

    • 标准的二分类问题,例如垃圾邮件检测、用户点击预测等。

    • 当需要输出概率预测值时,Logistic 回归是首选。

  • 代码实践 (Python)

import lightgbm as lgb from sklearn.model_selection import train_test_split from sklearn.datasets import make_classification from sklearn.metrics import accuracy_score, log_loss # 1. 生成二分类数据集 X_binary, y_binary = make_classification(n_samples=1000, n_features=10, n_classes=2, random_state=42) X_train_b, X_test_b, y_train_b, y_test_b = train_test_split(X_binary, y_binary, test_size=0.2, random_state=42) # 2. LightGBM 数据集 lgb_train_b = lgb.Dataset(X_train_b, y_train_b) lgb_eval_b = lgb.Dataset(X_test_b, y_test_b, reference=lgb_train_b) # 3. 设置参数 - 使用二元 Logistic 回归 params_binary = { 'objective': 'binary', # 或 'binary_logistic' 'metric': 'binary_logloss', # 或 'binary_error', 'auc', 'accuracy' 等 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9 } # 4. 训练模型 (二元 Logistic 回归) gbm_binary = lgb.train(params_binary, lgb_train_b, num_boost_round=100, valid_sets=lgb_eval_b, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 y_pred_prob_binary = gbm_binary.predict(X_test_b, num_iteration=gbm_binary.best_iteration) # 预测概率 y_pred_binary = [1 if p >= 0.5 else 0 for p in y_pred_prob_binary] # 转换为类别标签 (阈值 0.5) accuracy_binary = accuracy_score(y_test_b, y_pred_binary) logloss_binary = log_loss(y_test_b, y_pred_prob_binary) print(f"Binary Logistic Regression Accuracy: {accuracy_binary:.4f}") print(f"Binary Logistic Regression LogLoss: {logloss_binary:.4f}")
2. Cross-Entropy 损失 - objective="cross_entropy"
  • 适用场景:Cross-entropy 损失通常指多类交叉熵损失,但在二分类中也可以使用。与二元 Logistic 回归的损失函数本质上是相同的。

  • 代码实践:与二元 Logistic 回归的代码示例类似,只需将 objective 参数设置为 "cross_entropy" 即可。

3. Focal Loss - objective="focal_loss" (需要 LightGBM 版本 >= 3.0)
  • 适用场景:Focal Loss 旨在解决类别不平衡问题,尤其是在目标检测等任务中常见。它通过降低易分类样本的损失权重,使模型更关注难分类样本。

  • 参数

    • focal_loss_gamma (gamma):聚焦参数,控制损失函数降低易分类样本权重的程度。gamma=0 时退化为标准的交叉熵损失。gamma 值越大,对易分类样本的抑制作用越强。
  • 代码实践 (Python)

# ... (二分类数据集和数据准备代码与 Logistic 回归示例相同) ... # 3. 设置参数 - 使用 Focal Loss (需要 LightGBM >= 3.0) params_focal = { 'objective': 'focal_loss', 'metric': 'binary_logloss', # 或其他分类指标 'boosting_type': 'gbdt', 'num_leaves': 31, 'learning_rate': 0.05, 'feature_fraction': 0.9, 'focal_loss_gamma': 2.0 # 可选参数,调整 gamma 值,例如 0.5, 1.0, 2.0 } # 4. 训练模型 (Focal Loss) gbm_focal = lgb.train(params_focal, lgb_train_b, num_boost_round=100, valid_sets=lgb_eval_b, callbacks=[lgb.early_stopping(stopping_rounds=10)]) # 5. 预测与评估 (与 Logistic 回归示例相同) ...

3.2.2.3 多分类 (Multi-class Classification) 目标函数

多分类任务的目标是将样本分到多个类别中的一个。LightGBM 提供了以下多分类目标函数:

1. 多类 Logistic 回归 (Multi-class Logistic Regression) - objective="multiclass"
  • 公式:使用多类交叉熵损失 (Categorical Cross-Entropy Loss)。

    L(Y, P) = - \frac{1}{n} \sum_{i=1}^{n} \sum_{j=1}^{C} y_{ij} \log(p_{ij})

    • C:类别总数

    • y_{ij} \in \{0, 1\}:第 i 个样本是否属于第 j 个类别(one-hot 编码)

    • p_{ij} = \text{softmax}(\hat{y}_{ij}) = \frac{e^{\hat{y}_{ij}}}{\sum_{k=1}^{C} e^{\hat{y}_{ik}}}:模型预测的第 i 个样本属于第 j 个类别的概率(经过 Softmax 函数转换)

    • \hat{y}_{ij}:模型原始输出 (logit)

  • 特点

    • 多类概率输出:输出样本属于每个类别的概率,概率之和为 1。

    • 常用多分类损失:是多分类任务中最常用的目标函数。

    • Softmax 激活:使用 Softmax 函数将原始输出转换为概率分布。

  • 适用场景

    • 标准的多分类问题,例如图像分类、文本分类等。

    • 当需要输出多类别的概率预测值时,多类 Logistic 回归是首选。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U