一、 简介

        CatBoost 与 XGBoost 、LightGBM是主流的三大Boosting框架,都是高效的GBDT算法工程化实现框架。CatBoost 则因长于处理类别特征而取名为CatBoost(Categorical + Boosting)。算法的理论特色,包括用于处理类别变量的目标变量统计和排序提升算法。算法原文地址:CatBoost算法论文。原文结构如下:

1、Introduction(简介)

2、Background(算法提出背景)

3、Categary Features(处理类别特征)

4、Prediction shift and ordered boosting(预测偏移与有序提升算法)

5、Practical implementation of ordered boosting(有序提升的实现)

6、Experiments(实验与对比)

       其中3、4、5是论文核心,专门阐释CatBoost处理类别变量统计和排序提升算法及实施。本文对3、4、5尝试解读以阐释catboost原理。

二、 算法主要部分

     如论文简介所述,论文主要引入了两个关键算法以处理预测偏移问题:一种处理类别特征的创新算法Ordered Target Statistics 和 有序增强实现(一种排列驱动的替代经典算法)。这两种技术都是为了应对当前所有梯度增强算法实现中存在的一种被称之为的“目标泄漏”(是指特征的条件分布\hat{x}\mid y 在训练样本和测试样本中存在不同)所造成的预测偏移。

    首先是处理类别的算法,目标统计(注:目标就是一个样本(x_{k},y_{k})中的标签y_{k} ,目标统计就是用x^{i}_{k}y_{k}的期望值代替x_{k} 的类别特征值)。所有现有的梯度提升的实现通常面临以下问题,经过几步增强得到的预测模型F依赖于所有训练示例的目标。论文证明,这实际上导致训练示例x_{k}的F(x_{k}) | x_{k}的分布与测试示例x的F(x_{}) | x_{}的分布不一致,并最终导致学习模型的预测偏离。此外,在分类特征预处理的标准算法中也存在类似的问题。在梯度提升中使用它们的最有效方法之一是将类别转换为它们的目标统计值

      2.1 类别特征和目标统计

        类别特征是一种由一系列离散的且不能彼此比较的值所组成的集合,提升树通常处理类别特征的方法是独热编码,例如对每一类的取值,添加一个新的二进制特征来标志它,例如,某类离散取值有(甲类、乙类、丙类),则独热编码,增加三个特征:甲类、乙类、丙类,每一类取值0 或1 以标志某个样本是否属于某一类;然而这对于高基数的特征,比如用户ID号(通常是很大的正整数),则会导致实际不可行的大量新增的特征,如1000个取值就要新增加1000个特征,这对于算法而言会产生不小的负担。 通常解决办法是,将类别特征的取值再次分组为数量较少的几簇,然后再进行one-hot编码。还有一种方法就是使用每一类对应的标签值的统计值代替类别本身的值,譬如某个特征取值为 'm' 的n个样本 ,对应目标变量为y_{1}y_{2}y_{3}......y_{n} ,则取y_{1}y_{2}y_{3}......y_{n} 的某种统计值代替'm'。这样,特征的取值就由这些取值对应的 目标变量统计替代,而目标变量统计值的数量要比特征的取值数少,间接实现了降低特征取值数量的目的。

        正如上所述,一个有效的解决类别特征i的方法就是将样本k的第 i 个特征值x^{i}_{k} 用一个数值特征比如(TS) \hat{x}^{i}_{k} 统计。通常,这个估计值用某个类别对应的 y的期望值代替:\hat{x}^{i}_{k} \approx E(y \mid x^{i} = x_{k}^{i}) 。论文对于目标变量统计(TS)列举了 Greedy TS、HoldoutTS、Leave-one-out TS 并根据P1、P2准则(下文介绍)指出其中的不足,最后引出CatBoost提出的 ordered TS。

      Greedy TS: 估算函数最直接方式就是采用训练集中相同类别的x^{i}_{k}样本的目标变量y的平均值,这种估算方式在低频率类别上有噪声,因此常常会加先验p进行平滑。

  \hat{x_{k}^{i}} = \frac{\sum_{j=1}^{n}\mathbb{I}_{x_{j}^{i}=x_{k}^{i}}.y_{j}+a p}{\sum_{j=1}^{n}\mathbb{I}_{x_{j}^{i}=x_{k}^{i}}+a }           -------(1)

    其中i指示类别i,k指示样本k。而 \mathbb{I}_{x_{j}^{i}=x_{k}^{i}}.y_{j} 的意思是判断:当前样本j是否与样本k是同一类别i,如果是则为1,反之则为0。而先验p为数据集中对应i特征的所有目标值的均值, α 是 控制先验参与编码的权重。Greedy TS 的局限是:不满足文中提出的P1准则条件,即训练集某个样本在某个特征取新值(目标统计值)的期望 等于 测试集某个特征对应于本样本取值所对应的目标统计值的均值。

           P_{1}E({\hat{x}_{}^{i}| y=v}) = E({\hat{x}_{k}^{i}| y_{k}=v}) ,其中(x_{k},y_{k})是第k个样本。

文中举例说明,假设第 i 个是分类的,数据集此特征每个取值是唯一的,且取某个值A,y=1条件概率为0.5,因此对于每个样本的x^{i}_{k} ,TS值为\hat{x_{k}^{i}} =  \frac{y_{k} + ap}{1+a} ,因此 t = \tfrac{0.5+ ap}{1+a}  可以完整的区分所有的训练样本,然而对于测试样本,greedy TS 的值为 \hat{x_{k}^{i}} = p  。因而,对于上述例子说明,样本\hat{x_{k}^{i}} 目标值的期望E(\hat{x}_{k}^{i}| y_{k}) = \frac{y_{k} + ap}{1+a}不等于 测试集样本目标值的期望E(\hat{x}^{i} | y) = p,从而会导致目标泄露,进而会导致预测偏移。

    有很多方法可以防止条件偏移,常见的策略就是统计某个样本的TS时,将样本排除在外,即用

D_{k}\subset D \setminus \{x_{k}\},  得到下式:

\hat{x_{k}^{i}} = \frac{\sum_{x_{j}\in D_{k}}^{}\mathbb{I}_{x_{j}^{i}=x_{k}^{i} }\cdot y_{j} + ap}{\sum_{x_{j}\in D_{k}}^{}\mathbb{I}_{x_{j}^{i}=x_{k}^{i} }\cdot y_{j} +a}  ----------(2)

HoldoutTS:就是把训练集分成两部分,用一部分按公式2计算TS值,然后用另一部分训练,这种方法满足准则1,且明显减少了训练和计算TS值得数据量,但是,它不满足以下准则2:

                                   P_{2}:  有效地使用所有数据计算TS值和学习一个模型

Leave-one-out TS: 留一法 ,是将D去除样本{x_{k}} 后 计算  {x_{k}} 的TS值,并训练,而测试集则用全部的数据集(即并不排除测试样本本身)。文中同样举一特例,说明在这种情况下x^{i}_{k} 的TS取值\frac{n^{+} - y_{k} + ap}{n-1+a}  并且存在一个可划分所有训练样本的阈值。因此不满足准则1。

Ordered TS:  就是本文要重点引出的,它受在线学习按时间序列取得训练数据的处理方式启发,认为每样本的TS值依赖于观测的历史取值。为了将其移植到离线方式,引入虚拟的“人工时间”,就是把样本的一个排列δ看成一个时间序列,然后对于这个时间序列,对于每个样本 {x_{k}} ,取D_{k} ={ x_{j} : \sigma (j) < \sigma(k) } ,用公式(2)计算训练样本的TS值,而对于测试集取全部的 D_{k} = D 用来计算测试样本的TS值。Ordered TS 满足准则1和准则2。但是,如果只用一个排列σ 则排列在前面的样本TS值会比后面的有更高的方差,(因为后者用于计算TS值更多),因此在CatBoost对于梯度提升的不同轮次,采用了不同的排列,来解决这个问题。就是通过多次排列,训练集中的每个样本排在各个位置的概率相近,从而总体实现各样本相同的方差。

        2.2 预测偏移

         原文揭示了在梯度提升中存在的预测偏移。假设前一轮训练得到的强分类器为F^{t-1},则本轮迭代要拟合的弱分类器为h^{t},h^{t}的理想表达式为:

h^{t} = argmin_{h\in H}E(-g^{t}(x,y) - h(x))^{2}   ---------(3)

公式表明h(x)就是拟合本轮强分类器负梯度(实际计算中,可用上一轮分类器F^{t-1}表示)的最优值,上式在实际计算的近似式为:

h^{t} = argmin_{h\in H}\frac{1}{n}\sum_{k=1}^{n}(-g^{t}(x_{k},y_{k}) - h(x_{k}))^{2}   ----------(4)

由上式可知,最终预测偏移的链式传递为:

           1、训练样本梯度g^{t}(x_{k},y_{k} ) | x_{k} 的条件分布与测试样本梯度g^{t}(x_{},y_{} ) | x_{}条件分布存在偏移。

           2、h^{t} 的近似公式(4)和理想公式(3)存在偏移。

           3、前二者最终会影响F^{t} 的泛化性能。

          建立F^{t-1}的所有数据点的TS值,会在每一轮次被重复使用以计算梯度,而训练样本的分类器的条件分布F^{t-1}(x_{k})|x_{k}与 测试样本  F^{t-1}(x_{})|x_{} 的条件分布不一致,文中称之为预测偏移。

         关于预测偏移的分析:以二次损失函数L(y,\hat{y)} = (y-\hat{y})^{2}的形式简单地分析了回归任务的简单预测转移问题。 在这种情况下,公式(4)中的负梯度-g^{t}(x_{k},y_{k} )可以用残差函数r^{t-1}(x_{k},y_{k} ) = y_{k} - F^{t-1}(x_{k})代替。 假设我们有m = 2个特征x_{1}x_{2},独立同分布的伯努利随机变量,其中p = 1/2和y = f^{*}= c_{1}x_{1} + c_{2}x_{2}。 假设我们用决策树桩(深度为1的树)且步长为α= 1来进行N = 2步的梯度增强。获得模型F=F^{2} = h_{1} + h_{2}。假设h_{1}基于x_{1}h_{2}基于x_{2},这对于 |c_{1} | > | c_{2} | (这里在x_{1}x_{2}之间设置了一些不对称性)。

       根据以上假定,原文引出定理1(证明见原文附录Section A): 如果使用等式(4)分别使用大小为n的两个独立样本D_{1}D_{2}估计h_{1}h_{2},则E_{D_{1},D_{2}}F^{2}(x) = f^{*}(x) + O(1/2^{n})对于任何x∈\{0,1\}^{2}。 2.如果对于h_{1}h_{2}在公式(4)中使用相同的数据集D=_{}D_{1} =D_{2},则E_{D_{}}F^{2}(x) = f^{*}(x) -\frac{1}{n-1}c_{2} (x^{2}- 1/2)+ O(1/2^{n})

      定理说明:如果在加性模型的梯度提升的每一轮中,分别使用不同的独立样本集,则训练的模型是真实模型y = f^{*}(x) 的无偏估计,而如果每一轮中使用相同的样本集,则训练模型与真实模型存在\frac{1}{n-1}c_{2} (x^{2}- 1/2) 的偏差。这就从理论上证明并精确估计了偏差。

      2.3 有序提升算法

          基于以上的预测偏移,原文提出了一种称之为有序提升算法。假如训练集数据无限大,则容易构建一个算法。在这个提升算法的每一步,可以独立选取一个独立的新的数据集,然后可以用这个数据集训练得的模型计算在新训练样本上的无偏移残差。然而在实际中,标签数据是有限的,假设训练至有I棵树的模型,为了使残差r^{I-1}(x_{k},y_{k}) 的计算无偏移,需要在F^{I-1}中排除x_{k},这样为了使所有训练样本的残差计算无偏移,则没有样本用来训练F^{I-1}。这似乎让训练成为不可能。实际上,可以用模型训练所使用的样本来区分而得到一系列的模型,这样选取不包含这个样本的模型就可以计算这个样本的残差。为了构建这一些模型,可以采用之前ordered TS的方法。具体就是,选取一个样本的随机排列\sigma,然后训练n个支撑模型M_{1} 、M_{2}M_{3}........M_{n},其中M_{i} 模型是用排列\sigma的前i个样本训练得出。在每一步为了获得第j个样本的残差,使用模型M_{j-1}, 这样的算法就称之为有序提升算法。这种算法需要训练n个模型,增加了计算复杂度和存储。在CatBoost 中,提出了一种针对有序提升算法的修改方法,该修改方法就是图4中10-12行。

     在ordered TS 和 ordered boosting中,都相应地采用了训练样本的\sigma_{cat} 、\sigma_{boost} 排列用来计算,如果在一个算法中都采用两者,则需要\sigma_{cat} = \sigma_{boost} 以避免预测偏移。这样确保了标签值y_{i} 没有被用于训练M_{i} (即没有参与ordered TS 计算),可以设想\sigma_{cat} 不等于\sigma_{boost},而如果在\sigma_{cat} 使用了y_{i} ,则在\sigma_{boost} 中虽然没有用y_{i}y_{i}也参与了 ordered TS 的计算,这样就会存在 TS计算分析中存在的预测偏移。   

      2.4 有序提升算法的实现

      CatBoost 有两种提升模式,普通模式和有序模式,前者就是标准的梯度提升树中内嵌了ordered TS ,而后者就是在Algorithm1(如图1所示)算法基础上的改进。

                                                                         图1 有序提升算法的Algorithm1 

Algorithm1:该算法图是一个原理概略图(详见附录的正式算法图),输入是n个样本集合和树的棵数(对于Boosting ,其实就是迭代次数,不同树是叠加迭代关系),σ 是[1,n] 的一个排列,M_{i} 就是上文提出的支撑模型,对应于不同的训练样本集,首先初始化为0 ; 算法有三个循环,第一个循环控制迭代次数,就是梯度提升次数,每一次对应构建了一个梯度树,前一次在后一次的基础上提升。第二个循环就是 拟合前计算残差,每一次残差的计算,都用到了上一轮生成的M_{i} 系列模型,具体对应于样本Xi 在排列中的 序数 -1 即 \sigma (i) -1 的M ,M_{\sigma (i) -1} 用来生成预测值,从而用于计算残差。第三个循环和第二个循环并列,用于将在排列中前于等于i 的所有样本的残差值拟合成一棵残差树△M,然后用△M 更新M_{i} 每一迭代次数M_{1} 、M_{2}M_{3}........M_{n} 都得到了更新,经过t次迭代,得到最终的(M_{1} M_{2} M_{3} ......M_{n} )_{I} 。(当 \sigma (i) =1 时 j 取值使得 \sigma (j) =1 ,从而 j =i)

图2 采用有序提升算法构建一棵树

    Algorithm2:

        不同参数含义:  \{(x_{i},y_{i})\}_{i=1}^{n} :训练集;α :学习率;L :损失函数类型;Mode: 提升模式; 

        该算法图也是一个原理概略图(详见附录的正式算法图),描述的是构建一棵树的情形。输入M 其实是一个 对应于排列集合\{\sigma \}_{i=1}^{s} 的 数组,在ordered 模式下,M采用Algorithm1得到,在plain模式下,M采用了普通的GBDT提升树算法拟合,其次用梯度计算公式,计算对应模型的梯度数组,grad_{r} 对应于 \sigma _{r} 。对于两种模式计算相应的梯度数组G,对于Plain 模式,G = \{grad_{r}(1) - grad_{r} (2)---grad_{r}(3) ----grad_{r}(i) \} ,对应于 ordered 的模式 G= \{grad_{1 ,\sigma _{r}(1) -1}(1) --grad_{1 ,\sigma _{r}(2) -1}(2) --grad_{1 ,\sigma _{r}(i) -1}(i)--\}  ,每一次构建一个树时,选择一个随机排列\sigma _{r}。然后自顶而下构建一棵树,在每个节点分裂时,候选出可分裂的节点值c,计算预分裂后每个样本在节点的平均梯度值 ,然后结合样本点已有的梯度,计算余弦相似度损失函数,选取余弦相似度损失函数最小值对应的c 进行分裂,以此方式分裂直至整棵树完成。 最后将生成的树用于更新所有预先生成的M数组,也分成plain模式和ordered 模式。(可见,每次迭代生成的树拟合了某一随机排列下的训练集,综合了训练集的有用信息,而将每次迭代生成的树用于更新M数组,就可以使用更新的数组包含前一排列训练集的有用信息,以创建下一个树,同时经过多次迭代,M数组中,每个样本对应的M_{i} 可以降低方差)这样就完成了一棵树的构建,经过多次迭代,得到t棵树,用于构建最终树,和最终树对应的M数组。

      原文内容:

      CatBoost 产生s+1 个独立的随机排列。\sigma _{1} \sigma _{2} \sigma _{3} -\sigma _{s}用于评估树节点分裂,产生一棵树。\sigma _{0} 用于计算 已获得树的叶节点值;对于在给定的排列中前序很短的例子,有序提升使用的TS和预测(算法1中的Mσ(i)−1(xi))都有很大的方差。因此,仅使用一种排列可能会增加最终模型预测的方差,而使用多种排列则减少这种影响,后续会继续描述。在第6节的实验证实了采用多种排列的优点。

      构建一颗树:

      在CatBoost中,基本的预测器是oblivious树,oblivious是指在整个树的同一层次上使用相同的分割标准,即是用相同的特征进行分割。这样的树是平衡的,不容易过度拟合,并允许在测试时间显著加快执行。在CatBoost中建立树的过程在Algorithm2中描述。

     在有序提升模式中,在学习过程中,维持一个支持模型序列M_{r,j},其中M_{r,j}(i)是基于排列\sigma _{r}中前j个例子的对第i个例子的当前预测。在算法的每一次迭代t中,我们从{σ1,…,σs}随机选择一个\sigma _{r},并在此基础上构造树T_{r}。首先,对于类别特征,根据这种排列计算所有的TS值。其次,排列影响树的学习过程。即,基于M_{r,j}(i),计算相应的梯度grad_{r,j} = \frac{\partial L(y,s)}{\partial s} \mid _{s=M_{r,j}(i)}。然后,在构造树的时候,用余弦相似度cos(·,·)来近似梯度G。其中,对于每个例子i,我们取梯度grad_{r,j}(i)(它仅基于在σr中排在i之前的例子)。在候选拆分评估步骤中,叶片值∆(i)例如i分别通过对位于实例i所属叶片Leaf_{r}(i)中的且在\sigma _{r}排列中先于i的p梯度grad_{r,\sigma_{i} -1}平均值得到。注意,Leaf_{r}(i)依赖于所选择的排列σr,因为σr可以影响样本i 的ordered TS值。让我们强调一下,当Tt树构建后,这个数被用于更新所有M数组系列,但是这棵树根据r{}'和j的不同,被添加到不同的M_{r{}',j}上,,如算法Algorithm2所述。

      纯提升模式的工作原理与标准的GBDT过程相似,但是,如果有分类特征,它在σ1的基础上维持一个与TS对应的支持模型Mr ,而TS值与\sigma _{1} \sigma _{2} \sigma _{3} -----\sigma _{s} 对应。

     选择叶节点:当所有树构建完成后,叶子结点的值就可以通过最终模型F 计算,而F是基于标准的GBDT树 等权加总每个子树得到。而训练样本i 匹配到Leaf_{0}(i) 中,就是基于\sigma _{0}计算样本i的TS值。当最终模型应用于新的测试实例时,所有基于训练样本计算的TS值就会被使用,将其用于分配给Leaf_{r,i} ,便于F模型中的Getleaf(x,T_{t},Mode) 函数判断样本所属叶子结点使用。(和更新模型使用)

     模型复杂度:

其中Calc ordered TS的时间复杂度是指 在第t棵树中查找样本并计算一个样本的TS值得平均时间(N_{TS_{t}})乘以样本数n。

     特征组合:CatBoost的另一个重要细节是使用分类特征的组合作为附加的分类特征。可能的组合的数量随着分类特征的数量呈指数增长,对所有分类特征进行处理是不可行的。CatBoost以一种贪婪的方式构造组合。也就是说,对于树的每一个分割,CatBoost将所有分类特征(及其组合)与数据集中的所有分类特征结合(连接)。前者是指:在当前树中已经用于分割的所有分类特征(及其组合)。组合被动态转换为TS。

    

三、附录正式算法伪代码

图3 CatBoost 正式算法图

     图 4 更新模型算法

图5 构建树

四、参考资料

         https://blog.csdn.net/qq_41185868/article/details/112384070

         https://blog.csdn.net/u014686462/article/details/83543609

         https://blog.csdn.net/appleyuchi/article/details/85413352

         https://blog.csdn.net/qq_24591139/article/details/100104812

         https://zhuanlan.zhihu.com/p/540956200

       

           

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐