【漫话机器学习系列】048.编码有序类别特征(Encoding Ordinal Categorical Features)
在机器学习和数据预处理中,有序类别特征(Ordinal Categorical Features)是一种具有自然顺序但没有明确间隔大小的变量。例如:
- 教育水平:小学 < 初中 < 高中 < 大学
- 客户满意度:非常不满意 < 不满意 < 一般 < 满意 < 非常满意
对这些特征进行编码时,需要保留类别之间的顺序关系,以便模型能够正确理解数据的语义。
常见的编码方法
1. 整数编码(Integer Encoding)
将类别映射为整数,根据类别的顺序依次分配数字。
-
示例: 教育水平:
['小学', '初中', '高中', '大学']
编码为:[1, 2, 3, 4]
-
优点:
- 简单易用。
- 保留了类别的顺序信息。
-
缺点:
- 假设类别之间的差异是等距的,可能引入误导。
2. 目标编码(Target Encoding)
用每个类别对应目标变量(如回归中的连续值或分类中的概率)计算的统计量进行编码。
-
示例:假设目标变量为收入水平。 教育水平的平均收入:
- 小学:20,000
- 初中:30,000
- 高中:40,000
- 大学:60,000
编码为:[20000, 30000, 40000, 60000]
-
优点:
- 考虑了类别的目标信息。
- 有助于模型捕获类别与目标变量之间的关系。
-
缺点:
- 易过拟合,尤其在数据量较少时。
3. 权重编码(Weight Encoding)
对类别赋予权重值,通常通过专家经验或业务规则设置权重。
-
示例:客户满意度
- 非常不满意:0.1
- 不满意:0.3
- 一般:0.5
- 满意:0.7
- 非常满意:1.0
-
优点:
- 灵活,能反映业务的先验知识。
- 保留了顺序关系。
-
缺点:
- 主观性强。
如何选择编码方法?
-
数据特点:
- 如果类别数较少(如 3-5),
整数编码
或权重编码
通常足够。 - 如果类别数较多且与目标变量关系强,可以尝试
目标编码
。
- 如果类别数较少(如 3-5),
-
模型类型:
- 对于线性模型(如回归),避免引入多重共线性,可以使用
整数编码
。 - 对于非线性模型(如决策树),可以直接使用编码后的值,无需额外处理。
- 对于线性模型(如回归),避免引入多重共线性,可以使用
-
数据量:
- 数据量较小时,应避免使用目标编码,以免过拟合。
Python 实现示例
整数编码
from sklearn.preprocessing import OrdinalEncoder
# 示例数据
data = [['小学'], ['初中'], ['高中'], ['大学']]
encoder = OrdinalEncoder(categories=[['小学', '初中', '高中', '大学']])
encoded = encoder.fit_transform(data)
print(encoded)
运行结果
[[0.]
[1.]
[2.]
[3.]]
目标编码
import pandas as pd
# 示例数据
df = pd.DataFrame({
'Education': ['小学', '初中', '高中', '大学', '大学'],
'Income': [20000, 30000, 40000, 60000, 62000]
})
# 计算每个类别的平均目标值
mean_income = df.groupby('Education')['Income'].mean()
df['Education_encoded'] = df['Education'].map(mean_income)
print(df)
运行结果
Education Income Education_encoded
0 小学 20000 20000.0
1 初中 30000 30000.0
2 高中 40000 40000.0
3 大学 60000 61000.0
4 大学 62000 61000.0
总结
编码有序类别特征时,关键是保留类别的顺序信息并结合任务目标合理选择方法。
对于初学者,推荐从整数编码开始;对于复杂场景,可以尝试目标编码或结合业务知识使用权重编码。