【机器学习第三期(Python)】CatBoost 方法原理详解

发布于:2025-07-02 ⋅ 阅读:(21) ⋅ 点赞:(0)

CatBoost 和 XGBoost、LightGBM 并称为 GBDT 的三大主流神器,都是在 GBDT 算法框架下的一种改进实现。XGBoost 被广泛的应用于工业界,LightGBM 有效的提升了 GBDT 的计算效率,而 Yandex 的 CatBoost 号称是比 XGBoost 和 LightGBM 在算法准确率等方面表现更为优秀的算法。

XGBoost 的详细介绍可参考另一博客-【机器学习第二期(Python)】优化梯度提升决策树 XGBoost,本博客主要对CatBoost 方法进行解释说明。

一、CatBoost 简介

CatBoost(Categorical Boosting) 是由 Yandex 开发的基于 梯度提升决策树(GBDT) 的机器学习框架,其主要优势在于:

  • 原生支持类别特征(无需 One-Hot)
  • 高效处理数据偏差与过拟合
  • 训练速度快、预测准确性高
  • 自动处理缺失值与类别处理顺序问题

CatBoost vs XGBoost 对比

特性 CatBoost XGBoost
类别特征支持 ✅ 原生支持,无需 One-Hot ❌ 需手动 One-Hot 编码
编码方式 Ordered Target Encoding 手动编码
防止目标泄露 ✅ Ordered Boosting ❌ 默认不防止
特征重要性解释 ✅ 支持 ✅ 支持
多线程支持 ✅ 高效 ✅ 高效
GPU 支持 ✅ 有 ✅ 有
训练速度 🚀 快于 XGBoost(对类别数据尤为明显) 一般较快,但类别编码耗时
使用门槛 ✅ 简单(少调参) 需要更多调参

二、CatBoost 原理详解

🎯 1. 核心思想:Gradient Boosting

CatBoost 仍然是通过迭代构建弱模型(决策树)来拟合残差,优化目标函数。

与 XGBoost 和 LightGBM 不同,CatBoost 构建对称(平衡)树。在每一步中,前一棵树的叶子都使用相同的条件进行拆分。选择损失最低的特征分割对并将其用于所有级别的节点。这种平衡的树结构有助于高效的 CPU 实现,减少预测时间,模型结构可作为正则化以防止过度拟合。

🧬 2. 类别特征的处理(关键差异)

CatBoost 提出了 Ordered Target Statistics(顺序目标编码):

  • 避免了目标泄露(Target Leakage)
  • 比 One-Hot 更高效,避免维度膨胀

🔁 3. Ordered Boosting(顺序提升)

与传统 GBDT 不同,CatBoost 采用“顺序性”思想:

  • 构造每一棵树时,样本的顺序影响模型训练
  • 避免使用当前样本的真实标签来计算残差(防止过拟合)

三、XGBoost 实现步骤(Python)

库包安装:

conda install catboost

绘制的效果图如下:
在这里插入图片描述
左图:拟合效果:拟合曲线很好地捕捉了数据的非线性趋势。

  • 蓝点:训练数据
  • 红点:测试数据
  • 黑线:GBDT 拟合曲线

右图:残差图:残差应随机分布在 y=0 附近,没有明显模式,表明模型拟合良好。

输出结果为:

CatBoost Train MSE: 0.0305
CatBoost Test MSE: 0.0354

完整Python实现代码如下:

import numpy as np
import matplotlib.pyplot as plt
from catboost import CatBoostRegressor
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error

# 设置字体
plt.rcParams['font.family'] = 'Times New Roman'


# 1. 生成数据
np.random.seed(42)
X = np.linspace(0, 10, 200).reshape(-1, 1)
y = np.sin(X).ravel() + np.random.normal(0, 0.2, X.shape[0])

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

# 3. 训练 CatBoost 模型
model = CatBoostRegressor(
    iterations=100,
    learning_rate=0.1,
    depth=3,
    loss_function='RMSE',
    verbose=0,  # 不输出训练过程
    random_seed=42
)

model.fit(X_train, y_train)

# 4. 预测与评估
y_train_pred = model.predict(X_train)
y_test_pred = model.predict(X_test)

train_mse = mean_squared_error(y_train, y_train_pred)
test_mse = mean_squared_error(y_test, y_test_pred)

print(f"CatBoost Train MSE: {train_mse:.4f}")
print(f"CatBoost Test MSE: {test_mse:.4f}")

# 5. 可视化
plt.figure(figsize=(12, 6))

# 拟合曲线图
plt.subplot(1, 2, 1)
plt.scatter(X_train, y_train, color='lightblue', label='Train Data', alpha=0.6)
plt.scatter(X_test, y_test, color='lightcoral', label='Test Data', alpha=0.6)

X_all = np.linspace(0, 10, 1000).reshape(-1, 1)
y_all_pred = model.predict(X_all)
plt.plot(X_all, y_all_pred, color='green', label='CatBoost Prediction', linewidth=2)

plt.title("CatBoost Model Fit", fontsize=15)
plt.xlabel("X", fontsize=14)
plt.ylabel("y", fontsize=14)
plt.legend()
plt.grid(True)

# 残差图
plt.subplot(1, 2, 2)
train_residuals = y_train - y_train_pred
test_residuals = y_test - y_test_pred

plt.scatter(y_train_pred, train_residuals, color='blue', alpha=0.6, label='Train Residuals')
plt.scatter(y_test_pred, test_residuals, color='red', alpha=0.6, label='Test Residuals')
plt.axhline(y=0, color='black', linestyle='--')
plt.xlabel("Predicted y", fontsize=14)
plt.ylabel("Residuals", fontsize=14)
plt.title("Residual Plot", fontsize=15)
plt.legend()
plt.grid(True)

plt.tight_layout()
plt.show()

参考

1、知乎-彻底理解机器学习模型 CatBoost 原理、代码及应用