gbdt中,缺失值做极值填充到底有啥用

  • 2020 年 12 月 25 日
  • AI

在业务和比赛中经常出现对缺失值进行-9999之类的极值填充,这种填充有什么用?

根源问题主要在于xgb、lgb(catboost内部自动对缺失值做极值填充)的稀疏感知的实现,也就是我们常说的存在缺失值的样本分裂的时候分别进入左右枝计算gain,最终分到gain大的分支里,这种方法的问题就在当缺失的样本比较多的时候,比如90%左右,那么等于我们最终仅在10%的特征取值里进行分裂和分裂后的样本划分,那么显然,如果新数据在该特征中出现了大量的新的取值,很容易就发生过拟合了;

而极值填充的作用在于避免这种问题的发生,比如我们有10万个样本,当tree对于某一个feature A进行分裂的时候:[1,2,3,4…..np.nan,](取值已去重和预排序),假设1万个样本的这个特征有值,剩下90000个缺失,则默认分裂是(假设在3.5这个地方分裂)【1,2,3】,【4,。。。。】,并且假设左枝的gain比右枝大,则左枝分到的结果是[1,2,3,np.nan],右枝分到的结果是[4,….],左枝的样本明显比右枝多,因为包含了90000个存在缺失的样本;

整个过程等效于我们在10000个样本上进行分裂,然后把剩下的90000个样本直接插入最终的结果,整个tree的决策过程是在少量的子数据集上进行的,那么过拟合的问题就和小数据集过拟合的问题是类似的,当然,缺失问题不严重的时候这种处理方法没什么问题,但缺失值比较严重的时候就存在问题了;

而极值填充,以上面为例子,假设填充了-9999,则原始的特征去重预排序之后为[1,2,3,4,….-9999],此时分裂的时候gbdt的稀疏感知不发生作用(都没有缺失值了发生啥作用啊。。。),此时我们就是在全量的数据上进行分裂的决策了,这个时候就要分情况讨论了,

1、当缺失值很少的时候,当缺失值很少,比如占比都不到1%的情况下,其实处不处理在业务上差异并不会很大(比赛中倒是有可能导致万几的差异),此时其实做不做缺失值填充并没有太大的影响;

2、缺失值占非常大的时候,比如缺失值占比99%,然后我们进行了-9999的极值填充,为了方便描述还是举个例子吧,

【nan,nan。。。。。。。,1,2,3,4,】

假设我们有10000个样本,不进行缺失值填充的时候,分裂之后的结果可能是这样的

【-inf,nan,nan。。。。。。。,1,2,】,【 3,4,inf】

如果进行-9999的填充,分裂之后的结果可能是这样的:

【-inf,-9999,-9999。。。。。。。,1,2,】,【 3,4,inf】

有什么区别??????

其实主要原因在于,在某些特定的场景下,缺失值是存在重要意义的,举一个极端的例子,假设一个二分类问题,10万个缺失值的标签都是1,100个非缺失样本的标签有0,有1,显然。。。如果不做缺失处理,模型的效果相对于进行缺失值处理之后差太多了。。。。原因就是这么简单。。。

//www.kaggle.com/c/home-credit-default-risk/discussion/59026www.kaggle.com

相关论述可见这里。

但是当缺失值没有意义,属于完全随机缺失的话,做极值插补效果不一定好可能还更差