LightGBM

技术栈
AI 框架
gradient-boostingmicrosoftleaf-wisefastlarge-dataset

概览

LightGBM

LightGBM 是微软于 2017 年开源的轻量级梯度提升框架,核心创新是 Leaf-wise 生长策略和 GOSS 采样,在大数据场景下比 XGBoost 快 10-20x 且内存节省 3x。

核心价值:

  • Leaf-wise 生长:每次分裂增益最大的叶子,收敛更快
  • GOSS 采样:保留大梯度样本,随机采样小梯度样本,聚焦难学样本
  • EFB 特征捆绑:互斥特征合并,减少特征维度
  • 原生类别特征:直接传入 categorical 列,无需独热编码
  • 大规模友好:千万级样本轻松训练,分布式支持

适用场景: Kaggle 表格竞赛首选,推荐系统 CTR 预估,大规模金融风控。

安装

环境准备

  • Python:>= 3.7(推荐 3.10)
  • 系统:Linux 最佳,macOS/Windows 也可
  • GPU(可选):NVIDIA CUDA 11+

安装命令

CPU 版

pip install lightgbm

GPU 版

pip install lightgbm --config-settings=cmake.define.USE_CUDA=ON
# 或预编译 wheel
pip install lightgbm==4.3.0

验证安装

import lightgbm as lgb
print(lgb.__version__)

# 快速测试
import numpy as np
X = np.random.rand(100, 5)
y = np.random.randint(0, 2, 100)
model = lgb.LGBMClassifier(n_estimators=10, verbose=-1)
model.fit(X, y)
print("LightGBM 安装成功 ✓")

常见安装问题

Q1: libgomp.so.1: cannot open shared object file

缺少 OpenMP 库。Ubuntu: sudo apt install libgomp1;CentOS: sudo yum install libgomp

Q2: macOS 上 Library not loaded

使用官方 wheel:pip install --no-cache-dir lightgbm,不要从源码编译

Q3: GPU 训练报 CUDA error

检查 CUDA 版本兼容性。LightGBM GPU 支持 CUDA 11.0+。在参数中设置 device_type='cuda' 后首次运行会 JIT 编译。

示例

LightGBM 原生类别特征分类

目标

展示 LightGBM 两大特色:原生类别特征支持(无需 One-Hot)和 early stopping 回调。

完整代码

import lightgbm as lgb
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# ─── 1. 构造含类别特征的数据 ───
np.random.seed(42)
n = 5000
df = pd.DataFrame({
    "age": np.random.randint(18, 70, n),
    "city": np.random.choice(["Beijing", "Shanghai", "Guangzhou", "Shenzhen", "Hangzhou"], n),
    "education": np.random.choice(["High School", "Bachelor", "Master", "PhD"], n),
    "income": np.random.normal(15000, 5000, n),
    "experience": np.random.randint(0, 30, n),
})
df["target"] = (
    (df["income"] > 15000).astype(int)
    + (df["education"].isin(["Master", "PhD"])).astype(int)
    + (df["experience"] > 10).astype(int)
)
df["target"] = (df["target"] >= 2).astype(int)  # 二分类

print(f"正样本比例: {df['target'].mean():.2%}")

# ─── 2. 特征准备(类别特征声明为 'category' dtype) ───
cat_cols = ["city", "education"]
for col in cat_cols:
    df[col] = df[col].astype("category")

X = df.drop("target", axis=1)
y = df["target"]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# ─── 3. 训练 + Early Stopping ───
callbacks = [
    lgb.early_stopping(stopping_rounds=20, verbose=1),
    lgb.log_evaluation(period=50),
]

model = lgb.LGBMClassifier(
    n_estimators=500,
    learning_rate=0.05,
    max_depth=7,
    num_leaves=31,
    subsample=0.8,
    colsample_bytree=0.8,
    min_child_samples=20,
    random_state=42,
    verbose=-1,
)

model.fit(
    X_train, y_train,
    eval_set=[(X_test, y_test)],
    eval_metric="auc",
    callbacks=callbacks,
)

# ─── 4. 评估 ───
y_pred = model.predict(X_test)
acc = accuracy_score(y_test, y_pred)
print(f"\n测试准确率: {acc:.4f}")
print(f"最佳迭代轮次: {model.best_iteration_}")
print(f"最佳 AUC: {model.best_score_['valid_0']['auc']:.4f}")

# ─── 5. 特征重要性 ───
importance = pd.DataFrame({
    "feature": X.columns,
    "importance": model.feature_importances_,
}).sort_values("importance", ascending=False)
print("\n特征重要性:")
print(importance.to_string(index=False))

运行步骤

pip install lightgbm pandas scikit-learn
python lgb_categorical.py

预期输出

正样本比例: 35.62%
Training until validation scores don't improve for 20 rounds
[50]  valid_0's auc: 0.8234
[100] valid_0's auc: 0.8456
Early stopping, best iteration is [87]
测试准确率: 0.7823
最佳迭代轮次: 87
最佳 AUC: 0.8489

特征重要性:
     feature  importance
     income         450
 experience         380
        age         120
       city          80
  education          50

教程

LightGBM 入门教程:Leaf-wise 生长与 GOSS 原理

1. LightGBM 的设计哲学

LightGBM 的三个核心问题:

"XGBoost 在大数据上太慢了,内存也吃不起。能不能更快、更省?"

答案:三个算法创新 —— Leaf-wise / GOSS / EFB

2. Leaf-wise vs Level-wise

XGBoost (Level-wise):          LightGBM (Leaf-wise):
     [A]                           [A]
   /     \                          |
 [B]     [C]                       [B]        ← 只分裂增益最大的叶子
 / \     / \                       / \
[D][E] [F][G]                    [D] [E]

Level-wise 每层所有节点都分裂(很多没必要),Leaf-wise 只分裂增益最大的叶节点:

  • 相同叶子数下误差更低
  • 速度快 10-20x
  • 但易过拟合 → 需限制 max_depthnum_leaves

关键约束参数

num_leaves=31        # 最大叶子数(LightGBM 核心参数)
max_depth=-1         # 限制深度防止过拟合,-1 不限制
min_data_in_leaf=20  # 叶子最少样本数

⚠️ 调大 num_leaves 效果可能先升后降——典型过拟合信号。

3. GOSS:基于梯度的单边采样

动机:梯度小的样本已被学好了,梯度大的才需要重点关注。

算法:

  1. 按梯度绝对值排序
  2. 保留 top a% 大梯度样本
  3. 从剩余样本中随机采样 b%
  4. 对 b% 样本乘以 (1-a)/b 补偿

参数:

boosting_type='gbdt'     # 默认即使用 GOSS
top_rate=0.2             # a(大梯度保留比例)
other_rate=0.1           # b(小梯度采样比例)

4. EFB:互斥特征绑定

很多特征互斥(不同时为非零),如 One-Hot 编码后的类别。EFB 将它们捆绑为单个特征,减少直方图构建开销。

# 自动启用,无需手动设置
# 等效效果:100 个 One-Hot 列 → 合并为 ~20 个特征束

5. 原生类别特征:不用 One-Hot!

# ❌ XGBoost 需要这样(特征膨胀!)
pd.get_dummies(df, columns=['city'])

# ✅ LightGBM 原生支持
df['city'] = df['city'].astype('category')
model.fit(X, y, categorical_feature=['city'])

内部机制:对类别值求目标变量均值排序,再找最优分割点。既省内存,又更准。

6. 常见超参数调优指南

# 快速开始模板
lgb.LGBMClassifier(
    n_estimators=500,
    learning_rate=0.05,
    num_leaves=31,          # < 2^max_depth
    max_depth=7,
    min_child_samples=20,
    subsample=0.8,
    colsample_bytree=0.8,
    reg_alpha=0.1,          # L1
    reg_lambda=0.1,         # L2
)

7. LightGBM vs XGBoost 选型

场景 推荐
数据 < 10 万行 XGBoost(更稳定)
数据 > 100 万行 LightGBM
类别特征多 LightGBM
需极致精度 XGBoost(更保守,不易过拟合)
特征维度高(>1000) LightGBM(EFB)

思考题

  1. Leaf-wise 为什么比 Level-wise 更快?是算法原因还是工程原因?
  2. GOSS 采样会引入偏差,LightGBM 如何修正这个偏差?
  3. 为什么 num_leaves 设太大反而验证集效果下降?

参考资料

暂无参考文献