本文主要是介绍高基数类别特征预处理:平均数编码(目标编码),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
高基数类别特征预处理:平均数编码
参考:高基数类别特征预处理:平均数编码
1、引言
对于一个类别特征,如果这个特征的取值非常多,则称它为高基数(high-cardinality)类别特征。在深度学习场景中,对于类别特征我们一般采用Embedding的方式,通过预训练或直接训练的方式将类别特征值编码成向量。在经典机器学习场景中,对于有序类别特征,我们可以使用LabelEncoder进行编码处理,对于低基数无序类别特征(在lightgbm中,默认取值个数小于等于4的类别特征),可以采用OneHotEncoder的方式进行编码,但是对于高基数无序类别特征,若直接采用OneHotEncoder的方式编码,在目前效果比较好的GBDT、Xgboost、lightgbm等树模型中,会出现特征稀疏性的问题,造成维度灾难, 若先对类别取值进行聚类分组,然后再进行OneHot编码,虽然可以降低特征的维度,但是聚类分组过程需要借助较强的业务经验知识。本文介绍一种针对高基数无序类别特征非常有效的预处理方法:平均数编码(Mean Encoding)。在很多数据挖掘类竞赛中,有许多人使用这种方法取得了非常优异的成绩。
2、原理
平均数编码,有些地方也称之为目标编码(Target Encoding),是一种基于目标变量统计(Target Statistics)的有监督编码方式。该方法基于贝叶斯思想,用先验概率和后验概率的加权平均值作为类别特征值的编码值,适用于分类和回归场景。
如何工作:
假设你有一个分类特征和一个数值型目标变量。平均编码的步骤如下:
- 分组:对于每个类别,根据该类别分组数据。
- 计算平均值:计算每个类别对应的目标变量的平均值。
- 映射:将分类特征中的每个类别替换为其对应的平均目标值。
优点:
- 效率高:平均编码可以显著减少数据的维度,特别是对于高基数的分类特征。
- 性能提升:它通常可以提供更好的预测性能,因为它直接利用了目标变量的信息。
- 简化模型:由于直接使用数值代替类别,模型可以更快地收敛。
缺点和风险:
- 过拟合:平均编码极易导致过拟合,尤其是当某些类别的观察次数很少时。
- 数据泄露:如果不正确实施,很容易引入来自测试集或验证集的信息,导致评估指标不准确。
防止过拟合的策略:
为了减少过拟合和数据泄露的风险,可以采取以下一些策略:
- 正则化:引入平滑,当类别的观察次数较少时,通过将全局平均(整个数据集的目标平均)与类别平均混合来减少噪声。
- 交叉验证:使用嵌套的交叉验证方法,在每个训练折叠上独立地计算平均值,然后应用到验证折叠上。
- 分箱:如果某些类别观察次数很少,可以考虑将它们与其他相似的类别组合起来。
- 泛化处理:对于测试集中的新类别或很少见的类别,可以赋予全局平均或某种形式的估计值。
结论:
平均编码是一种强大的编码方式,适合那些与目标变量强相关的分类特征。然而,它需要仔细的实施和验证,以避免过拟合和数据泄露。适当时,结合其他防止过拟合的策略,可以在许多问题上取得优异的性能。
示例:
import pandas as pd
from category_encoders import TargetEncoderdf = pd.DataFrame({'cat': ['a', 'b', 'a', 'b', 'a', 'a', 'b', 'c', 'c', 'd'], 'target': [1, 0, 0, 1, 0, 0, 1, 1, 0, 1]})
te = TargetEncoder(cols=["cat"], min_samples_leaf=2, smoothing=1)
df["cat_encode"] = te.transform(df)["cat"]
print(df)
# 结果如下:cat target cat_encode
0 a 1 0.279801
1 b 0 0.621843
2 a 0 0.279801
3 b 1 0.621843
4 a 0 0.279801
5 a 0 0.279801
6 b 1 0.621843
7 c 1 0.500000
8 c 0 0.500000
9 d 1 0.634471
此外,测试集中出现训练集中未见的类别时,这被称为“冷启动”问题或“新类别”问题。对于目标编码来说,**一个简单的策略是将未见类别的编码设置为训练集目标变量的全局平均值。**这种方法简单,但可能不是最优的,尤其是当新类别和已知类别有很大不同的时候。
这篇关于高基数类别特征预处理:平均数编码(目标编码)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!