趋近智
标称类别特征表示没有内在顺序或等级的类别。例如颜色(“红色”、“蓝色”、“绿色”)、城市名称(“伦敦”、“东京”、“纽约”)或产品类型(“电子产品”、“服装”、“杂货”)。机器学习算法通常需要数值输入,因此我们需要一种方法将这些标签转换为数字,而不会强加人为的顺序。为此,最常用且直接的方法之一是独热编码 (OHE)。
独热编码背后的基本思想是为原始标称特征中存在的每个独特类别创建新的二元特征。对于数据集中的每个观测(行),这些新二元特征中只有一个会是“1”(热),表示该特定类别的存在,而所有其他新创建的二元特征都将是“0”。
假设一个名为“颜色”的特征有三个独特值:“红色”、“绿色”和“蓝色”。独热编码将此单列转换为三个新列:“Color_Red”、“Color_Green”和“Color_Blue”。
这种转换有效地将类别信息传递给算法,使用数值(0/1)来表达,而没有暗示类别之间的任何序数关系。
使用独热编码转换“颜色”特征。每个独特类别都获得其自己的二元列。
Pandas 提供了方便的函数 get_dummies(),可以直接在数据框或 Series 上执行独热编码。
import pandas as pd
# 示例数据框
data = {'ID': [1, 2, 3, 4],
'Color': ['Red', 'Green', 'Blue', 'Green'],
'Value': [10, 15, 5, 12]}
df = pd.DataFrame(data)
print("原始数据框:")
print(df)
# 对“Color”列应用独热编码
df_encoded = pd.get_dummies(df, columns=['Color'], prefix='Color', prefix_sep='_')
print("\n独热编码后的数据框:")
print(df_encoded)
输出:
Original DataFrame:
ID Color Value
0 1 Red 10
1 2 Green 15
2 3 Blue 5
3 4 Green 12
DataFrame after One-Hot Encoding:
ID Value Color_Blue Color_Green Color_Red
0 1 10 0 0 1
1 2 15 0 1 0
2 3 5 1 0 0
3 4 12 0 1 0
pd.get_dummies() 的重要参数:
data: 要编码的数据框或 Series。columns: 要编码的列名列表。如果为 None,则尝试编码所有对象或类别数据类型的列。prefix: 要添加到新列名开头的字符串或字符串列表。有助于标识原始特征。prefix_sep: 前缀和类别名称之间的分隔符字符串(默认为“_”)。drop_first: 一个布尔值(默认为 False)。如果设置为 True,它会为每个特征丢弃第一个类别级别。这在一些线性模型中很有用,可以避免多重共线性,因为当所有其他类别列都为 0 时,被丢弃类别的信息已被隐含地包含。例如,如果“Color_Blue”被丢弃,则“Color_Green=0”和“Color_Red=0”的行将表示颜色是蓝色。Scikit-learn 的 OneHotEncoder(来自 sklearn.preprocessing)在构建机器学习管道时通常更受青睐,特别是它能够在训练和测试阶段之间一致地处理数据。
import pandas as pd
from sklearn.preprocessing import OneHotEncoder
import numpy as np
# 示例数据框(同前)
data = {'ID': [1, 2, 3, 4],
'Color': ['Red', 'Green', 'Blue', 'Green'],
'Value': [10, 15, 5, 12]}
df = pd.DataFrame(data)
# 选择类别列——注意:OneHotEncoder 期望 2D 数组状输入
categorical_features = df[['Color']]
# 初始化编码器
# sparse_output=False 返回一个密集 NumPy 数组(更易于查看)
# handle_unknown='ignore' 可以避免测试数据中出现未见过类别时的错误
encoder = OneHotEncoder(sparse_output=False, handle_unknown='ignore')
# 拟合编码器到数据(学习类别)并转换数据
encoded_data = encoder.fit_transform(categorical_features)
# 获取编码器生成的新特征名称
encoded_feature_names = encoder.get_feature_names_out(['Color'])
# 使用编码后的特征创建新数据框
df_encoded_sklearn = pd.DataFrame(encoded_data, columns=encoded_feature_names, index=df.index)
# 与原始非类别特征合并
df_final = pd.concat([df.drop('Color', axis=1), df_encoded_sklearn], axis=1)
print("\nScikit-learn OneHotEncoder 后的数据框:")
print(df_final)
# 示例:转换新数据(可能包含未见过类别“Yellow”)
new_data = pd.DataFrame({'Color': ['Green', 'Red', 'Yellow']})
new_encoded = encoder.transform(new_data[['Color']])
print("\n编码后的新数据:")
print(pd.DataFrame(new_encoded, columns=encoded_feature_names))
输出:
DataFrame after Scikit-learn OneHotEncoder:
ID Value Color_Blue Color_Green Color_Red
0 1 10 0.0 0.0 1.0
1 2 15 0.0 1.0 0.0
2 3 5 1.0 0.0 0.0
3 4 12 0.0 1.0 0.0
Encoded new data:
Color_Blue Color_Green Color_Red
0 0.0 1.0 0.0
1 0.0 0.0 1.0
2 0.0 0.0 0.0
请注意,当使用 handle_unknown='ignore' 时,未见过类别“Yellow”的结果是全零。handle_unknown 的其他选项包括 'error'(默认值,引发错误)或使用 infrequent_if_exist 分配特定的编码向量。
sklearn.preprocessing.OneHotEncoder 的重要参数:
categories: 手动指定类别(默认为“auto”从数据中学习)。drop: {'first', 'if_binary'} 或 None(默认)。类似于 Pandas 中的 drop_first,用于为每个特征丢弃一个类别。'if_binary' 仅为具有两个类别的特征丢弃第一个类别。sparse_output: 布尔值(默认为 True)。是否返回稀疏矩阵(高维度时内存高效)或密集 NumPy 数组。对于更易于检查或较小的数据集,设置为 False。handle_unknown: {'error', 'ignore', 'infrequent_if_exist'}。如何处理 transform 期间遇到但 fit 期间未见的类别。'ignore' 为该特征输出全零。drop_first=False 或 drop=None),则生成的特征将是完全多重共线的。任何一列的值都可以由其他列的值完美预测(如果一个类别不存在,其对应的 OHE 列之和将为 0;否则为 1)。尽管许多算法(特别是基于树的算法,如随机森林或梯度提升)能够较好地处理这种情况,但线性模型(如线性回归、逻辑回归)可能会出现系数稳定性和可解释性问题。使用 drop_first=True 或 drop='first' 可以缓解此问题。fit)期间不存在的新类别,pd.get_dummies(默认情况下)和 sklearn.OneHotEncoder(使用 handle_unknown='error')都会导致问题(要么缺少列,要么出错)。使用 Scikit-learn 的 handle_unknown='ignore' 或 'infrequent_if_exist' 可以处理这种情况。OHE 是以下情况的可靠默认选择:
对于基数非常高的特征,替代编码方法,如目标编码、哈希或分箱(稍后讨论),可能更合适来管理维度。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造