catboost学习笔记


原文链接

优势对比

CatBoost和XGBoost、LightGBM并称为GBDT的三大主流神器,都是在GBDT算法框架下的一种改进实现。

正如其名字所说那样,CatBoost主要是在类别特征上的处理上做了很多的改进。

从用户使用角度来看,相比XGBoost和LightGBM,CatBoost具有如下特点。

模型精度:XGBoost和LightGBM相当,CatBoost往往略好一些,无需调参即可获取很好的结果。
训练速度:LightGBM远快于XGBoost,CatBoost快于XGBoost但比LightGBM慢。
预测速度:LightGBM与XGBoost相当,CatBoost远快于LightGBM与XGBoost,是它们的几十分之一。
内存消耗:LightGBM远小于XGBoost,CatBoost小于XGBoost,但大于LightGBM。
类别特征:XGBoost不支持类别特征,需要OneHot编码预处理。LightGBM支持类别特征,需转换成整数编码。CatBoost提供更强大的对类别特征的支持,直接支持字符串类型的类别特征,无需预处理。
缺失值特征:XGBoost和LightGBM都可以自动处理特征缺失值,CatBoost不能自动处理缺失值(或者将缺失值视为最小值/最大值)。
GPU支持:LightGBM与CatBoost支持GPU训练,XGBoost不支持GPU训练。
可视化:CatBoost还自带一套可视化工具,可以在Jupyter Notebook或者TensorBoard中实时看到指标变化。

创新点

CatBoost主要创新点如下:

1.类别特征的 Ordered Target Statistics 数值编码方法。

其次,它用特殊的方式处理categorical features。
首先他们会计算一些数据的statistics。计算某个category出现的频率,加上超参数,生成新的numerical features。这一策略要求同一标签数据不能排列在一起(即先全是0之后全是1这种方式),训练之前需要打乱数据集。
第二,使用数据的不同排列(实际上是4个)。在每一轮建立树之前,先扔一轮骰子,决定使用哪个排列来生成树。
第三,考虑使用categorical features的不同组合。例如颜色和种类组合起来,可以构成类似于blue dog这样的feature。当需要组合的categorical features变多时,catboost只考虑一部分combinations。在选择第一个节点时,只考虑选择一个feature,例如A。在生成第二个节点时,考虑A和任意一个categorical feature的组合,选择其中最好的。就这样使用贪心算法生成combinations。
第四,除非向gender这种维数很小的情况,不建议自己生成one-hot vectors,最好交给算法来处理。参考

target statistic详解

1.1 什么是预测偏移?
在GBDT一类模型中,弱学习器模型均在同一完整训练集上训练,然后不断提升成强学习器,但如果训练集和测试集存在分布不一致,模型就会过拟合训练集而在测试集上表现不好 (即预测偏移到训练集上),预测偏移也算是目标泄露 (Target Leakage)的一种。
预测偏移发生在哪里?
预测偏移发生在两个地方:类别特征编码和梯度提升方法。
(1) 类别特征编码中的预测偏移

  1. GBDT:直接把类别型当作连续型数据对待。

  2. XGBoost:建议提前对类别特征One-hot编码后再输入模型。

  3. LightGBM:在每步梯度提升下,将类别特征转为GS (梯度统计Gradient Statistics)。注:很对不起,【务实基础】LightGBM 中 “5. 支持类别特征” 这块存在错误,LGBM不是采用TS编码 (目标统计Target Statistics,即平均值\(\frac{\operatorname{sum}(y)}{\operatorname{count}(y)}\),而是GS编码,将类别特征转为累积值\(\frac{\operatorname{sum}(\text { gradient })}{\operatorname{sum}(\text { hessian })}\), (一阶偏导数之和/二阶偏导数之和)再进行直方图特征排序 [2]。

虽然LGBM用GS编码类别特征看起来挺厉害的,但是存在两个问题:

计算时间长:因为每轮都要为每个类别值进行GS计算。
内存消耗大:对于每次分裂,都存储给定类别特征下,它不同样本划分到不同叶节点的索引信息。
为了克服以上问题,LGBM将长尾特征聚集到一类,但也因此丢失了部分信息。对此,Catboost作者认为,LGBM的GS没有TS好,因为TS省空间且速度快,每个类别存一个数就好了。但TS不是完美的,因为它存在预测偏移。这很明显,因为TS是依赖训练集的目标标签进行类别特征编码(算是目标泄露),如果训练集和测试集分布过大,那么类别编码就会偏移向训练集,导致模型的通用性差。

如果我们要了解“预测偏移是怎么发生在TS类别特征编码 (也称目标编码Target Encoding) 过程当中?”,我们得先了解下TS的编码机制。

一个有效且高效处理类别型特征的方法是用一个 TS编码的数值型变量 \(\hat{x}_{i}^{k}\) 来替代第 \(k\) 个训练样本的 类别 \(x_{i}^{k}\) 。通常来说, TS是基于类别的目标变量 \(\mathrm{y}\) 的期望来进行估算: \(\hat{x} i^{k} \approx \mathbb{E}\left(y \mid x^{i}=x_{k}^{i}\right)\) 。 直白来说, \(\hat{x} i^{k}\)\(\mathrm{TS}\) 编码值, \(\mathbb{E}\left(y \mid x^{i}=x_{k}^{i}\right)\) 是基于目标变量y估算函数。

图1: Greedy TS编码方式
估算函数最直接方式就是采用训练集中相同类别的 \(x_{i}^{k}\) 样本的目标变量y的平均值, 如上图所示。 这种估算方式在低基类别上有噪声, 因此常常会加先验概率p进行平滑:

\[\hat{x} i^{k}=\frac{\sum_{j=1}^{n} \mathbb{I}_{\left\{x j^{i}=x_{k}^{i}\right\}} \cdot y_{j}+a p}{\sum_{j=1}^{n} \mathbb{I}_{\left\{x j^{i}=x_{k}^{i}\right\}}+a} \]

i指示类别i, \(\mathrm{k}\) 指示样本 \(\mathrm{k}\) 。而 \(\mathbb{I}\left\{x j^{i}=x_{k}^{i}\right\}\) 的意思是判断:当前样本j是否与样本 \(\mathrm{k}\) 是同一类别i, 如果是则为 1 , 反之则为 0 。而先验概率 \(p\) 为数据集所有目标值的均值, \(\alpha\) 是控制先验参与编码的 权重。
现在, 我们举个具体的例子, 看下预测偏移是怎么影响模型通用性。假设特征为类别型且它的值 都是独特的 (unique)。那么如果TS编码就会发生严重的目标泄露, 如下图所示:

图2: Greedy TS编码出现目标泄露的样例
有几种方法可以避免条件偏移 (Conditional shift)。其中一个通用的想法是为x_k计算其TS时, 用 除去 \(x_{k}\) 后的样本集 \(D_{k}\) 去计算, \(D_{k} \subset D \backslash\left\{x_{k}\right\}\)

\[\hat{x} i^{k}=\frac{\sum_{x_{j} \in D_{k}} \mathbb{I}\left\{x j^{i}=x k^{i}\right\} \cdot y_{j}+a p}{\sum_{x_{j} \in D_{k}} \mathbb{I}\left\{x j^{i}=x k^{i}\right\}+a} \]

(2) 梯度提升方法中的预测偏移
我们已经知道TS因目标泄露带来预测偏移。那接下来, 我们来看下GBDT一类模型中, 它们梯度提 升方法里的预测偏移是在哪发生的。我们先简单回顾下GBDT的梯度提升方法。假设我们上一轮获 得强学习器 \(F^{t-1}\), 那么, 当前第 \(\mathrm{t}\) 轮下的强学习器为: \(F^{t}=F^{t-1}+\alpha h^{t} 。 h^{t}\) 为第t轮的弱 学习器, \(\alpha\) 为学习率。 \(h^{t}\) 目标是使损失函数最小化:

\[h^{t}=\underset{h \in H}{\operatorname{argmin}} L\left(F^{t-1}+h\right)=\underset{h \in H}{\operatorname{argmin}} \mathbb{E} L\left(y, F^{t-1}(x)+h(x)\right) \]

最小化问题可通过牛顿法或梯度下降求解。在梯度下降中, GBDT是用损失函数的负梯度去帮助拟 合, 负梯度如下:

\[g^{t}(x, y):=-\left.\frac{\partial L(y, s)}{\partial s}\right|_{s=F^{t-1}(x)} \]

还记得我在之前文章里说过, GBDT当前轮的弱学习器是拟合上一轮的负梯度值, 因此, \(h^{t}\) 可以 为:

\[h^{t}=\underset{h \in H}{\operatorname{argmin}} \mathbb{E}\left(-g^{t}(x, y)-h(x)\right)^{2} \]

如果训练集和测试集分布不一致, 那么用训练集得到的梯度值分布就跟测试集的梯度值分布不一 致, 那么便会有预测偏移, 最终影响了模型的通用性。

order taget statistic

Catboost针对类别特征TS编码时发生的预测偏移采用了Ordered TS方法,针对梯度提升方法中的偏移采用Ordered Boosting方法。
a: Ordered TS
之前在背景里有讲Greedy TS的编码思路,但其实还有其它TS编码方式。这里,我根据论文整理了下Greedy TS、Holdout TS和Leave-one-out TS的编码思路对比图如下:

图3:其它常见TS编码方式对比图
我们发现, 常见的TS的编码方式没有平衡好"充分利用数据集“和"目标泄露“。Catboost作者受到 在线学习算法 (即随时间变化不断获取训练集) 的启发, 提出了Ordered TS。Ordered TS是基于排 序原则, 对于每个样本的TS编码计算式依赖于可观测的样本。为了使这个想法符合标准线下设 定, 作者人为构造了"时间"。具体步骤如下:
(1) 随机打乱训练集, 获取一个随机排列顺序 \(\sigma\)
(2) 在训练集中, 用 \(x_{k}\) 的"历史"样本去计算样本 \(x_{k}\) 的TS, 即训练集采用 \(D_{k}=\left\{x_{j}: \sigma(j)<\sigma(k)\right\}\)
(3) 在测试集中, 用全测试集数据去计算 \(x_{k}\)\(\mathrm{TS}\)
该方法既充分利用了数据集, 又避免了目标泄露。 \(D_{k}=D\) 注意如果只用一个随机排列顺序, 那 么最高进行 \(T S\) 编码的样本会比后面才TS编码的样本具有更高方差 (即先编码比后编码更欠拟合), 因此, Catboost在不同梯度提升轮数中采用不同的排列顺序去计算 \(\mathrm{TS}\), 这样模型的方差会变低, 利于拟合。
为了方便理解,我画了个Ordered TS的计算样例图:

其余参考推断参考:https://zhuanlan.zhihu.com/p/346420728

2.基于贪心策略的特征组合方法。

3.避免预测偏移的 Ordered Boosting 方法。

4.使用对称二叉树作为基模型,有正则作用且预测极快。

Catboost使用对称树。XGboost一层一层地建立节点,lightGBM一个一个地建立节点,而Catboost总是使用完全二叉树。它的节点是镜像的。Catboost称对称树有利于避免overfit,增加可靠性,并且能大大加速预测等等。
具体可以参考这篇文章:https://www.zhihu.com/question/311641149/answer/593286799

原理推导

个人觉得这个写的很详细,看上去是读过原文的https://zhuanlan.zhihu.com/p/102570430?utm_source=qq

代码实现

https://catboost.ai/en/docs/concepts/python-installation

参考文章
Anna Veronika Dorogush, Andrey Gulin, Gleb Gusev, Nikita Kazeev, Liudmila Ostroumova Prokhorenkova, Aleksandr Vorobev "Fighting biases with dynamic boosting". arXiv:1706.09516, 2017
Anna Veronika Dorogush, Vasily Ershov, Andrey Gulin "CatBoost: gradient boosting with categorical features support". Workshop on ML Systems at NIPS 2017

posted @ 2022-04-17 16:29  高文星星  阅读(822)  评论(0编辑  收藏  举报