独热编码(One-Hot Encoding)对名义类别(顺序不重要)有效,但将其应用于序数数据(即具有有意义序列的类别)时,可能会丢失有价值的排序信息。考虑像客户满意度('Low'低, 'Medium'中, 'High'高)或服装尺码('S'小, 'M'中, 'L'大, 'XL'特大)这样的特征。这里的顺序是固有的,并且可能与您尝试预测的目标变量相关。序数编码旨在通过将每个类别映射到不同的整数来保留此序列。此方法:分配排序序数编码通过根据预定义顺序中的位置,为每个独特类别分配一个数值排序,通常从0或1开始。例如,如果我们有教育水平:'High School'(高中), 'Bachelor's'(学士), 'Master's'(硕士), 'PhD'(博士),我们可以这样映射它们:'High School'(高中):0'Bachelor's'(学士):1'Master's'(硕士):2'PhD'(博士):3这种数值表示直接反映了类别中固有的进展。实施序数编码您可以使用Pandas手动实施序数编码,或借助Scikit-learn的专用转换器。使用Pandas手动映射如果您知道类别的具体顺序,定义自定义映射字典并使用Pandas的map函数会很简单。import pandas as pd # 带有序数特征的示例数据 data = {'ID': [1, 2, 3, 4, 5], 'Satisfaction': ['Medium', 'Low', 'High', 'Medium', 'Low']} df = pd.DataFrame(data) # 定义所需的顺序和映射 satisfaction_mapping = {'Low': 0, 'Medium': 1, 'High': 2} # 将映射应用于“Satisfaction”列 df['Satisfaction_Encoded'] = df['Satisfaction'].map(satisfaction_mapping) print(df)此代码生成: ID Satisfaction Satisfaction_Encoded 0 1 Medium 1 1 2 Low 0 2 3 High 2 3 4 Medium 1 4 5 Low 0这种方法让您完全控制赋值,但每个序数特征都需要手动定义。使用Scikit-learn的OrdinalEncoderScikit-learn在其preprocessing模块中提供了OrdinalEncoder类。它可以自动确定类别或接受预定义的顺序。重要的是,对于序数数据,您应始终通过categories参数指定顺序,以确保编码反映真实序列,而不是基于数据中类别出现的顺序或字母顺序的任意序列。import pandas as pd from sklearn.preprocessing import OrdinalEncoder # 示例数据 data = {'ID': [1, 2, 3, 4, 5], 'Satisfaction': ['Medium', 'Low', 'High', 'Medium', 'Low'], 'Size': ['M', 'S', 'XL', 'L', 'M']} df = pd.DataFrame(data) # 定义每个序数列的具体顺序 satisfaction_order = ['Low', 'Medium', 'High'] size_order = ['S', 'M', 'L', 'XL'] # 使用定义的顺序初始化编码器 # 注意:categories是一个列表的列表,每个特征一个内层列表 encoder = OrdinalEncoder(categories=[satisfaction_order, size_order]) # 应用编码器 # 选择与'categories'匹配的正确顺序的列进行编码 encoded_features = encoder.fit_transform(df[['Satisfaction', 'Size']]) # 在DataFrame中为编码后的特征创建新列 df['Satisfaction_Encoded'] = encoded_features[:, 0] df['Size_Encoded'] = encoded_features[:, 1] print(df)输出显示了编码后的特征: ID Satisfaction Size Satisfaction_Encoded Size_Encoded 0 1 Medium M 1.0 1.0 1 2 Low S 0.0 0.0 2 3 High XL 2.0 3.0 3 4 Medium L 1.0 2.0 4 5 Low M 0.0 1.0如果您省略categories参数,OrdinalEncoder可能会按字母顺序或按出现顺序分配整数,这将破坏序数关系(例如,按字母顺序将'High'赋值为0,'Low'赋值为1,'Medium'赋值为2)。对于有意义的序数编码,请始终明确定义顺序。{"data": [{"type": "bar", "x": ["Low", "Medium", "High"], "y": [0, 1, 2], "marker": {"color": ["#ffc9c9", "#ffd8a8", "#b2f2bb"]}, "name": "满意度编码"}], "layout": {"title": "序数编码映射示例", "xaxis": {"title": "原始类别"}, "yaxis": {"title": "编码整数值", "tickmode": "array", "tickvals": [0, 1, 2]}, "bargap": 0.2}}条形图直观地表示了为“Satisfaction”特征定义的映射,清楚地显示了基于指定顺序的数值分配。优点与缺点优点:保留顺序: 直接编码类别的序列性质。简单易行: 易于理解和实施。维度: 将特征保留为单列,避免了独热编码中出现的维度增加。缺点:任意数值差: 类别之间的数值差是恒定的(例如0、1、2、3)。这意味着“低”和“中”之间的差异与“中”和“高”之间的差异相同。此假设可能不成立,并且可能误导对特征数值大小和距离敏感的算法(如线性模型、SVM、KNN)。模型解释: 线性模型可能将编码值解释为具有一致的线性效应,这可能无法反映真实的潜在关系。需要已知顺序: 您必须正确定义序列;不正确的顺序会使编码变得无意义或具有误导性。何时使用序数编码序数编码在以下情况下最为适用:类别特征具有清晰、固有的顺序。您使用的模型可以自然处理序数关系,而不会对任意数值差假设过于敏感(例如,基于树的模型,如决策树、随机森林、梯度提升)。这些模型主要关注分割点,而不是值之间的精确数值距离。保持较低维度很重要。尽管当数值映射与目标变量的关系良好对齐时,它可能对线性模型有用,但请谨慎对待等间距假设。除非数值映射真正反映了类别之间有意义的距离,否则它通常不太适合基于距离的算法。在决定序数编码是否是正确选择时,请始终考虑您数据的性质以及所选机器学习算法的要求。