集成学习(6)CatBoost

深入理解CatBoost

深入理解CatBoost - Microstrong的文章 - 知乎 https://zhuanlan.zhihu.com/p/102540344

本文主要内容概览:

img

一、CatBoost简介

CatBoost是俄罗斯的搜索巨头Yandex在2017年开源的机器学习库,是Boosting族算法的一种。CatBoost和XGBoost、LightGBM并称为GBDT的三大主流神器,都是在GBDT算法框架下的一种改进实现。XGBoost被广泛的应用于工业界,LightGBM有效的提升了GBDT的计算效率,而Yandex的CatBoost号称是比XGBoost和LightGBM在算法准确率等方面表现更为优秀的算法。

CatBoost是一种基于对称决策树(oblivious trees)为基学习器实现的参数较少、支持类别型变量和高准确性的GBDT框架,主要解决的痛点是高效合理地处理类别型特征,这一点从它的名字中可以看出来,CatBoost是由Categorical和Boosting组成。此外,CatBoost还解决了梯度偏差(Gradient Bias)以及预测偏移(Prediction shift)的问题,从而减少过拟合的发生,进而提高算法的准确性和泛化能力。

与XGBoost、LightGBM相比,CatBoost的创新点有:

  • 嵌入了自动将类别型特征处理为数值型特征的创新算法。首先对categorical features做一些统计,计算某个类别特征(category)出现的频率,之后加上超参数,生成新的数值型特征(numerical features)。
  • Catboost还使用了组合类别特征,可以利用到特征之间的联系,这极大的丰富了特征维度
  • 采用排序提升的方法对抗训练集中的噪声点,从而避免梯度估计的偏差,进而解决预测偏移的问题。
  • 采用了完全对称树作为基模型

二、类别型特征

所谓类别型特征,即这类特征不是数值型特征,而是离散的集合,比如省份名(山东、山西、河北等),城市名(北京、上海、深圳等),学历(本科、硕士、博士等)。在梯度提升算法中,最常用的是将这些类别型特征转为数值型来处理,一般类别型特征会转化为一个或多个数值型特征。

类别型特征基数比较低(low-cardinality features),即该特征的所有值去重后构成的集合元素个数比较少,一般利用One-hot编码方法将特征转为数值型。One-hot编码可以在数据预处理时完成,也可以在模型训练的时候完成,从训练时间的角度,后一种方法的实现更为高效,CatBoost对于基数较低的类别型特征也是采用后一种实现。

高基数类别型特征(high cardinality features)当中,比如 user ID,这种编码方式会产生大量新的特征,造成维度灾难。一种折中的办法是可以将类别分组成有限个的群体再进行One-hot编码。一种常被使用的方法是根据目标变量统计(Target Statistics,以下简称TS)进行分组,目标变量统计用于估算每个类别的目标变量期望值。甚至有人直接用TS作为一个新的数值型变量来代替原来的类别型变量。 重要的是,可以通过对TS数值型特征的阈值设置,基于对数损失、基尼系数或者均方差,得到一个对于训练集而言将类别一分为二的所有可能划分当中最优的那个。

在LightGBM当中,类别型特征用每一步梯度提升时的梯度统计(Gradient Statistics,以下简称GS)来表示。虽然为建树提供了重要的信息,但是这种方法有以下两个缺点:

  • 增加计算时间,因为需要对每一个类别型特征,在迭代的每一步,都需要对GS进行计算;
  • 增加存储需求,对于一个类别型变量,需要存储每一次分离每个节点的类别;

为了克服这些缺点,LightGBM以损失部分信息为代价将所有的长尾类别归为一类,作者声称这样处理高基数类别型特征时比One-hot编码还是好不少。不过如果采用TS特征,那么对于每个类别只需要计算和存储一个数字。

因此,采用TS作为一个新的数值型特征是最有效、信息损失最小的处理类别型特征的方法。TS也被广泛应用在点击预测任务当中,这个场景当中的类别型特征有用户、地区、广告、广告发布者等。接下来我们着重讨论TS,暂时将One-hot编码和GS放一边。

2.1 目标变量统计(Target Statistics)

CatBoost算法的设计初衷是为了更好的处理GBDT特征中的categorical features。在处理 GBDT特征中的categorical features的时候,最简单的方法是用 categorical feature 对应的标签的平均值来替换。在决策树中,标签平均值将作为节点分裂的标准。这种方法被称为 Greedy Target-based Statistics , 简称 Greedy TS,用公式来表达就是: \[ \hat{x}_k^i=\frac{\sum_{j=1}^n\left[x_{j, k}=x_{i, k}\right] \cdot Y_i}{\sum_{j=1}^n\left[x_{j, k}=x_{i, k}\right]} \]

这种方法有一个显而易见的缺陷,就是通常特征比标签包含更多的信息, 如果强行用标签的平均值来表示特征的话,当训练数据集和测试数据集数据结构和分布不一样的时候会出条件偏移问题。

一个标准的改进 Greedy TS的方式是添加先验分布项,这样可以减少噪声和低频率类别型数据对于数据分布的影响:

\[ \hat{x}_k^i=\frac{\sum_{j=1}^{p-1}\left[x_{\sigma_{j, k}}=x_{\sigma_{p, k}}\right] Y_{\sigma_j}+a \cdot p}{\sum_{j=1}^{p-1}\left[x_{\sigma_{j, k}}=x_{\sigma_{p, k}}\right]+a} \]

其中\(p\)是添加的先验项, \(a\)通常是大于 0 的权重系数。添加先验项是一个普遍做法,针对类别数较少的特征,它可以减少噪声数据。对于回归问题,一般情况下,先验项可取数据集label的均值。对于二分类,先验项是正例的先验概率。利用多个数据集排列也是有效的,但是,如果直接计算可能导致过拟合。CatBoost利用了一个比较新颖的计算叶子节点值的方法,这种方式(oblivious trees,对称树)可以避免多个数据集排列中直接计算会出现过拟合的问题。

当然,在论文《CatBoost: unbiased boosting with categorical features》中,还提到了其它几种改进Greedy TS的方法,分别有:Holdout TS、Leave-one-out TS、Ordered TS。我这里就不再翻译论文中的这些方法了,感兴趣的同学可以自己翻看一下原论文。

2.2 特征组合

值得注意的是几个类别型特征的任意组合都可视为新的特征。例如,在音乐推荐应用中,我们有两个类别型特征:用户ID和音乐流派。如果有些用户更喜欢摇滚乐,将用户ID和音乐流派转换为数字特征时,根据上述这些信息就会丢失。结合这两个特征就可以解决这个问题,并且可以得到一个新的强大的特征。然而,组合的数量会随着数据集中类别型特征的数量成指数增长,因此不可能在算法中考虑所有组合。为当前树构造新的分割点时,CatBoost会采用贪婪的策略考虑组合。对于树的第一次分割,不考虑任何组合。对于下一个分割,CatBoost将当前树的所有组合、类别型特征与数据集中的所有类别型特征相结合,并将新的组合类别型特征动态地转换为数值型特征。CatBoost还通过以下方式生成数值型特征和类别型特征的组合:树中选定的所有分割点都被视为具有两个值的类别型特征,并像类别型特征一样被进行组合考虑。

2.3 CatBoost处理Categorical features总结

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

三、CatboostQ&A

3.1 CatBoost与XGBoost、LightGBM的联系与区别?

(1)2014年3月XGBoost算法首次被陈天奇提出,但是直到2016年才逐渐著名。2017年1月微软发布LightGBM第一个稳定版本。2017年4月Yandex开源CatBoost。自从XGBoost被提出之后,很多文章都在对其进行各种改进,CatBoost和LightGBM就是其中的两种。

(2)CatBoost处理类别型特征十分灵活,可直接传入类别型特征的列标识,模型会自动将其使用One-hot编码,还可通过设置 one_hot_max_size参数来限制One-hot特征向量的长度。如果不传入类别型特征的列标识,那么CatBoost会把所有列视为数值特征。对于One-hot编码超过设定的one_hot_max_size值的特征来说,CatBoost将会使用一种高效的encoding方法,与mean encoding类似,但是会降低过拟合。处理过程如下:

  • 将输入样本集随机排序,并生成多组随机排列的情况;
  • 将浮点型或属性值标记转化为整数;
  • 将所有的类别型特征值结果都根据以下公式,转化为数值结果;

\[ avg_target =\frac{\text { countInClass }+ \text { prior }}{\text { totalCount }+1} \]

其中 countInClass 表示在当前类别型特征值中有多少样本的标记值是1;prior 是分子的初始值,根据初始参数确定。totalCount 是在所有样本中(包含当前样本)和当前样本具有相同的类别型特征值的样本数量。

LighGBM 和 CatBoost 类似,也可以通过使用特征名称的输入来处理类别型特征数据,它没有对数据进行独热编码,因此速度比独热编码快得多。LighGBM 使用了一个特殊的算法来确定属性特征的分割值。

1
2
train_data = lgb.Dataset(data, label=label, feature_name=['c1', 'c2', 'c3'], categorical_feature=['c3'])
# 注意,在建立适用于 LighGBM 的数据集之前,需要将类别型特征变量转化为整型变量,此算法不允许将字符串数据传给类别型变量参数。

(3)XGBoost 和 CatBoost、 LighGBM 算法不同,XGBoost 本身无法处理类别型特征,而是像随机森林一样,只接受数值数据。因此在将类别型特征数据传入 XGBoost 之前,必须通过各种编码方式:例如序号编码、独热编码和二进制编码等对数据进行处理。