特征编码 是将数据集中的分类特征(Categorical Features)转换为数值特征(Numerical Features)的过程。分类特征是机器学习模型(尤其是数值模型,如线性回归、支持向量机等)无法直接处理的数据类型,必须通过特征编码进行转换。
特征编码的主要方法
1. One-Hot Encoding(独热编码)
将分类变量的每个类别转换为一个独立的二进制特征。
特点:
- 每个类别都会变成一个新列。
- 某样本属于某个类别时,该列值为 1,其他列值为 0。
适用场景:
- 类别数量较少(低基数特征)。
- 特征之间没有大小顺序或关系。
示例:
对于一个列 Color = ['Red', 'Green', 'Blue']
:
import pandas as pd
data = pd.DataFrame({'Color': ['Red', 'Green', 'Blue']})
one_hot = pd.get_dummies(data['Color'])
print(one_hot)
输出:
Blue Green Red
0 0 0 1
1 0 1 0
2 1 0 0
2. Label Encoding(标签编码)
将每个类别映射到一个整数值。
特点:
- 简单高效。
- 但会引入类别的隐含顺序,可能会误导模型(尤其是线性模型)。
适用场景:
- 树模型(如决策树、随机森林、XGBoost 等),它们对数值的大小不敏感。
- 类别数量较多时(比 One-Hot 更节省内存)。
示例:
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
data['Color_encoded'] = le.fit_transform(data['Color'])
print(data)
输出:
Color Color_encoded
0 Red 2
1 Green 1
2 Blue 0
3. Ordinal Encoding(有序编码)
对有序分类特征(如学历、评分等)按照指定顺序进行整数映射。
特点:
- 映射顺序需由领域知识决定。
- 避免误导模型需要明确类别的大小关系。
适用场景:
- 分类特征具有明确的顺序(如“低、中、高”)。
示例:
education_mapping = {'High School': 0, 'Bachelor': 1, 'Master': 2, 'PhD': 3}
data['Education_encoded'] = data['Education'].map(education_mapping)
4. Target Encoding(目标编码)
将分类特征的每个类别替换为其对应目标变量(如回归中的目标值)的均值。
特点:
- 捕获特征和目标之间的统计关系。
- 可能引入数据泄漏,需要结合交叉验证。
适用场景:
- 高基数分类特征(如商品 ID、用户 ID)。
- 分类特征与目标变量强相关。
示例:
from category_encoders import TargetEncoder
te = TargetEncoder()
data['Category_encoded'] = te.fit_transform(data['Category'], data['Target'])
5. Binary Encoding(二进制编码)
将类别转换为其对应整数值的二进制表示,再将二进制拆分为多个列。
特点:
- 适合中等基数特征。
- 比 One-Hot 节省内存,但比 Label Encoding 更能捕捉关系。
示例:
对于类别 [‘A’, ‘B’, ‘C’, ‘D’],其编码为:
- A = 0 -> [0, 0]
- B = 1 -> [0, 1]
- C = 2 -> [1, 0]
- D = 3 -> [1, 1]
代码实现:
from category_encoders import BinaryEncoder
be = BinaryEncoder(cols=['Category'])
binary_encoded = be.fit_transform(data['Category'])
6. Frequency Encoding(频率编码)
用类别的出现频率代替类别值。
特点:
- 简单高效。
- 适合类别出现次数与目标变量相关的情况。
适用场景:
- 高基数特征。
- 频率信息与目标相关。
示例:
data['Frequency_encoded'] = data['Category'].map(data['Category'].value_counts() / len(data))
7. Hashing Encoding(哈希编码)
通过哈希函数将类别映射到固定数量的列。
特点:
- 空间效率高,避免了 One-Hot 的爆炸性增长。
- 存在哈希冲突,可能导致信息丢失。
适用场景:
- 超高基数特征(如数百万个类别)。
示例:
from sklearn.feature_extraction import FeatureHasher
fh = FeatureHasher(n_features=10, input_type='string')
hashed = fh.fit_transform(data['Category'])
对比不同编码方法
编码方法 | 是否引入顺序信息 | 内存占用 | 是否适用高基数 | 适用模型 |
---|---|---|---|---|
One-Hot Encoding | 否 | 高 | 否 | 所有模型 |
Label Encoding | 是 | 低 | 是 | 树模型(决策树等) |
Ordinal Encoding | 是 | 低 | 是 | 对顺序敏感的模型 |
Target Encoding | 否 | 中 | 是 | 所有模型 |
Binary Encoding | 否 | 中 | 是 | 所有模型 |
Frequency Encoding | 否 | 低 | 是 | 所有模型 |
Hashing Encoding | 否 | 低 | 是 | 所有模型 |
选择合适的编码方法
- 低基数特征(<10 类):
- 推荐使用 One-Hot Encoding 或 Ordinal Encoding。
- 中等基数特征(10-100 类):
- 推荐使用 Target Encoding 或 Binary Encoding。
- 高基数特征(100+ 类):
- 推荐使用 Target Encoding、Frequency Encoding 或 Hashing Encoding。
- 树模型:
- 使用 Label Encoding 或 Target Encoding。
通过合理选择编码方法,可以提升模型的效果和计算效率! 🚀