问题起因
- 在用户风险预测模型(安全审核)中,提出了特征应该用类别特征还是 one-hot 特征,针对此问题进行调研
理论分析
1、GBDT做为树模型对高维稀疏特征处理效果差,究其原因到底是因为什么呢??
- 假设在分类场景下,某一维特征有 1000 个类别,那么采用 one-hot 编码,每一维特征就是 0 or 1,那么 GBDT 可能会错误的学习到只要某个特征为 0 或者 1 就是某个类别,这种情况下就会产生过拟合,在训练数据不充足的情况下,这种问题更严重;
- 同样的场景下,不采用 one-hot 而采用 label encoding ,那么会存在什么问题,树模型在分裂的过程中,特征会变成分段划取,比如x<90 and x>50,这就会导致 50-90 之间的类别特征都有了关联来进行处理的,因此引入了额外的噪音(特征隐含信息);
- 这也就解释了为啥在薪资预测模型中,GBDT 的效果差于线性模型,原因也在于特征通过 one-hot 编码过于稀疏,而线性模型可以很好的利用正则化来解决数据系数问题。
2、那 GBDT应该用什么编码方式
- 不适用 one-hot 编码原因
- 微软在 light GBM 文档里面说明了,category 特征可以直接输入,不需要 one-hot 编码,速度快八倍,准确度差不多
- one-hot 编码容易导致特征维度过大且稀疏,导致GBDT模型学校效果差很多
- 不适用 label-encoding 编码原因
- label-encoding 编码后 GBDT 会使得特征编码之间具有了关联性,容易引入噪音,尤其对一些训练集中未出现的类别,再实际测试集中有的类别特征容易出现问题,例如88这个类别特征没有出现过,但在测试时却有,模型很容易把他和同区间的类别特征统一处理,从而导致线上不可控问题,one-hot 可以很好的解决这种问题
实践出真知
- 公说公有理,婆说婆有理,不管谁有理,实践出真知
1.label-encoding
模型 | LR | Random Forest | GBDT | XGboost | GradientBoosting + LogisticRegression | lightgbm |
---|---|---|---|---|---|---|
acc | 0.7533 | 0.8657 | 0.8697 | 0.8511 | 0.8703 | 0.8710 |
confusion_matrix | [[542 163] [208 591]] | [[671 122] [ 79 632]] | [[668 114] [ 82 640]] | [[669 146] [ 81 608]] | [[660 105] [ 90 649]] | [[662 106] [ 88 648]] |
其他指标 | 1-precision: 0.7838 1-recall: 0.7397 1-f1: 0.7611 0-precision: 0.7227 0-recall: 0.7688 0-f1: 0.745 | 1-precision: 0.8382 1-recall: 0.8889 1-f1: 0.8628 0-precision: 0.8947 0-recall: 0.8462 0-f1: 0.8697 | 1-precision: 0.8488 1-recall: 0.8864 1-f1: 0.8672 0-precision: 0.8907 0-recall: 0.8542 0-f1: 0.8721 | 1-precision: 0.8064 1-recall: 0.8824 1-f1: 0.8427 0-precision: 0.892 0-recall: 0.8209 0-f1: 0.855 | 1-precision: 0.8607 1-recall: 0.8782 1-f1: 0.8694 0-precision: 0.88 0-recall: 0.8627 0-f1: 0.8713 | 1-precision: 0.8594 1-recall: 0.8804 1-f1: 0.8698 0-precision: 0.8827 0-recall: 0.862 0-f1: 0.8722 |
2.one-hot
模型 | LR | Random Forest | GBDT | XGboost | GradientBoosting + LogisticRegression | lightgbm |
---|---|---|---|---|---|---|
acc | 0.8364 | 0.8684 | 0.8677 | 0.8664 | 0.8703 | 0.8690 |
confusion_matrix | [[[646 142] [104 612]] | [[670 118] [ 80 636]] | [[666 115] [ 84 639]] | [[668 119] [ 82 635]] | [[659 104] [ 91 650]] | [[655 102] [ 95 652]] |
其他指标 | 1-precision: 0.8117 1-recall: 0.8547 1-f1: 0.8327 0-precision: 0.8613 0-recall: 0.8198 0-f1: 0.8401 | 1-precision: 0.8435 1-recall: 0.8883 1-f1: 0.8653 0-precision: 0.8933 0-recall: 0.8503 0-f1: 0.8713 | 1-precision: 0.8475 1-recall: 0.8838 1-f1: 0.8653 0-precision: 0.888 0-recall: 0.8528 0-f1: 0.87 | 1-precision: 0.8422 1-recall: 0.8856 1-f1: 0.8634 0-precision: 0.8907 0-recall: 0.8488 0-f1: 0.8692 | 1-precision: 0.8621 1-recall: 0.8772 1-f1: 0.8696 0-precision: 0.8787 0-recall: 0.8637 0-f1: 0.8711 | 1-precision: 0.8647 1-recall: 0.8728 1-f1: 0.8688 0-precision: 0.8733 0-recall: 0.8653 0-f1: 0.8693 |
结论:两者对比发现,one-hot编码再线性模型中提升较大,但对于树模型来说基本没有起到作用,或者说两种编码方式均可,可能的原因我们数据类别特征较少,均为两个或者三个类别,用one-hot和label-encoding没有很大的区别,最后值得指出的是再实际使用场景中,应该根据实际的数据特征来进行分析,不确定的情况下两者均进行尝试,对比效果再对其进行原因分析。