常用监督学习算法

合集:AI算法

传统机器学习算法通常分为监督学习、无监督学习和半监督学习三大类:

  • 监督学习(Supervised Learning)的核心思想是利用带有标签(正确答案)的数据训练模型,使模型能够学习输入(特征)与输出(标签)之间的映射关系,从而对新的未知数据做出预测。典型的算法包括:线性回归、逻辑回归、决策树、随机森林、XGBoost等。
  • 无监督学习(Unsupervised Learning)的核心思想是从无标签数据中自动发现隐藏模式或结构,无需人工标注。例如聚类将相似数据分组,如用户分群。主要成分分析/PCA对数据降维。关联规则挖掘数据相关性,如购物篮分析。
  • 半监督学习(Semi-Supervised Learning)的核心思想:结合少量标注数据 + 大量无标签数据训练模型,降低标注成本。

以下为常用监督学习算法和样例:决策树、随机森林、梯度提升决策树、XGBoost、LightGBM。

一、决策树(Decision Tree)

决策树(Decision Tree) 是一种基于树形结构的监督学习算法,适用于分类和回归任务。它通过一系列规则(if-else判断)对数据进行分割,模拟人类决策过程,具有直观、易解释的特点。

决策树由根节点、内部节点(决策节点)和叶子节点(结果节点)组成,每个节点代表一个特征或决策规则,每条分支代表规则的可能结果。从根节点开始,根据特征的值将数据递归划分到子节点,直到达到停止条件(如节点纯度达标或深度限制)。

代码示例

鸢尾花数据集简介 来源:经典分类数据集,由统计学家 Ronald Fisher 于 1936 年整理。 内容: 样本数量:150 个(3 类 × 50 个)。 特征(4 个数值型):

  • 花萼长度(sepal length, cm)
  • 花萼宽度(sepal width, cm)
  • 花瓣长度(petal length, cm)
  • 花瓣宽度(petal width, cm)

类别(3 种鸢尾花):

  • 0: Setosa(山鸢尾)
  • 1: Versicolor(杂色鸢尾)
  • 2: Virginica(维吉尼亚鸢尾)
# -*- coding: utf-8 -*-
"""
以下是一个完整的 •决策树分类器(Decision Tree Classifier)•• 的 Python 开发样例,
使用 scikit-learn 库实现,包含数据生成、模型训练、可视化及评估,可直接运行。
"""
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.tree import DecisionTreeClassifier, plot_tree
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report

# 1. 加载数据集(这里以鸢尾花数据集为例)
data = load_iris()
X = data.data # 特征 (150个样本, 4个特征)
y = data.target # 标签 (0: Setosa, 1: Versicolor, 2: Virginica)
feature_names = data.feature_names
class_names = data.target_names

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

# 3. 创建决策树模型
model = DecisionTreeClassifier(
  max_depth=3, # 控制树的最大深度(防止过拟合)
  random_state=42
)
model.fit(X_train, y_train)

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

# 5. 评估模型
print("准确率:", accuracy_score(y_test, y_pred))
print("\n分类报告:\n", classification_report(y_test, y_pred, target_names=class_names))

# 6. 可视化决策树
plt.figure(figsize=(12, 8))
plot_tree(
  model,
  feature_names=feature_names,
  class_names=class_names,
  filled=True, # 填充颜色表示类别
  rounded=True
)
plt.title("决策树可视化")
plt.show()

python decision-tree-sample.py

准确率: 1.0

分类报告:
              precision   recall f1-score   support

    setosa       1.00     1.00     1.00       19
versicolor       1.00     1.00     1.00       13
  virginica       1.00     1.00     1.00       13

  accuracy                           1.00       45
  macro avg       1.00     1.00     1.00       45
weighted avg       1.00     1.00     1.00       45

二、随机森林

随机森林(Random Forest) 是一种基于决策树的集成学习算法,属于 Bagging/Bootstrap Aggregating/自助聚集法 家族。它通过构建多棵决策树并综合投票(分类)或平均(回归)结果,显著提升模型的泛化能力和鲁棒性。

1. 核心思想

Bagging 思想:

Bagging 是 Bootstrap Aggregating 的缩写,中文译为自助聚集法,是一种集成学习(Ensemble Learning)策略。它的核心思想是通过并行训练多个基学习器(Base Learner),并对它们的预测结果进行综合(如投票或平均),从而降低模型的方差(Variance),提升泛化能力。通过自助采样(Bootstrap Sampling)生成多个子数据集,并行训练多个基学习器(决策树),最终通过投票或平均降低模型方差。

双重随机性

  1. 数据随机性:每棵树使用不同的子数据集(行采样)。
  2. 特征随机性:每棵树分裂时仅考虑随机子集的特征(列采样)。

森林意思是:构建多棵决策树。

2. 核心流程

以分类任务为例:

  1. 自助采样: 从原始数据集中随机抽取 (n) 个样本(有放回),形成训练子集。未被抽中的样本称为 OOB(Out-of-Bag),可用于验证。
  2. 构建单棵树
    • 每个节点分裂时,从全部特征中随机选择 (m) 个候选特征(通常 (m = \sqrt{\text{总特征数}}))。
    • 基于信息增益(如基尼系数)选择最优分裂点,递归生成完整决策树(不剪枝)。
  3. 聚合结果: 重复上述过程构建 (T) 棵树,最终通过投票(分类)或平均(回归)输出结果。

3. 关键特点

✅ 优点

  • 高泛化能力:通过双重随机性和集成投票,有效降低方差,减少过拟合。
  • 天然抗噪声:对异常值、缺失值不敏感。
  • 并行化训练:各树独立生成,支持多线程加速。
  • 可解释性辅助:提供特征重要性评估(基于分裂时的信息增益或OOB误差)。
  • 无需复杂调参:默认参数表现稳健,适合快速实现。

❌ 缺点

  • 预测速度较慢:需遍历所有树的预测结果,实时性要求高的场景不适用。
  • 空间复杂度高:存储多棵完整决策树占用内存较大。
  • 对高维稀疏数据效果差:如文本特征、One-Hot编码后的稀疏矩阵。
  • 偏向于高基数特征:类别型特征取值较多时可能被过度重视。

4. 核心参数

  • n_estimators:森林中树的数量(默认100),数量越多模型越稳定,但计算成本增加。
  • max_depth:单棵树的最大深度(默认不限制,直到叶子节点纯度一致)。
  • max_features:分裂时随机选择的最大特征数(默认"auto",即sqrt(总特征数)。
  • min_samples_split:节点分裂所需的最小样本数(默认2)。
  • min_samples_leaf:叶子节点最小样本数(默认1)。
  • bootstrap:是否启用自助采样(默认True,若设为False则使用全部数据)。
  • oob_score:是否使用OOB样本评估模型性能(默认False)。

5. 与GBDT的对比

假设用同一数据集(如MNIST手写数字识别)比较:

模型训练时间测试准确率过拟合程度(训练集 vs 测试集)
单棵决策树1秒88% vs 85%明显过拟合(差异3%)
随机森林200秒92% vs 91%轻微过拟合(差异1%)
梯度提升树(GBDT)150秒(较短)93% vs 90%可能过拟合(差异3%)

说明:在人工智能(AI)和机器学习中,过拟合(Overfitting)是指模型在训练数据上表现非常好,但在新的、未见过的数据上表现较差的现象。简单来说,模型“死记硬背”了训练数据的细节和噪声,而不是真正学习到数据背后的通用规律,导致泛化能力不足。

结论

  • 随机森林通过更长的训练时间,换取了更高的泛化能力(测试集准确率更接近训练集)。
  • 但相比梯度提升树(GBDT),随机森林的并行化潜力更高(每棵树独立训练),实际可通过多核CPU加速。

6. 适用场景

  1. 何时用随机森林?
    • 数据维度高、特征间存在复杂关系。
    • 需要快速验证模型效果(代码实现简单,调参相对容易)。
    • 对训练时间不敏感,但对稳定性要求高(如金融风控)。
  2. 如何缓解计算慢?
    • 减少树的数量(如从500减到100,适当牺牲精度)。
    • 限制树的深度(设置max_depth=10)。
    • 使用并行计算(设置n_jobs=-1调用所有CPU核心)。
    • 降维处理(用PCA减少特征数量)。
  3. 替代方案
    • 对时间敏感且数据量大时,用梯度提升树(如XGBoost、LightGBM),训练更快且精度更高(但需精细调参)。
    • 对解释性要求高时,用单棵剪枝后的决策树。

7. 代码示例(Python)

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import seaborn as sns
import pandas as pd

# 1. 加载数据集(以鸢尾花数据集为例)
data = load_iris()
X = data.data  # 特征 (150个样本, 4个特征)
y = data.target  # 标签 (0: Setosa, 1: Versicolor, 2: Virginica)
feature_names = data.feature_names
class_names = data.target_names

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

# 3. 创建随机森林模型
model = RandomForestClassifier(
   n_estimators=100,  # 树的数量
   max_depth=3,       # 单棵树的最大深度(防止过拟合)
   random_state=42,
   oob_score=True     # 启用袋外(OOB)评估
)
model.fit(X_train, y_train)

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

# 5. 评估模型
print("测试集准确率:", accuracy_score(y_test, y_pred))
print("OOB Score:", model.oob_score_)  # 袋外估计(类似交叉验证)
print("\n分类报告:\n", classification_report(y_test, y_pred, target_names=class_names))

# 6. 混淆矩阵可视化
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
           xticklabels=class_names,
           yticklabels=class_names)
plt.title("混淆矩阵")
plt.xlabel("预测值")
plt.ylabel("真实值")
plt.show()

# 7. 特征重要性分析
importance = model.feature_importances_
df_importance = pd.DataFrame({
   "Feature": feature_names,
   "Importance": importance
}).sort_values("Importance", ascending=False)

plt.figure(figsize=(10, 5))
sns.barplot(x="Importance", y="Feature", data=df_importance, palette="viridis")
plt.title("特征重要性排序")
plt.show()

python random-forest-sample.py

测试集准确率: 1.0
OOB Score: 0.9523809523809523

分类报告:
              precision   recall f1-score   support

    setosa       1.00     1.00     1.00       19
versicolor       1.00     1.00     1.00       13
  virginica       1.00     1.00     1.00       13

  accuracy                           1.00       45
  macro avg       1.00     1.00     1.00       45
weighted avg       1.00     1.00     1.00       45

8. 优化技巧

  1. 增加树的数量:优先增大n_estimators(直到性能稳定),再调整其他参数。
  2. 限制树复杂度:通过max_depthmin_samples_leaf防止单棵树过拟合。
  3. 调整特征随机性:增大max_features可能提升模型表现(但可能增加方差)。
  4. 利用OOB评估:无需额外交叉验证即可快速估计模型泛化能力。
  5. 处理类别不平衡:设置class_weight="balanced"或调整样本采样策略。

总结

随机森林是一种高效、稳健的集成学习算法,尤其适合中小规模数据集和特征维度适中的场景。其“双重随机性”设计在降低过拟合风险的同时,提供了天然的特征选择能力。尽管在预测速度和内存占用上存在局限性,但其易用性和可靠性使其成为工业界和学术界的经典选择。

参考资料

三、GBDT梯度提升决策树

GBDT(Gradient Boosting Decision Tree,梯度提升决策树) 是一种基于决策树的集成学习算法,属于 Boosting/提升家族。它通过逐步训练多个弱学习器(通常是决策树),结合梯度下降的思想,不断修正前序模型的残差(误差),最终生成一个强大的预测模型。

GBDT 是一种强大且灵活的机器学习算法,尤其擅长处理复杂的非线性问题。其变种(如 XGBoost、LightGBM)在工业界广泛应用,是数据科学竞赛(如 Kaggle)中的常胜工具。使用时需注意参数调优和正则化,以平衡模型精度与泛化能力。

以下是其核心原理、流程和特点的详细介绍:

1、核心思想

  • Boosting 思想: 通过迭代训练多个弱学习器(如深度较浅的决策树),每个新模型专注于修正前序模型的预测误差,最终将所有模型的预测结果加权结合。弱学习器是指那些性能不太好的简单模型。
  • 梯度下降: 用损失函数的负梯度(近似残差)作为当前模型的优化目标,适用于任何可微损失函数(如平方损失、对数损失)。

2、关键特点

✅ 优点

  • 高预测精度:通过迭代修正误差,模型对复杂非线性关系的拟合能力极强。
  • 鲁棒性:对缺失值、异常值有一定容忍度(可通过正则化增强)。
  • 特征自动组合:决策树天然支持特征交互,无需人工构造交叉特征。
  • 灵活性:支持多种损失函数(回归、分类、排序等任务均可处理)。

❌ 缺点

  • 训练速度慢:需串行生成多棵树,难以并行化(但 XGBoost/LightGBM 优化了效率)。
  • 容易过拟合:树的数量(n_estimators)或深度过大时可能过拟合,需通过正则化(如剪枝、学习率调整)控制。
  • 解释性差:集成模型复杂度高,可解释性弱于单棵决策树。

3、核心参数与正则化

  • 学习率(learning_rate: 控制每棵树的贡献权重,越小需要更多树但模型更稳定(经验值:0.01~0.3)。
  • 树的数量(n_estimators: 迭代次数,需结合学习率调整,防止过拟合。
  • 树复杂度控制
    • 最大深度(max_depth
    • 叶子节点最小样本数(min_samples_leaf
    • 节点分裂最小增益(min_split_gain
  • 随机性增强
    • 行采样(subsample):随机选择部分样本训练每棵树。
    • 列采样(colsample_bytree):随机选择部分特征。

4. 代码示例

参考章节:核心参数。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
import seaborn as sns
import pandas as pd

# 1. 加载数据集(以鸢尾花数据集为例)
data = load_iris()
X = data.data # 特征 (150个样本, 4个特征)
y = data.target # 标签 (0: Setosa, 1: Versicolor, 2: Virginica)
feature_names = data.feature_names
class_names = data.target_names

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

# 3. 创建梯度提升模型
model = GradientBoostingClassifier(
n_estimators=100, # 树的数量
learning_rate=0.1, # 学习率(缩小每棵树的贡献)
max_depth=3, # 单棵树的最大深度
random_state=42
)
model.fit(X_train, y_train)

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

# 5. 评估模型
print("测试集准确率:", accuracy_score(y_test, y_pred))
print("\n分类报告:\n", classification_report(y_test, y_pred, target_names=class_names))

# 6. 混淆矩阵可视化
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(8, 6))
sns.heatmap(cm, annot=True, fmt="d", cmap="Blues",
xticklabels=class_names,
yticklabels=class_names)
plt.title("混淆矩阵")
plt.xlabel("预测值")
plt.ylabel("真实值")
plt.show()

# 7. 特征重要性分析
importance = model.feature_importances_
df_importance = pd.DataFrame({
"Feature": feature_names,
"Importance": importance
}).sort_values("Importance", ascending=False)

plt.figure(figsize=(10, 5))
sns.barplot(x="Importance", y="Feature", data=df_importance, palette="viridis")
plt.title("特征重要性排序")
plt.show()

# 8. 训练过程中的损失函数值(可选)
plt.figure(figsize=(10, 5))
plt.plot(np.arange(model.n_estimators_), model.train_score_, label="训练集损失")
plt.xlabel("迭代次数")
plt.ylabel("损失值")
plt.title("训练过程中的损失下降曲线")
plt.legend()
plt.show()

#执行结果
测试集准确率: 1.0

分类报告:
precision recall f1-score support

setosa 1.00 1.00 1.00 19
versicolor 1.00 1.00 1.00 13
virginica 1.00 1.00 1.00 13

accuracy 1.00 45
macro avg 1.00 1.00 1.00 45
weighted avg 1.00 1.00 1.00 45

5、常见优化变种

  • XGBoost: 引入二阶梯度、正则化项、预排序算法,大幅提升效率和精度。
  • LightGBM: 基于直方图的决策树算法,支持更高效的特征并行和垂直分裂。
  • CatBoost: 自动处理类别型特征,通过 Ordered Boosting 减少过拟合。

6、应用场景

  • 分类任务:点击率预测、用户流失预测。
  • 回归任务:销量预测、房价预测。
  • 排序任务:搜索引擎结果排序、推荐系统。
  • 特征重要性分析:通过树分裂时的信息增益评估特征重要性。

7、与随机森林(Random Forest)对比

随机森林(Random Forest)和GBDT(Gradient Boosting Decision Tree)是两种不同的集成学习算法,各有其优势和适用场景,没有绝对的“优劣”,但可以根据具体需求选择更适合的算法。以下是两者的对比及选择建议:

a. 核心思想对比

特性随机森林(RF)GBDT
集成策略Bagging(并行训练独立模型,降低方差)Boosting(串行训练依赖模型,降低偏差)
基学习器强学习器(完全生长的决策树)弱学习器(浅层决策树)
优化目标降低方差(Variance)降低偏差(Bias)
数据随机性行采样(Bootstrap) + 列采样(特征随机)基于残差或梯度的样本加权(无随机采样,但可加入正则化)
过拟合风险低(天然抗过拟合)高(需正则化控制)
训练速度快(并行训练)慢(串行训练,但现代实现如LightGBM/XGBoost优化加速)
预测速度较慢(需遍历所有树)较快(树的数量通常更少)
参数敏感性低(默认参数表现稳定)高(需精细调参)
解释性中等(提供特征重要性)中等(类似)
异常值敏感度低(鲁棒性强)高(梯度对异常敏感)

b. 选择建议

✅ 优先选择随机森林的场景
  1. 数据噪声大或异常值多: RF对噪声和异常值鲁棒性强,GBDT可能因梯度敏感而表现不稳定。
  2. 追求快速实现和稳定基线: RF默认参数表现稳健,适合快速验证模型可行性。
  3. 高维稀疏数据(如文本特征): RF通过特征随机性有效处理高维特征,GBDT可能过拟合。注释:对于高维稀疏数据(如文本特征)的处理,一般采用word embedding/文本编码技术。
  4. 并行计算资源充足: RF支持多线程并行训练,适合大规模数据。
  5. 需要天然抗过拟合: 无需复杂正则化即可避免过拟合。
✅ 优先选择GBDT的场景
  1. 预测精度要求极高: GBDT通过Boosting逐步修正误差,通常比RF精度更高(尤其在结构化数据中)。
  2. 数据量适中且质量高: 数据干净、特征工程充分时,GBDT能充分发挥其降低偏差的优势。
  3. 需要灵活的自定义损失函数: GBDT支持自定义损失函数(如Huber Loss),适合特定业务需求。
  4. 实时性要求高(预测阶段): GBDT树的数量通常比RF少(如100 vs 500),预测速度更快。
  5. 特征交互复杂: GBDT通过Boosting自动学习高阶特征组合,适合复杂非线性关系。

c. 性能对比(经验总结)

指标随机森林GBDT
训练速度⚡️⚡️⚡️(快)⚡️⚡️(中,依赖实现)
预测速度⚡️⚡️(中)⚡️⚡️⚡️(快)
分类任务精度⚡️⚡️(中)⚡️⚡️⚡️(高)
回归任务精度⚡️⚡️(中)⚡️⚡️⚡️(高)
抗过拟合能力⚡️⚡️⚡️(强)⚡️(弱,需正则化)
易用性⚡️⚡️⚡️(高)⚡️⚡️(中,需调参)

四、XGBoost

XGBoost是Extreme Gradient Boosting的缩写,主要用于回归和分类问题。XGBoost 是 GBDT 的改进版,具备更高的训练速度和性能优化。它引入了正则化控制模型复杂度,能够处理缺失值、具有更好的并行计算性能,适用于大规模数据集,如推荐系统、广告点击率预测等。

随机森林是高方差、低偏差模型,通过大量无关树的投票来减少过拟合。XGBoost是偏差方差权衡的强大学习器,适合追求极致性能,但需要仔细调参。方差是模型对训练数据中噪声或微小波动的敏感度,反映模型的稳定性。偏差是模型预测值与真实值之间的系统误差,反映了模型对数据内在规律的拟合能力。

对比随机森林和XGBoost

项目随机森林(RF)极限梯度提升(XGBoost)
方法Bagging(并行)Boosting(串行)
建模过程每棵树独立训练每棵树依赖前一棵树误差
训练方式同时训练顺序迭代训练
树的类型深度很大的决策树(未剪枝)通常浅树(防止过拟合)
特征选择训练时随机选择特征全局考虑所有特征,分裂时按增益
正则化有显式的 、 正则化
偏差-方差权衡降低方差,偏差较大同时控制偏差和方差
计算复杂度较高(但可高效实现)
并行性很强部分支持(比如特定分裂时)
超参数调节较简单较复杂(学习率、树深、步长等)

参考资料

五、LightGBM

1、简介

GBDT (Gradient Boosting Decision Tree) 是机器学习中一个长盛不衰的模型,其主要思想是利用弱分类器(决策树)迭代训练以得到最优模型,该模型具有训练效果好、不易过拟合等优点。GBDT不仅在工业界应用广泛,通常被用于多分类、点击率预测、搜索排序等任务;在各种数据挖掘竞赛中也是致命武器,据统计Kaggle上的比赛有一半以上的冠军方案都是基于GBDT。而LightGBM(Light Gradient Boosting Machine)是一个实现GBDT算法的框架,支持高效率的并行训练,并且具有更快的训练速度、更低的内存消耗、更好的准确率、支持分布式可以快速处理海量数据等优点。

2、动机

常用的机器学习算法,例如神经网络等算法,都可以以mini-batch的方式训练,训练数据的大小不会受到内存限制。而GBDT在每一次迭代的时候,都需要遍历整个训练数据多次。如果把整个训练数据装进内存则会限制训练数据的大小;如果不装进内存,反复地读写训练数据又会消耗非常大的时间。尤其面对工业级海量的数据,普通的GBDT算法是不能满足其需求的。

LightGBM提出的主要原因就是为了解决GBDT在海量数据遇到的问题,让GBDT可以更好更快地用于工业实践。

3、XGBoost的缺点及LightGBM的优化

(1)XGBoost的缺点

在LightGBM提出之前,最有名的GBDT工具就是XGBoost了,它是基于预排序方法的决策树算法。这种构建决策树的算法基本思想是:

  • 首先,对所有特征都按照特征的数值进行预排序。
  • 其次,在遍历分割点的时候用的代价找到一个特征上的最好分割点。
  • 最后,在找到一个特征的最好分割点后,将数据分裂成左右子节点。

这样的预排序算法的优点是能精确地找到分割点。但是缺点也很明显:首先,空间消耗大。这样的算法需要保存数据的特征值,还保存了特征排序的结果(例如,为了后续快速的计算分割点,保存了排序后的索引),这就需要消耗训练数据两倍的内存。其次,时间上也有较大的开销,在遍历每一个分割点的时候,都需要进行分裂增益的计算,消耗的代价大。最后,对cache优化不友好。

在预排序后,特征对梯度的访问是一种随机访问,并且不同的特征访问的顺序不一样,无法对cache进行优化。同时,在每一层长树的时候,需要随机访问一个行索引到叶子索引的数组,并且不同特征访问的顺序也不一样,也会造成较大的cache miss。

(2)LightGBM的优化

为了避免上述XGBoost的缺陷,并且能够在不损害准确率的条件下加快GBDT模型的训练速度,lightGBM在传统的GBDT算法上进行了如下优化:

  • 基于Histogram的决策树算法。
  • 单边梯度采样 Gradient-based One-Side Sampling(GOSS):使用GOSS可以减少大量只具有小梯度的数据实例,这样在计算信息增益的时候只利用剩下的具有高梯度的数据就可以了,相比XGBoost遍历所有特征值节省了不少时间和空间上的开销。
  • 互斥特征捆绑 Exclusive Feature Bundling(EFB):使用EFB可以将许多互斥的特征绑定为一个特征,这样达到了降维的目的。
  • 带深度限制的Leaf-wise的叶子生长策略:大多数GBDT工具使用低效的按层生长 (level-wise) 的决策树生长策略,因为它不加区分的对待同一层的叶子,带来了很多没必要的开销。实际上很多叶子的分裂增益较低,没必要进行搜索和分裂。LightGBM使用了带有深度限制的按叶子生长 (leaf-wise) 算法。
  • 直接支持类别特征(Categorical Feature)
  • 支持高效并行
  • Cache命中率优化

4、核心参数

参数名作用常用值调参方向
objective定义任务类型(分类、回归等)binary, multiclass, regression根据任务选择
boosting_type提升算法类型(默认gbdt,可选dart, goss, rfgbdtgoss更快但可能过拟合;dart防过拟合
num_leaves单棵树的最大叶子节点数(直接影响模型复杂度)31-1024增加→模型更复杂,可能过拟合
max_depth树的最大深度(LightGBM可忽略此参数,由num_leaves间接控制)-1(无限制)限制深度防过拟合
learning_rate学习率(步长)0.01-0.3小学习率需更多树
n_estimators树的个数(迭代次数)100-10000增加→模型更复杂,可能过拟合

速度与内存优化

参数名作用调参方向
bin_construct_sample_cnt构建直方图的样本数量(值越小越快)降低→牺牲精度换速度
max_bin特征值分桶的最大数量(默认255)降低→减少内存占用,但可能损失精度
gpu_use是否使用GPU加速True/False

正则化与过拟合控制

参数名作用调参方向
lambda_l1L1正则化系数(控制权重稀疏性)增加→防止过拟合
lambda_l2L2正则化系数(控制权重大小)增加→防止过拟合
min_data_in_leaf叶子节点最小样本数增加→限制树生长
feature_fraction每棵树随机选取的特征比例(类似随机森林)0.6-1.0,降低→增强随机性防过拟合
bagging_fraction每棵树随机选取的样本比例0.6-1.0,降低→增强随机性防过拟合
early_stopping_round当模型在验证集上的评估指标(如损失函数、准确率等)在连续若干轮迭代中没有进一步改善时,提前终止训练,以防止过拟合并节省计算资源。

类别特征处理

参数名作用
categorical_feature指定类别特征的列索引(需数据格式为pd.Category或提前编码)

5. 代码示例:分类与回归任务

分类任务(鸢尾花数据集)

import lightgbm as lgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
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)

# 转换为LightGBM数据集格式
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 参数配置
params = {
   'objective': 'multiclass',  #分类任务
   'num_class': 3, # 分类数
   'num_leaves': 31, # 单棵树的最大叶子节点数(直接影响模型复杂度)
   'learning_rate': 0.1, #学习率(步长)小学习率需更多树
   'feature_fraction': 0.8, # 每棵树随机选取的特征比例(类似随机森林)
   'lambda_l2': 0.1, # L2正则化系数(控制权重大小)
   'verbosity': -1,  # 关闭日志输出
   'early_stopping_round': 20  # 提前停止轮数(注意参数名)
}

# 训练模型
model = lgb.train(
   params,
   train_data,
   valid_sets=[test_data],
   num_boost_round=100
)

# 预测与评估
y_pred = model.predict(X_test).argmax(axis=1)
print("Accuracy:", accuracy_score(y_test, y_pred))

# 保存模型
model.save_model('iris_model.txt')

python lightgbm-iris.py

输出:

Accuracy: 1.0

文件iris_model.txt

tree
version=v4
num_class=3
num_tree_per_iteration=3
label_index=0
max_feature_idx=3
objective=multiclass num_class:3
feature_names=Column_0 Column_1 Column_2 Column_3
feature_infos=[4.4000000000000004:7.7000000000000002] [2:4.4000000000000004] [1:6.9000000000000004] [0.10000000000000001:2.5]
tree_sizes=351 542 451 358 559 558 357 557 558 358 562 556 359 561 559 462 560 556 357 560 560 359 559 560 357 559 560 359 559 562 359 558 562 359 662 562 358 560 562 359 559 561 358 559 561 358 557 559 463 557 562 358 667 559 357 562 457 358 562 458 359 663 460 464 562 460 462 564 458 358 670 562 460 668 459 461 563 461 358 565 559 358 664 562 358 666 556 357 767 461 356 659 564 357 668 560 358 768 564 358 663 562 360 770 566 361 665 668 360 564 764 361 666 563 361 769 665 470 773 566 362 666 766 467 772 567 361 872 669 361 668 774 471 666 569 361 672 772 363 768 776 467 770 567 363 460 573 363 570 773 363 772 574 361 880 571 362 672 571 362 569 565 363 670 566 362 666 777 364 671 574 363 775 670 362 668 565 363 777 566 364 669 673 472 674 573 363 779 678 364 674 673 362 672 669 365 676 569 365 674 569
。。。

回归任务(波士顿房价数据集)

import lightgbm as lgb
import numpy as np
from sklearn.datasets import fetch_openml
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split

# 加载数据
boston = fetch_openml(name='boston', version=1)
X, y = boston.data, boston.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 转换为LightGBM数据集格式
train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

# 参数配置
params = {
   'objective': 'regression',  #回归任务
   'num_leaves': 64,
   'learning_rate': 0.05, #学习率(步长)小学习率需更多树
   'min_data_in_leaf': 10, # 叶子节点最小样本数
   'metric': 'rmse', # 'rmse' 用于指定模型在训练和验证过程中使用的评估指标为 •均方根误差(Root Mean Squared Error, RMSE)
   'early_stopping_round': 50  # 提前停止轮数
}

# 训练与验证
model = lgb.train(
   params,
   train_data,
   valid_sets=[test_data],
   num_boost_round=500
)

# 预测与评估
y_pred = model.predict(X_test)
rmse = np.sqrt(mean_squared_error(y_test, y_pred))  # 手动计算RMSE
print("RMSE:", rmse)

python lightgbm-boston.py

运行结果:

[LightGBM] [Info] Auto-choosing col-wise multi-threading, the overhead of testing was 0.000338 seconds.
You can set `force_col_wise=true` to remove the overhead.
[LightGBM] [Info] Total Bins 1031
[LightGBM] [Info] Number of data points in the train set: 404, number of used features: 13
[LightGBM] [Info] Start training from score 22.480693
[LightGBM] [Warning] No further splits with positive gain, best gain: -inf
Training until validation scores don't improve for 50 rounds
Did not meet early stopping. Best iteration is:
[489]   valid_0's rmse: 3.02607
RMSE: 3.026067608496124

模型在训练和验证过程中使用的评估指标为均方根误差(Root Mean Squared Error, RMSE)值为3.02。

6. 调参建议

  1. 先固定learning_raten_estimators:通常从0.1100开始,后续调整其他参数后再优化迭代次数。
  2. 调节num_leavesmax_depth:初始值设为31-1,若过拟合则逐步减少。
  3. 正则化参数:通过lambda_l1lambda_l2min_data_in_leaf控制模型复杂度。
  4. 随机性参数:使用feature_fractionbagging_fraction增强鲁棒性。

7. 常见问题

  • 过拟合:降低num_leaves、增加min_data_in_leaf、提高正则化系数。
  • 训练速度慢:减小max_bin、启用GPU('device': 'gpu')、降低num_leaves
  • 类别特征处理:将列转换为category类型后直接传入,无需独热编码。

参考资料

发表评论