趋近智
处理分类特征时,特别是那些拥有大量独特值(高基数)的特征,独热编码等方法可能导致特征数量急剧增加,从而使模型计算成本高昂且容易过拟合 (overfitting)。类似地,目标编码需要谨慎处理以防止数据泄露。哈希编码器,通常被称为“哈希技巧”,提供了一种替代方法,能够有效处理高基数特征,适用于在线学习场景,同时保持输出维度固定。
哈希编码的核心思想是使用哈希函数将可能众多的类别值映射到预定义、固定数量的维度(输出特征)中。哈希编码不是为每个类别分配一个唯一的列(如独热编码),也不是基于目标变量计算统计量(如目标编码),而是将哈希函数应用于类别名称(通常表示为字符串),然后使用生成的哈希值来决定哪个输出列将代表该类别。
%)被缩减到所需的输出维度数量。如果您想要 个输出特征,您就计算 hash_value % k。这个操作将哈希值映射到 0 和 之间的索引。hash_value % k)对应的列中的值通常设为 1。其他实现可能采用不同方案,例如根据哈希值的另一个位使用 +1 或 -1 来轻微减轻冲突影响,甚至使用特征计数。考虑一个分类特征“城市”,其值包括“伦敦”、“巴黎”、“东京”、“纽约”。如果我们的哈希编码器选择 n_components=3:
1234567890 -> 1234567890 % 3 -> 索引 09876543210 -> 9876543210 % 3 -> 索引 05555555555 -> 5555555555 % 3 -> 索引 11122334455 -> 1122334455 % 3 -> 索引 2生成的编码特征可能如下所示:
| 原始值 | 哈希特征 0 | 哈希特征 1 | 哈希特征 2 |
|---|---|---|---|
| London | 1 | 0 | 0 |
| Paris | 1 | 0 | 0 |
| Tokyo | 0 | 1 | 0 |
| New York | 0 | 0 | 1 |
请注意这里的一个重要问题:'London' 和 'Paris' 被映射到了相同的输出特征(索引 0)。这被称为哈希冲突。
n_components),而不受独特类别数量的影响。这避免了独热编码在高基数特征上导致的维度激增问题。n_components)的增加,冲突的可能性也会增加。hash_0 并非特指“伦敦”或“巴黎”,而是指恰好哈希到该索引的类别集合。这使得解释与哈希特征相关的模型系数或特征重要性变得困难。n_components: 选择输出维度数量是一个重要的超参数 (parameter) (hyperparameter)。维度过少会增加冲突风险,可能损害性能。维度过多可能会抵消部分降维优势,尽管对于高基数特征来说,它仍会远少于独热编码。这通常需要根据模型验证性能进行调整。category_encoders 实现虽然 Scikit-learn 有一个常用于文本的 HashingVectorizer,但 category_encoders 库提供了一个方便的 HashingEncoder,专门用于 DataFrame 中的分类特征。
import pandas as pd
import category_encoders as ce
# 示例数据
data = {'Color': ['Red', 'Blue', 'Green', 'Red', 'Yellow', 'Blue', 'Black'],
'Value': [10, 20, 15, 12, 25, 18, 5]}
df = pd.DataFrame(data)
# 定义输出维度(特征)的数量
n_output_features = 4
# 初始化哈希编码器
# 我们指定要编码的列和所需的组件数量
encoder = ce.HashingEncoder(cols=['Color'], n_components=n_output_features)
# 拟合并转换数据
df_encoded = encoder.fit_transform(df)
print("原始DataFrame:")
print(df)
print("\n哈希编码后的DataFrame (n_components=4):")
print(df_encoded)
# 示例说明如何处理新类别
new_data = pd.DataFrame({'Color': ['Red', 'Orange', 'Blue'], 'Value': [11, 30, 22]})
df_new_encoded = encoder.transform(new_data) # 使用 transform,而不是 fit_transform
print("\n编码新数据(包含 'Orange'):")
print(df_new_encoded)
输出的 df_encoded 会将被“Color”列替换为 n_output_features(本例中为 4)个新列,命名为 col_0、col_1、col_2、col_3。每行将根据原始“Color”值的哈希结果,将值(通常是 1,但实现细节有所不同)分布在这些列中。请注意,transform 步骤中如何无误地处理了 new_data 中未见过的类别“Orange”。
哈希编码特别有用时:
当简单方法难以处理时,它通常是一个实用的选择,但请注意哈希冲突的潜在影响。通常需要尝试 n_components 的不同值,并评估其对后续模型性能的影响。
这部分内容有帮助吗?
© 2026 ApX Machine LearningAI伦理与透明度•