LightGBM - 参数调整

优化 LightGBM 的参数对于提升模型的性能至关重要,无论是速度还是准确性。本章详细介绍了如何调整最必要的 LightGBM 参数。

什么是参数调整?

参数调整是调整机器学习模型的超参数或参数以最大化性能的过程。在 LightGBM 等模型中,控制模型学习过程的超参数是叶子计数、学习率和树深度。

这些参数是必需的,因为 −

  • 提高准确性 − 对于新的、未经测试的数据,微调后的模型会生成更准确的预测。

  • 防止过度拟合/欠拟合 −它确保模型既不太复杂也不太简单。

  • 优化速度 − 调整可以使用更少的内存或处理器能力来减少训练时间,而不会影响性能。

那么让我们看看如何调整LightGBM模型的参数 −

1. 控制模型复杂度

这些是通过调整num_leaves和max_depth等参数来调节模型复杂度,平衡欠拟合和过拟合的方法。调整这些参数有助于我们管理LightGBM模型的复杂性。

  • num_leaves − 它用于控制每个决策树中的叶子数量。更多的叶子会增加模型的复杂性,但太多会导致过度拟合。将 num_leaves 设置为小于或等于 2(max_depth)。例如,如果 max_depth = 6,则设置 num_leaves <= 64。

  • min_data_in_leaf − 显示叶子可以包含的最小样本数或数据点数。通过更改此参数,您可以帮助模型减少数据中的噪音。如果深度太低,树可能会增长得太深并变得过度拟合。数百或数千范围内的值适合大型数据集。

  • max_depth − 它用于限制树的深度。这可以通过限制树可以增长的深度来帮助防止过度拟合。因此,与 num_leaves 结合使用来控制树的复杂性。

2.加速模型

通过使用 bagging、特征子采样和 max_bin 缩减等方法,可以在不影响准确性的情况下提高训练速度。

  • Bagging − 要加速训练,请在每个周期中使用数据子集。通过设置参数。每次迭代中使用的数据百分比由变量 bagging_fraction 给出。bagging_freq 返回每个频率的 bagging 迭代次数。设置两个合适的设置是 bagging_fraction = 0.8 和 bagging_freq = 5,以加速模型而不显着影响准确性。

  • 特征子采样 − 在每次迭代中随机选择一组特征进行训练。使用 feature_fraction 等参数。此参数控制用于训练的特征分数。最佳实践是将 feature_fraction = 0.8 设置为 0.8 以减少训练时间。

  • max_bin − 此参数控制用于连续特征的 bin 数量。因此,最佳实践是可以减少 max_bin 以加快模型速度并减少内存消耗,但准确性可能会受到影响。

  • save_binary − 存储二进制数据是为了在连续运行中更快地加载。因此,建议在同一数据集上重复运行模型时使用 save_binary=True。

3. 提高准确性

使用更大的数据集、更低的学习率和 Dart 等高级技术可以提高模型的准确性,但代价是更长的训练时间。

  • learning_rate 和 num_iterations − 每次迭代的步骤数和模型修改量由参数 learning_rate 和 num_iterations 控制。使用较小的 learning_rate(如 0.01)和较大的 num_iterations(如 1000+)是最佳选择。

  • num_leaves − 增加 num_leaves 会使模型更加复杂。这可能会提高准确性,但如果使用不当,也可能导致过度拟合。因此,最佳做法是,如果您有足够的数据,则增加 num_leaves,但请确保将其与正则化技术相结合,以避免过度拟合。

  • 使用更大规模的数据进行训练 − 更多数据通常会带来更高的准确性,因为模型可以拾取更大范围的模式。因此,最佳做法是提高模型的泛化能力,如果过度拟合是一个问题,则使用尽可能多的数据。

  • Dart(Dropouts 满足多重加性回归树) − 此特定版本的梯度提升技术通过在训练期间随机删除树来提高模型的准确性。因此,最佳做法是针对您看到过度拟合的问题或如果您正在寻找额外的准确性使用 boosting_type='dart'。

  • 使用分类特征 − 通过消除将分类特征转换为虚拟变量的需要,LightGBM 可以直接处理它们,从而可能提高性能。因此,最好通过使用 categorical_feature 选项来识别哪些属性是分类的,从而提高模型准确性。

4.处理过度拟合

本节介绍如何使用子采样技术、树深度限制和正则化来防止模型过度拟合训练集。

  • max_bin − 使用较小的 max_bin 可以减少过度拟合,因为它限制了特征分箱中的细节数量。

  • num_leaves − 为防止训练集过度拟合和模型变得过于复杂,请减少模型中的叶子数量。

  • min_data_in_leaf 和 min_sum_hessian_in_leaf − 这些设置有助于防止树太深,方法是确保每个叶子包含二阶导数的最小和(min_sum_hessian_in_leaf)和最少的数据点(min_data_in_leaf)。增加 min_data_in_leaf 和 min_sum_hessian_in_leaf 以避免过度拟合,特别是对于小数据集。

  • Bagging 和特征子采样 − 使用特征子采样 (feature_fraction) 和 bagging (bagging_fraction 和 bagging_freq) 来增加模型中的不可预测性并减少过度拟合。

  • 正则化 − 定义 lambda_l1 等参数,即 L1 正则化,通常称为 Lasso,以降低模型的复杂性。而 lambda_l2 用于通过基于脊的 L2 正则化减少过度拟合。分割树节点所需的最小增益由变量 min_gain_to_split 指示。尝试增加 lambda_l1 和 lambda_l2 来为模型添加正则化,并调整 min_gain_to_split 来控制模型创建新分支的难易程度。

  • max_depth − 设置合理的 max_depth 来限制树的深度并避免过度拟合,尤其是在较小的数据集上。

Python 中参数调整的示例

以下是在 Python 中执行 LightGBM 参数调整的小示例 −

# 导入必要的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

from sklearn.model_selection import train_test_split, RandomizedSearchCV
import lightgbm as lgb
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

sns.set(style="whitegrid", color_codes=True, font_scale=1.3)

import warnings
warnings.filterwarnings('ignore')

# 加载数据集
data = pd.read_csv('/Python/breast_cancer_data.csv')
data.head()

# 1. 预处理
# 删除不必要的列
data = data.drop(columns=['id', 'Unnamed: 32'])

# 将"diagnosis"列转换为数值(0:良性,1:恶性)
data['diagnosis'] = data['diagnosis'].map({'B': 0, 'M': 1})

# 将数据拆分为特征(X)和目标(y)
X = data.drop(columns=['diagnosis'])
y = data['diagnosis']

# 清理列名以避免 LightGBM 错误
X.columns = X.columns.str.replace('[^A-Za-z0-9_]+', '', regex=True)

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

# 2. 定义用于调整的参数网格
param_grid = {
    'learning_rate': [0.01, 0.05, 0.1],
    'num_leaves': [20, 31, 40],
    'max_depth': [-1, 10, 20],
    'feature_fraction': [0.6, 0.8, 1.0],
    'bagging_fraction': [0.6, 0.8, 1.0],
    'bagging_freq': [0, 5, 10],
    'lambda_l1': [0, 1, 5],
    'lambda_l2': [0, 1, 5]
}

# 3. 设置 LightGBM 模型
lgb_estimator = lgb.LGBMClassifier(objective='binary', metric='binary_logloss')

# 4. 执行随机搜索以调整参数
random_search = RandomizedSearchCV(estimator=lgb_estimator, param_distributions=param_grid,
n_iter=50,scoring='accuracy', cv=5, verbose=1, random_state=42)

# 5. 拟合模型
random_search.fit(X_train, y_train)

# 6. 获取最佳参数
print("最佳参数:", random_search.best_params_)

# 7. 预测并评估模型
y_pred = random_search.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"准确率: {accuracy * 100:.2f}%")

# 混淆矩阵
conf_matrix = confused_matrix(y_test, y_pred)
print("混淆矩阵:")
print(conf_matrix)

# 分类报告
print("分类报告:")
print(classification_report(y_test, y_pred))

# 可选:绘制混淆矩阵以进行可视化
plt.figure(figsize=(8,6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=['Benign', 'Malignant'], yticklabels=['Benign', 'Malignant'])
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()

输出

这是上述 LightGBM 模型参数调整的输出 −

准确率:97.37%
混淆矩阵:
[[70  1]
 [ 2 41]]
Classification Report:
              precision    recall  f1-score   support

           0       0.97      0.99      0.98        71
           1       0.98      0.95      0.96        43

    accuracy                           0.97       114
   macro avg       0.97      0.97      0.97       114
weighted avg       0.97      0.97      0.97       114

混淆矩阵如下 −

LightGBM 混淆矩阵

总结

需要调整 LightGBM 参数以最大化模型性能和训练速度。在速度、精度、复杂性和过拟合预防之间找到平衡是关键。通过仔细调整 num_leaves、min_data_in_leaf、bagging_fraction 和 max_depth 等参数,您可以构建一个在训练和未见数据上表现良好的模型。在这里,L1 和 L2 正则化程序可以帮助进一步防止过拟合并增强模型的泛化能力。