[机器学习] 类别变量编码库category_encoders使用指南
category_encoders是一个Python库,专门用于将分类变量(如文字、标签)转换为机器学习模型可以处理的数值形式。它是 scikit-learn-contrib 项目的一部分,完全兼容Scikit-learn的API,可以无缝集成到机器学习流程中。本文将围绕该库的核心用法展开详细讲解。

category_encoders的github官方仓库见:category_encoders,category_encoders介绍文档见:category_encoders-docs。
安装方式如下:
pip install category_encoders
# 查看category_encoders版本
import category_encoders as ce
ce.__version__
'2.8.1'
1 基础介绍
1.1 使用概览
category_encoders库的核心价值在于它集成了超过20种不同的编码方法,远超Scikit-learn自带的少数几种。其主要特点包括:
- 统一的Scikit-learn API:所有编码器都遵循
fit、transform等方法,可以轻松用于管道(Pipeline)和交叉验证。 - 丰富的编码方法:提供了从经典到前沿的各种编码技术,满足不同数据和模型的需求。
- 便捷的列处理:可以指定需要编码的列,或自动识别数据框中的非数值列进行编码。
- 处理未见类别:部分编码器(如
TargetEncoder)能够以合理的方式处理在训练集中未出现过的新类别。
那么为什么需要这么多编码,这是因为机器学习模型只能看懂数字看不懂文字,所以得把颜色、城市这些文字类的特征转换成数字,这就是编码;独热编码虽然常用,但只适合类别少、没有顺序的特征,要是遇到几百个城市这种类别多的情况,用独热编码会生成超多列数据,模型计算起来又慢又容易出错,遇到低中高这种有顺序的特征,用独热编码还会丢掉高低顺序的关键信息。所以才需要序数编码、目标编码这些其他方法,它们能压缩数据列数或者保留顺序,让模型算得快还预测得准。
此外,对于深度学习模型,虽然其可以通过嵌入层自动学习类别特征的表示,但在某些场景下,预先使用编码方法将类别特征转换为数值形式,可以简化网络结构并提升训练效率。
所有category_encoders的编码器使用方式如下:
import category_encoders as ce
import pandas as pd
import numpy as np
# 创建更简单的数据集 - 使用颜色代替城市
np.random.seed(42)
data = pd.DataFrame({
'color': ['红', '蓝', '绿', '红', '蓝', '绿', '红', '蓝'],
'feature1': np.random.randn(8),
'target': [1, 0, 1, 0, 1, 0, 1, 0]
})
# 手动划分训练集和测试集(前6个训练,后2个测试)
X_train = data[['color', 'feature1']].iloc[:6]
y_train = data['target'].iloc[:6]
X_test = data[['color', 'feature1']].iloc[6:]
y_test = data['target'].iloc[6:]
print("原始训练数据:")
print(X_train)
print("\n训练目标:")
print(y_train)
# 使用OneHot编码(这是类别编码的一种,更直观)
encoder = ce.OneHotEncoder(cols=['color'])
X_train_encoded = encoder.fit_transform(X_train) # 有监督编码需传入y,无监督可省略y
X_test_encoded = encoder.transform(X_test)
print("\n编码后的训练数据:")
print(X_train_encoded)
print("\n编码后的测试数据:")
print(X_test_encoded)
# 查看编码器学习到的映射关系
print("\n编码器学习到的映射:")
print(encoder.mapping)
原始训练数据:
color feature1
0 红 0.496714
1 蓝 -0.138264
2 绿 0.647689
3 红 1.523030
4 蓝 -0.234153
5 绿 -0.234137
训练目标:
0 1
1 0
2 1
3 0
4 1
5 0
Name: target, dtype: int64
编码后的训练数据:
color_1 color_2 color_3 feature1
0 1 0 0 0.496714
1 0 1 0 -0.138264
2 0 0 1 0.647689
3 1 0 0 1.523030
4 0 1 0 -0.234153
5 0 0 1 -0.234137
编码后的测试数据:
color_1 color_2 color_3 feature1
6 1 0 0 1.579213
7 0 1 0 0.767435
编码器学习到的映射:
[{'col': 'color', 'mapping': color_1 color_2 color_3
1 1 0 0
2 0 1 0
3 0 0 1
-1 0 0 0
-2 0 0 0}]
1.2 编码方法介绍
category_encoders库中的编码器大致可分为两类,可以根据数据是否有目标变量来确定。
无监督编码方法
这类方法不依赖于目标变量(预测值),仅根据特征自身的分布或属性进行转换。
-
Backward Difference Contrast
- 编码方法:将有序分类变量的每个级别(除第一个外)与其前一个级别的均值进行比较和编码。
- 核心特点:适用于分析相邻级别间的变化趋势,常见于方差分析等统计模型。
-
BaseN
- 编码方法:将整数类别ID转换为自定义进制(如二进制、三进制)的数值表示。
- 核心特点:提供灵活的数值转换,但通常不是特征工程的首选,效率有限。
-
Binary
- 编码方法:先将类别转换为有序整数,再将该整数转换为二进制数,并将每一位作为独立的二元特征。
- 核心特点:能高效压缩维度,在类别数量极多时,比独热编码节省大量特征空间。
-
Gray
- 编码方法:与二进制编码类似,但使用格雷码(循环码)进行转换,保证相邻数值间仅一位不同。
- 核心特点:编码后的相邻类别具有最小的特征差异,对某些算法可能更稳定。
-
Count
- 编码方法:使用该类别在数据集中出现的次数(频数)作为其编码值。
- 核心特点:简单快速,能反映类别的普遍性或常见度,但会丢失类别本身的区分信息。
-
Hashing
- 编码方法:应用哈希函数将类别字符串映射到一个固定大小的、低维度的特征向量中。
- 核心特点:内存消耗恒定,非常适合在线学习或超高基数特征,但存在哈希冲突导致信息损失的风险。
-
Helmert Contrast
- 编码方法:将有序分类变量的某个级别,与其之后所有级别的均值进行比较和编码。
- 核心特点:用于统计模型,分析特定水平与后续整体平均水平之间的差异。
-
Ordinal
- 编码方法:根据明确的顺序(如大小、等级),为有序分类变量分配连续的整数。
- 核心特点:简单且保留了顺序信息,但隐含了“类别间隔相等”的假设,可能引入误导。
-
One-Hot
- 编码方法:为每一个类别创建一个新的二元特征(列),样本属于该类别则标记为1,否则为0。
- 核心特点:彻底消除类别间的虚假顺序关系,但类别多时会导致特征稀疏和维度灾难。
-
Rank Hot
- 编码方法:先为有序分类变量按明确顺序分配排名,再对排名执行独热编码(对应排名标1,其余为0),可优化为Top-K策略(仅编码核心排名)。
- 核心特点:兼具顺序保留与无虚假间隔优势,灵活控维度;适用于中等类别数有序变量,类别过多易稀疏。
-
Polynomial Contrast
- 编码方法:将有序分类变量的级别转换为正交多项式(如线性、二次、三次)的系数。
- 核心特点:用于检测和拟合目标变量与有序分类变量之间可能存在的多项式趋势(如曲线关系)。
-
Sum Contrast
- 编码方法:将每个类别的效应编码为与所有类别整体均值的偏差。
- 核心特点:在回归模型中,使得截距项代表全局响应均值,系数易于解释为与全局均值的偏离。
有监督编码方法
这类方法在编码过程中利用了目标变量的信息,旨在将类别信息与预测目标更紧密地联系起来。
-
CatBoost Encoding
- 编码方法:一种基于目标变量统计(如均值)的编码,通过引入样本的随机排列顺序,并在计算中排除当前样本的值来防止目标泄露。
- 核心特点:专为CatBoost设计,能有效防止过拟合,且可直接应用于其他树模型,无需额外验证策略。
-
Generalized Linear Mixed Model
- 编码方法:将类别变量视为随机效应,使用广义线性混合模型估计其对目标的效应值,以此作为编码。
- 核心特点:特别适用于具有层次结构、重复测量或存在组内相关性的数据。
-
James-Stein Estimator
- 编码方法:将每个类别的目标统计量(如均值)向整体均值进行收缩,收缩强度取决于该类别的样本量。
- 核心特点:通过方差缩减来优化估计,尤其能提升小样本类别编码值的稳健性和可靠性。
-
LeaveOneOut
- 编码方法:对于当前样本,计算其所属类别中所有其他样本的目标统计量(如均值)作为编码值。
- 核心特点:最直接的防止目标泄露方法之一,但计算量较大,且对相同类别样本的编码值不完全相同。
-
M-estimator
- 编码方法:计算目标均值与一个先验值(如全局均值)的加权平均。权重由类别样本量决定,样本量大的类别更依赖自身均值。
- 核心特点:对简单的目标均值编码进行平滑,有效减少因小类别样本量不足而引入的噪声和过拟合。
-
Target Encoding / Mean Encoding
- 编码方法:使用该类别的目标变量均值(回归)或正类比例(分类)来替换类别标签。
- 核心特点:将类别信息与预测目标强关联,效果显著,但必须配合严格的交叉验证或平滑使用,否则极易导致数据泄露和过拟合。
-
Weight of Evidence
- 编码方法:主要用于二分类,计算
ln((好样本比例) / (坏样本比例))作为编码值。 - 核心特点:直接衡量该类别对区分“好”、“坏”事件的预测能力,在金融风控等领域应用广泛,解释性强。
- 编码方法:主要用于二分类,计算
-
Quantile Encoder
- 编码方法:不使用目标均值,而是使用目标变量在该类别下的特定分位数(如中位数、第25分位数)进行编码。
- 核心特点:对异常值不敏感,能捕捉类别内目标值的分布位置信息,比单一均值提供更稳健的编码。
-
Summary Encoder
- 编码方法:为目标变量在每个类别下的分布计算多个统计量(如均值、标准差、分位数、偏度等),生成一组特征。
- 核心特点:提供关于类别与目标关系的全景视图,能更丰富地描述数据分布形态,但特征维度会增加。
重要提示:本文仅介绍category_encoders库中各种编码方法的基本使用和适用场景,关于每种编码方法的详细数学原理和统计理论,需要进一步自行查阅相关学术资料和官方文档进行深入学习。

1.3 编码器选择建议
-
无监督编码:无目标变量时使用
- 标准首选:
One-Hot(类别少,<10),Ordinal(变量有明确顺序)。 - 类别极多(高基数):用
Binary、Hashing压缩维度。 - 探索类别频率:用
Count。 - 有序变量分析:
Backward Difference、Helmert、Polynomial(用于统计模型趋势分析)。 - 特定需求:
BaseN、Gray(一般很少用)。
- 标准首选:
-
有监督编码:有目标变量时优先考虑
- 通用稳健选择:
CatBoost(防过拟合好)、M-estimator(平滑小类别)。 - 二分类问题(如风控):首选
Weight of Evidence (WOE),解释性强。 - 避免泄露:使用
LeaveOneOut或严格在训练集内做Target Encoding并配合交叉验证。 - 数据有层次/组结构:考虑
Generalized Linear Mixed Model (GLMM)。 - 提升小类别估计:用
James-Stein(收缩至整体均值)。 - 关注分布而非仅均值:用
Quantile Encoder(抗异常值)、Summary Encoder(描述完整分布)。
- 通用稳健选择:
-
简明决策路径
- 是否有目标变量?
- 无 → 选 无监督编码,根据类别数量、顺序选择。
- 有 → 选 有监督编码,尤其推荐
CatBoost、M-estimator或WOE。
- 关键注意:
- 防过拟合:有监督编码必须使用交叉验证或在训练集内拟合,避免数据泄露。
- 在线学习:
Hashing是唯一内存固定的编码器。 - 树模型:可放心使用
CatBoost、Ordinal。 - 线性/统计模型:慎用
Ordinal(可能引入虚假顺序),多用One-Hot或统计对比编码(Helmert等)。
- 是否有目标变量?
核心原则:根据数据特点(顺序、基数)和任务目标(预测、解释)选择,有监督编码通常预测能力更强,但务必小心处理避免目标泄露。
2 代码示例
以下数据集作为后续所有示例的基础数据:
import pandas as pd
# 构造示例数据
df = pd.DataFrame({
"color": ["红", "蓝", "绿", "红", "绿"],
"size": ["S", "M", "L", "M", "L"],
"target": [25.3, 30.1, 28.5, 26.7, 29.3] # 有监督编码需要目标变量
})

2.1 无监督编码方法(Unsupervised)
Backward Difference Contrast(后向差分对比编码)
- 核心逻辑:将有序类别转换为相邻类别均值的差值,适用于有序类别特征(如S<M<L);
- 输出形式:k个类别生成k-1列,每列表示当前类别与前一类别均值的差分;
- 适用场景:有序分类特征(如评分、等级、年龄段),需体现类别间的顺序差值。
# 针对有序特征size(S<M<L)
encoder = ce.BackwardDifferenceEncoder(cols=["size"], drop_invariant=True)
df_encoded = encoder.fit_transform(df)
print("后向差分编码结果:")
print(df_encoded[["size_0", "size_1"]]) # 3个类别生成2列,每一列代表当前列和上一列的一次比较
后向差分编码结果:
size_0 size_1
0 -0.666667 -0.333333
1 0.333333 -0.333333
2 0.333333 0.666667
3 0.333333 -0.333333
4 0.333333 0.666667
BaseN(BaseN编码)
- 核心逻辑:把类别变成N进制数字,用更少的列装下更多的类,是Binary编码的通用版;
- 关键参数:
base(进制数,默认2,即Binary编码); - 输出形式:k个类别生成[log_base(k)个⌉列,base为进制数,k为类别数;
- 适用场景:类别特别多,不想生成太多列的情况。
# 对color特征用3进制编码
encoder = ce.BaseNEncoder(cols=["color"], base=3)
df_encoded = encoder.fit_transform(df)
print("BaseN(3进制)编码结果:")
print(df_encoded.filter(like="color"))
BaseN(3进制)编码结果:
color_0 color_1
0 0 1
1 0 2
2 1 0
3 0 1
4 1 0
Binary(二进制编码)
- 核心逻辑:BaseN编码的特例(base=2),先将类别映射为整数,再转换为二进制,每一位作为一列;
- 输出形式:k个类别生成⌈log2(k)⌉列,列数远少于One-Hot;
- 适用场景:类别特别多,极限压缩编码维度的情况。
encoder = ce.BinaryEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df)
print("二进制编码结果:")
print(df_encoded.filter(like="color"))
二进制编码结果:
color_0 color_1
0 0 1
1 1 0
2 1 1
3 0 1
4 1 1
Gray(格雷编码)
- 核心逻辑:基于格雷码(相邻整数仅有1位不同的二进制编码),减少编码列间的相关性;
- 输出形式:与Binary编码列数相同,但数值分布更平滑;
- 适用场景:需降低编码后特征间相关性的高维度类别特征。
encoder = ce.GrayEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df)
print("格雷编码结果:")
print(df_encoded.filter(like="color"))
格雷编码结果:
color_0 color_1
0 0 1
1 1 0
2 1 1
3 0 1
4 1 1
Count(计数编码)
- 核心逻辑:用每个类别在数据集中的出现次数(频数)替换该类别;
- 输出形式:每个类别特征生成1列,值为对应类别的计数;
- 适用场景:需体现类别“出现频率”的场景,如高频类别更重要的特征。
encoder = ce.CountEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df)
print("计数编码结果:")
print(df_encoded[["color"]]) # color列值为该颜色出现的次数
计数编码结果:
color
0 2
1 1
2 2
3 2
4 2
Hashing(哈希编码)
- 核心逻辑:通过哈希函数将类别映射到固定数量的列(桶),无需拟合(可处理未知类别);
- 关键参数:
n_components(哈希桶数,默认8)、hash_method(哈希方法,如'md5'/'sha1'); - 输出形式:固定n_components列,可能存在哈希冲突;
- 适用场景:超大规模数量特征(如用户ID、商品ID),无需存储类别映射表。
encoder = ce.HashingEncoder(cols=["color"], n_components=4, hash_method='sha1')
df_encoded = encoder.fit_transform(df)
print("哈希编码结果:")
print(df_encoded.filter(like="col")) # 输出4列哈希值
哈希编码结果:
col_0 col_1 col_2 col_3
0 0 1 0 0
1 0 1 0 0
2 0 1 0 0
3 0 1 0 0
4 0 1 0 0
Helmert Contrast(赫尔默特对比编码)
- 核心逻辑:将每个类别与后续所有类别的均值对比,适用于有序类别;
- 输出形式:k个类别生成k-1列,每列表示当前类别与后续类别均值的差值;
- 适用场景:适用于有序类别特征,常用于统计建模与回归分析,以考察当前类别 vs 后续所有类别的差异。
encoder = ce.HelmertEncoder(cols=["size"])
df_encoded = encoder.fit_transform(df)
print("赫尔默特对比编码结果:")
print(df_encoded.filter(like="size"))
赫尔默特对比编码结果:
size_0 size_1
0 -1.0 -1.0
1 1.0 -1.0
2 0.0 2.0
3 1.0 -1.0
4 0.0 2.0
Ordinal(序数编码)
- 核心逻辑:将有序类别映射为连续整数(如S→1, M→2, L→3),最基础的有序编码;
- 关键参数:
mapping(自定义类别-整数映射,默认按字母顺序); - 输出形式:每个类别特征生成1列,值为整数;
- 适用场景:明确有序的类别特征(如学历、评分),需保留顺序关系。
# 自定义size的映射(S<M<L)
mapping = [{"col": "size", "mapping": {"S": 1, "M": 2, "L": 3, None: 0}}]
encoder = ce.OrdinalEncoder(cols=["size"], mapping=mapping)
df_encoded = encoder.fit_transform(df)
print("序数编码结果:")
print(df_encoded[["size"]])
序数编码结果:
size
0 1
1 2
2 3
3 2
4 3
One-Hot(独热编码)
- 核心逻辑:将每个类别映射为独立列,列值为0/1(当前样本是否属于该类别);
- 关键参数:
drop_invariant(删除全0/全1列)、use_cat_names(用类别名作为列名); - 输出形式:k个类别生成k列(或k-1列,避免多重共线性);
- 适用场景:低基数无序类别特征(如性别、颜色),是最常用的无监督编码。
encoder = ce.OneHotEncoder(cols=["color"], use_cat_names=True)
df_encoded = encoder.fit_transform(df)
print("独热编码结果:")
print(df_encoded[["color_红", "color_蓝", "color_绿"]])
独热编码结果:
color_红 color_蓝 color_绿
0 1 0 0
1 0 1 0
2 0 0 1
3 1 0 0
4 0 0 1
Rank Hot(秩热编码)
- 核心逻辑:先对类别按出现频率排序(秩),再对秩进行独热编码;
- 输出形式:k个类别生成k列,列值为0/1,基于秩的分布;
- 适用场景:需结合类别频率和独热编码的场景,突出高频类别。
encoder = ce.RankHotEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df)
print("秩热编码结果:")
print(df_encoded.filter(like="color"))
秩热编码结果:
color_1 color_2 color_3
0 1 0 0
1 1 1 1
2 1 1 0
3 1 0 0
4 1 1 0
Polynomial Contrast(多项式对比编码)
- 核心逻辑:将有序类别转换为多项式(线性、二次、三次等)形式,捕捉类别间的非线性关系;
- 输出形式:k个类别生成k-1列,对应不同阶数的多项式;
- 适用场景:有序类别特征,需捕捉类别与目标间的非线性关系(无监督场景下仅体现类别自身的非线性)。
encoder = ce.PolynomialEncoder(cols=["size"])
df_encoded = encoder.fit_transform(df)
print("多项式对比编码结果:")
print(df_encoded.filter(like="size"))
多项式对比编码结果:
size_0 size_1
0 -7.071068e-01 0.408248
1 -4.433780e-17 -0.816497
2 7.071068e-01 0.408248
3 -4.433780e-17 -0.816497
4 7.071068e-01 0.408248
Sum Contrast(和对比编码)
- 核心逻辑:将每个类别与总体均值对比,列值和为0,避免多重共线性;
- 输出形式:k个类别生成k-1列,每列值表示当前类别与总体均值的偏差;
- 适用场景:有序/无序类别特征,需避免独热编码的多重共线性问题。
encoder = ce.SumEncoder(cols=["size"])
df_encoded = encoder.fit_transform(df)
print("和对比编码结果:")
print(df_encoded.filter(like="size"))
和对比编码结果:
size_0 size_1
0 1.0 0.0
1 0.0 1.0
2 -1.0 -1.0
3 0.0 1.0
4 -1.0 -1.0
2.2 有监督编码方法(Supervised)
CatBoost(CatBoost编码)
- 核心逻辑:基于目标变量的统计值,按样本顺序逐步编码(避免过拟合),对每个类别计算目标均值并加入随机噪声;
- 关键参数:
sigma(噪声系数,默认0.05,防止过拟合); - 输出形式:每个类别特征生成1列,值为结合目标均值的编码值;
- 适用场景:分类/回归任务,尤其是梯度提升树(CatBoost/XGBoost)模型,抗过拟合能力强。
encoder = ce.CatBoostEncoder(cols=["color"],sigma=0.01)
df_encoded = encoder.fit_transform(df, y=df["target"])
print("CatBoost编码结果:")
print(df_encoded[["color"]])
CatBoost编码结果:
color
0 27.848641
1 28.131808
2 27.850336
3 26.515930
4 28.308330
Generalized Linear Mixed Model(GLMM编码)
- 核心逻辑:基于广义线性混合模型,将类别作为随机效应,计算每个类别的后验均值;
- 输出形式:每个类别特征生成1列,值为模型估计的后验均值;
- 适用场景:需结合统计模型的编码场景,适合小样本数据(正则化效果好)。
encoder = ce.GLMMEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df, y=df["target"])
print("GLMM编码结果:")
print(df_encoded[["color"]])
GLMM编码结果:
color
0 -2.119044
1 1.555984
2 0.563060
3 -2.119044
4 0.563060
James-Stein Estimator(詹姆斯-斯坦因估计编码)
- 核心逻辑:用詹姆斯-斯坦因估计量收缩类别均值,平衡全局均值和类别自身均值,减少方差;
- 输出形式:每个类别特征生成1列,值为收缩后的目标均值;
- 适用场景:类别样本分布不均衡(部分类别样本少),需收缩均值减少偏差。
encoder = ce.JamesSteinEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df, y=df["target"])
print("James-Stein编码结果:")
print(df_encoded[["color"]])
James-Stein编码结果:
color
0 26.0
1 30.1
2 28.9
3 26.0
4 28.9
LeaveOneOut(留一法编码)
- 核心逻辑:对每个样本,用除自身外同类别样本的目标均值作为编码值,避免自身信息泄露;
- 输出形式:每个类别特征生成1列,值为留一法计算的目标均值;
- 适用场景:小样本数据,防止过拟合(无信息泄露),适合分类/回归任务。
encoder = ce.LeaveOneOutEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df, y=df["target"])
print("留一法编码结果:")
print(df_encoded[["color"]])
留一法编码结果:
color
0 26.70
1 27.98
2 29.30
3 25.30
4 28.50
M-estimator(M估计量编码)
- 核心逻辑:基于稳健统计的M估计量,降低异常值对类别均值的影响;
- 关键参数:
sigma(稳健性系数); - 输出形式:每个类别特征生成1列,值为稳健的目标均值估计;
- 适用场景:目标变量存在异常值的回归/分类任务,需稳健的均值估计。
encoder = ce.MEstimateEncoder(cols=["color"], sigma=0.01)
df_encoded = encoder.fit_transform(df, y=df["target"])
print("M-estimator编码结果:")
print(df_encoded[["color"]])
M-estimator编码结果:
color
0 26.660000
1 29.040000
2 28.593333
3 26.660000
4 28.593333
Target Encoding(目标编码)
- 核心逻辑:用每个类别的目标变量均值替换该类别(分类任务:概率;回归任务:均值);
- 关键参数:
smoothing(平滑系数,平衡全局均值和类别均值,避免过拟合); - 输出形式:每个类别特征生成1列,值为目标均值;
- 适用场景:分类/回归任务的核心编码方法,简单高效,但需注意平滑/交叉验证防止过拟合。
# 加入平滑避免小类别过拟合
encoder = ce.TargetEncoder(cols=["color"], smoothing=10)
df_encoded = encoder.fit_transform(df, y=df["target"])
print("目标编码结果:")
print(df_encoded[["color"]])
目标编码结果:
color
0 27.699135
1 28.255830
2 28.110503
3 27.699135
4 28.110503
Weight of Evidence(证据权重编码,WOE)
- 核心逻辑:专为二分类任务设计,计算每个类别对正/负样本的区分度:\[WOE = ln(\frac{正样本占比}{负样本占比}) \]
- 输出形式:每个类别特征生成1列,值为WOE值;
- 适用场景:二分类任务(如风控、违约预测),WOE值可直接体现类别对目标的区分能力。
import pandas as pd
import category_encoders as ce
# 1. 构建示例数据
data = {
"color": ["红", "蓝", "红", "绿", "蓝", "绿", "红"],
"target": [1, 0, 1, 0, 0, 1, 1,] # 二分类标签:0/1
}
df_temp = pd.DataFrame(data)
# 2. 查看原始数据(变量名同步修改)
print("原始数据:")
print(df_temp)
print("-" * 50)
# 3. 执行WOE编码(变量名同步修改)
encoder = ce.WOEEncoder(cols=["color"])
df_encoded = encoder.fit_transform(df_temp, y=df_temp["target"])
# 4. 输出编码结果
print("证据权重(WOE)编码结果:")
print(df_encoded[["color"]])
原始数据:
color target
0 红 1
1 蓝 0
2 红 1
3 绿 0
4 蓝 0
5 绿 1
6 红 1
--------------------------------------------------
证据权重(WOE)编码结果:
color
0 1.203973
1 -1.280934
2 1.203973
3 -0.182322
4 -1.280934
5 -0.182322
6 1.203973
Quantile Encoder(分位数编码)
- 核心逻辑:用类别对应的目标变量分位数(如中位数、四分位数)替换类别,而非均值,抗异常值更强;
- 关键参数:
quantile(分位数,默认0.5即中位数); - 输出形式:每个类别特征生成1列,值为目标变量的分位数;
- 适用场景:目标变量有异常值的回归任务,需稳健的统计量替代均值。
# 用75分位数编码
encoder = ce.QuantileEncoder(cols=["color"], quantile=0.75)
df_encoded = encoder.fit_transform(df, y=df["target"])
print("分位数编码结果:")
print(df_encoded[["color"]])
分位数编码结果:
color
0 27.333333
1 29.700000
2 29.166667
3 27.333333
4 29.166667
Summary Encoder(分位数摘要编码)
- 核心逻辑:对每个类别计算目标变量的指定分位数(如25%分位数、中位数、75%分位数等),生成多列编码;
- 关键参数:
quantiles(分位数列表,默认(0.25, 0.75))、m(贝叶斯平滑系数,默认1.0,缓解稀有类别分位数估计偏差); - 输出形式:每个类别特征生成
len(quantiles)列,列名格式为「原列名_分位数值」(如 color_0.25、color_0.5); - 适用场景:高基数类别特征编码(如用户ID、商品SKU),分位数对异常值鲁棒,相比均值编码更稳定,但列数随分位数数量增加。
encoder = ce.SummaryEncoder(
cols=["color"], # 仅编码color列
quantiles=[0.25, 0.5, 0.75], # 计算25%分位数、中位数(0.5)、75%分位数
m=1.0, # 平滑系数,缓解过拟合
handle_unknown="value", # 未知类别用全局分位数填充
handle_missing="value" # 缺失值用全局分位数填充
)
df_encoded = encoder.fit_transform(df, y=df["target"])
print("汇总编码结果:")
print(df_encoded.filter(like="color"))
汇总编码结果:
color_25 color_50 color_75
0 26.000000 26.833333 27.333333
1 28.400000 29.300000 29.700000
2 28.033333 28.766667 29.166667
3 26.000000 26.833333 27.333333
4 28.033333 28.766667 29.166667
3 参考
本文来自博客园,作者:落痕的寒假,转载请注明原文链接:https://www.cnblogs.com/luohenyueji/p/19368711

浙公网安备 33010602011771号