CatBoost: 基本原理类似于常规的Gradient Boosting算法,只是在处理类别特征时,效果较好。一方面,可以自动处理分类特征,并且在训练过程中处理这些类别特征有优势;另一方面,使用了一种新的方式计算leaf-values(可降低过拟合)。它有两个版本,学习算法基于GPU实现,打分算法基于CPU实现。
categorical features: 类别特征,CatBoost中专指不必相互比较的特征,如城市名称、用户ID等等。常规的操作是在训练模型之前,将这些类别特征转换为数值型特征,如One-Hot编码。而在CatBoost中,基于统计量,将类别特征转换为数值型特征。
与One-Hot处理类别特征的方法不同,另一种处理类别特征的方法是使用样本的label value来计算一些统计量。
假设数据集 D = { ( X i , Y i } i = 1 , . . , n D=\{(X_i,Y_i\}_i=1,..,n D={(Xi,Yi}i=1,..,n, w h e r e X i = ( x i , 1 , . . . , x i , m ) , Y i ∈ R where X_i=(x_{i,1},...,x_{i,m}),Y_i∈R whereXi=(xi,1,...,xi,m),Yi∈R是label value。m个特征,有些是数值型特征,有些是类别特征。
1、处理类别特征值的最简单方法是在整个数据集上,用平均的label value来代替。则:
x i , k = ∑ j = 1 n [ x j , k = x i , k ] ∗ Y j ∑ j = 1 n [ x j , k = x i , k ] x_{i,k}=\frac{\sum_{j=1}^{n}[x_{j,k}=x_{i,k}]*Y_j}{\sum_{j=1}^{n}[x_{j,k}=x_{i,k}]} xi,k=∑j=1n[xj,k=xi,k]∑j=1n[xj,k=xi,k]∗Yj
w h e r e [ . ] where [.] where[.]表示指示函数。很显然,这会导致过拟合。例如,只有一个样本的情况下, x i , k x_{i, k} xi,k在所有数据集上等于label value的值。最直接减少过拟合的方式是将整体数据集分为两部分,一部分仅仅用来计算统计量,另一部分用来训练模型。但问题是这样做以后,计算统计量的样本将减少,并且训练样本也减少了。
2、针对以上不足,CatBoost使用一个更有效的策略,一方面可以减少过拟合,另一方面使用全部数据来训练。对数据集先随机排序,对于每个样本的该类别特征中的某个取值,转换为数值型时都是基于该样本之前的类别label value取均值,同时加入了优先级(先验值)和优先级(先验值)的权重系数。
假设 σ = ( σ 1 , σ 2 , . . . , σ n ) σ=(σ_1, σ_2, ..., σ_n) σ=(σ1,σ2,...,σn)为随机排序序列,则:
x σ p , k = ∑ j = 1 p − 1 [ x σ j , k = x σ p , k ] ∗ Y σ j + α ∗ P ∑ j = 1 p − 1 [ x α j , k = x α p , k ] + α x_{σ_{p},k}=\frac{\sum_{j=1}^{p-1}[x_{σ_{j},k}=x_{σ_{p},k}]*Y_{σ_j}+α*P}{\sum_{j=1}^{p-1}[x_{α_{j},k}=x_{α_{p},k}]+α} xσp,k=∑j=1p−1[xαj,k=xαp,k]+α∑j=1p−1[xσj,k=xσp,k]∗Yσj+α∗P
其中, P P P代表优先级, α > 0 α>0 α>0代表优先级的权重系数。加入权重是一个常规操作,并且可以降低类别特征中来自于低频次特征带来的噪声。在回归问题中,通过对数据集中的label value取均值来计算优先级;在二分类问题中,通过基于正类样本的先验概率计算优先级。
使用多序列也是有效的,但是对于多序列计算统计量的直接用法会导致过拟合,因此CatBoost使用一个新奇方法使用多序列来计算leaf values。
3、特征组合。对于几个类别特征的任意组合都可认为是一个新的特征。使用以上公式计算出来的数值型特征,可能会丢失一些信息,组合特征可以解决这个问题并且可以得到一个更有效的特征。但是,特征组合的数量会随着类别特征数量指数级增长,这在算法中不被允许
当前树中构建一个新的分割时,CatBoost使用贪心方式考虑组合特征。第一次分割时不考虑类别特征的组合,之后的分割考虑所有的特征组合,组合后的特征就会变成数值型的。CatBoost还将所有分割后的两组值作为类别型特征参与后面的组合。
4、重要实施细节。另外一种代替类别特征的方式是在数据集中计算该类别出现的次数。这种方式同样适用于特征组合。这是一个简单且高效的技术,并且CatBoost适用。
为了拟合最优的先验值,考虑几个先验值,并为每个先验值构造一个特征。
CatBoost与其它梯度提升算法类似,它每构建一颗新树,都会近似当前模型的梯度。但所有经典的boosting算法都存在有偏的逐点梯度估计带来的过拟合问题(这是由于每一层的梯度都是用已建立好的模型、用相同的数据估计得来的,而每个特征空间上的分布与真实分布存在差异),因此CatBoost试图修正梯度偏差以缓解过拟合。
构建一颗树有两个阶段:第一,选择树结构;第二,在树结构固定后计算叶节点的值。CatBoost在第二阶段采用传统的GBDT方法执行,而在第一阶段采用修正的方法—即梯度步长的无偏估计。
令 F i F^i Fi为前 i i i棵树的结构模型(已构建好的),为了使 g i ( X k , Y k ) g^i(X_k,Y_k) gi(Xk,Yk)是关于模型 F i F^i Fi的无偏梯度,需要在训练模型 F i F^i Fi时不使用样本 X k X_k Xk。由于需要所有训练样本的无偏梯度,照以上做法,将没有样本可用来训练模型 F i F^i Fi。CatBoost使用了一个技巧解决这个问题。
样本集为 { ( X k , Y k ) } k = 1 n \{(X_k,Y_k)\}_{k=1}^{n} {(Xk,Yk)}k=1n按随机序列 σ σ σ排序,树的棵树为 I I I。首先,对于样本 X k X_k Xk,初始化模型 M k M_k Mk。其次,对于每一棵树,遍历每一个样本,对前 k − 1 k-1 k−1个样本,依次计算 L o s s Loss Loss的梯度 g i g_i gi;再次,将前 k − 1 k-1 k−1个样本的 g j g_j gj和 X j X_j Xj( j = 1 , . . . , k − 1 j=1,...,k-1 j=1,...,k−1)用来构建模型 M M M;最后,对每一个样本 X k X_k Xk,用 M M M来修正初始化的 M k M_k Mk,这样就可以得到一个分隔的模型 M k M_k Mk(并且这个模型不需要这个样本用梯度估计来更新)。重复上述操作,就可以得到每一个样本 X X X的分隔模型 M M M。由此可见,每一个 M k M_k Mk都共享相同的树结构。
在CatBoost中,构建样本集的 s s s个随机序列来增强算法的鲁棒性。用不同的序列来训练不同的模型,这将不会导致过拟合。对每一个序列 σ σ σ,训练 n n n个模型 M k M_k Mk( k = 1 , . . . , n k=1,...,n k=1,...,n),构建一棵树的复杂度为 O ( n 2 ) O(n^2) O(n2), s s s个随机序列的复杂度为 O ( s n 2 ) O(sn^2) O(sn2)。CatBoost降低复杂度(至 O ( s n ) O(sn) O(sn))的一个技巧是:对每一个随机序列,基于前 2 i 2^i 2i个样本值近似样本 j j j的 M i ( X j ) M_i(X_j) Mi(Xj),令为 M i ′ ( X j ) M_i^{'}(X_j) Mi′(Xj)( i = 1 , . . . , [ l o g 2 ( n ) ] , j < 2 i + 1 i=1,...,[log_2(n)],j<2^{i+1} i=1,...,[log2(n)],j<2i+1),所以 M i ′ ( X j ) M_i^{'}(X_j) Mi′(Xj)的数量小于 ∑ 0 ≤ i ≤ l o g 2 ( n ) 2 i + 1 < 4 n \sum_{0≤i≤log_2(n)}2^{i+1}<4n ∑0≤i≤log2(n)2i+1<4n。所以对于每一个随机序列,构建每一棵树的的复杂度小于 O ( 4 s n ) = O ( s n ) O(4sn)=O(sn) O(4sn)=O(sn)。
CatBoost使用oblivious树(亦称对称数)作为基预测器(对称数与普通决策树的最大不同在于,普通决策树的每一层左右节点的判断条件不同,而对称树的每一层左右节点的判断条件相同)。这种树是平衡的并且不容易过拟合。在对称树中,每一个叶节点可以被编码成长度等于树的深度的二进制向量,先将所有浮点特征、统计信息和One-Hot编码特征二值化,然后使用二进制特征来计算预测值。所有样本的二进制特征值被存储在一个连续向量中,这个向量可以以3倍速度平行式的构建,这导致评分速度加快。
1、密集型数值特征。CatBoost利用对称树作为基学习器,并将特征离散化到固定数量的箱中以减少内存使用。在GPU的内存使用上,CatBoost至少与LightGBM一样有效。LightGBM和XGBoost有一个缺点,就是依赖于原子操作,这虽然可以很简单的处理合流内存访问,但即使在现代GPU上处理速度也很慢。事实上,直方图算法可以不用原子操作以更加有效。因此CatBoost的主要改进之处就是使用了一种不依赖于原子操作的直方图计算方法。
2、类别特征。CatBoost采用多种方式处理类别特征。对于One-Hot编码特征,不需要特殊操作,直接基于直方图方法;对于单个类别特征的统计量计算,可以在预处理阶段进行;可使用特征组合,但这最耗时和最耗内存。
因此,针对内存消耗问题,CatBoost使用完美哈希来存储类别特征以降低内存使用。由于GPU内存的限制,在CPU RAM中存储按位压缩的完美哈希,以及要求的数据流、重叠计算和内存等操作。通过哈希来分组观察。在每个组中,需要计算一些统计量的前缀和。该统计量的计算使用分段扫描GPU图元实现。
3、多GPU支持。CatBoost支持多GPU,可通过样本或特征并行化地进行分布式树学习。采用训练数据的多序列排列的计算方案,在训练期间计算类别特征的统计量。
由于CatBoostClassifier/CatBoostRegressor参数不同,以下分别介绍二者参数。
通用参数:
learning_rate/eta:学习率,default=automatically;
depth/max_depth:树的最大深度,default=6;
2_leaf_reg/reg_lambda:L2正则化系数,default=3;
n_eatimators/num_boost_round(num_trees:解决ML问题的树的最大数量,default=1000;
one_hot_max_size:对于某些变量进行one-hot编码,default=2
loss_function:损失函数,default=‘Logloss’,可供选择有’RMSE’、‘Logloss’、‘MAE’、‘CrossEntropy’;
custom_metric:default=None,可供选择的有’RMSE’,‘Logloss’,‘MAE’,‘CrossEntropy’,‘Recall’,‘Precision’,‘F1’,‘Accuracy’,‘AUC’,‘R2’;
eval_metric:default=None,可供选择的有’RMSE’,‘Logloss’,‘MAE’,‘CrossEntropy’,‘Recall’,‘Precision’,‘F1’,‘Accuracy’,‘AUC’,‘R2’;
nan_mode:处理NAN的方法,default=None,可供选择的有’Forbidden’、‘Min’、‘Max’;
leaf_estimation_method:迭代求解的方法,梯度和牛顿,default=None,可供选择的有’Newton’、‘Gradient’;
random_seed:训练时的随机种子,default=None。
性能参数:
thread_count:训练时所用的CPU/GPU核数,default=-1,默认使用最大核数;
used_ram_limit:CTR问题,计算时的内存限制,default=None;
gpu_ram_part:GPU内存限制,default=None。
处理单元设置:
task_type:训练的器件,default=CPU;
devices:训练的GPU设备ID,default=None
counter_calc_method:default=None
leaf_estimation_iterations:default=None
use_best_model:default=None
verbose:default=None
model_size_reg:default=None
rsm:default=None
logging_level:default=None
metric_period:default=None
ctr_leaf_count_limit:default=None
store_all_simple_ctr:default=None
max_ctr_complexity:default=None
has_time:default=None
classes_count:default=None
class_weights:default=None
random_strength:default=None
name:default=None
ignored_features:default=None
train_dir:default=None
custom_loss:default=None
bagging_temperature:default=None
border_count:default=None
feature_border_type:default=None
save_snapshot:default=None
snapshot_file:default=None
fold_len_multiplier:default=None
allow_writing_files:default=None
final_ctr_computation_mode:default=None
approx_on_full_history:default=None
boosting_type:default=None
simple_ctr:default=None
combinations_ctr:default=None
per_feature_ctr:default=None
device_config:default=None
bootstrap_type:default=None
subsample:default=None
colsample_bylevel:default=None
random_state:default=None
objective:default=None
max_bin:default=None
scale_pos_weight:default=None
gpu_cat_features_storage:default=None
data_partition:default=None