You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MultiIndex数据框LabelEncoder编码时未知标签ValueError问题求解

解决LabelEncoder测试集未知标签报错问题

现有18×80的Pandas MultiIndex数据框,分为“TEAM ONE”和“TEAM TWO”两组,需对categoricals数组指定的分类列做LabelEncoder编码,但测试集执行时出现ValueError: y contains previously unseen labels报错。由于LabelEncoder没有handle_unknown参数,try/except方案实用性不足,可通过以下几种方式解决:

方法1:提前检测并替换未知标签

先在训练集拟合编码器时记录所有已知标签,处理测试集前将不在训练集中的标签统一替换为“unknown”,再更新编码器的类别列表后执行转换:

import numpy as np
from sklearn.preprocessing import LabelEncoder

categoricals = ['TRAITS', 'UNIT_1', 'UNIT_2', 'UNIT_3', 'AUGMENT_1', 'AUGMENT_2', 'AUGMENT_3']
le = {col: LabelEncoder() for col in categoricals}

# 处理训练集,同时记录每个列的已知标签
for col in train_data.columns.levels[0]:
    for sub_col in train_data.columns.levels[1]:
        if sub_col in le:
            train_series = train_data[(col, sub_col)].astype(str)
            le[sub_col].fit(train_series)
            train_data[(col, sub_col)] = le[sub_col].transform(train_series)
            # 保存该列的已知标签集合
            le[sub_col].known_labels = set(le[sub_col].classes_)

# 处理测试集:替换未知标签并转换
for col in test_data.columns.levels[0]:
    for sub_col in test_data.columns.levels[1]:
        if sub_col in le:
            test_series = test_data[(col, sub_col)].astype(str)
            # 替换不在训练集中的标签为统一值
            test_series = test_series.apply(lambda x: x if x in le[sub_col].known_labels else 'unknown')
            # 将统一值加入编码器的类别列表(避免transform报错)
            if 'unknown' not in le[sub_col].classes_:
                le[sub_col].classes_ = np.append(le[sub_col].classes_, 'unknown')
            test_data[(col, sub_col)] = le[sub_col].transform(test_series)

方法2:改用OrdinalEncoder(推荐)

OrdinalEncoder支持handle_unknown参数,可直接指定未知标签的编码值(如-1),无需额外处理,更适合批量列的编码场景:

from sklearn.preprocessing import OrdinalEncoder

categoricals = ['TRAITS', 'UNIT_1', 'UNIT_2', 'UNIT_3', 'AUGMENT_1', 'AUGMENT_2', 'AUGMENT_3']
encoders = {}

for col in train_data.columns.levels[0]:
    for sub_col in categoricals:
        # 初始化编码器,设置未知标签处理规则
        enc = OrdinalEncoder(handle_unknown='use_encoded_value', unknown_value=-1)
        # 拟合并转换训练集
        train_col = train_data[(col, sub_col)].astype(str).values.reshape(-1, 1)
        train_data[(col, sub_col)] = enc.fit_transform(train_col).flatten()
        # 转换测试集
        test_col = test_data[(col, sub_col)].astype(str).values.reshape(-1, 1)
        test_data[(col, sub_col)] = enc.transform(test_col).flatten()
        encoders[(col, sub_col)] = enc

方法3:手动构建标签映射字典

跳过LabelEncoder,自己建立训练集标签到编码的映射,测试集遇到未知标签时返回默认值(如-1):

categoricals = ['TRAITS', 'UNIT_1', 'UNIT_2', 'UNIT_3', 'AUGMENT_1', 'AUGMENT_2', 'AUGMENT_3']
label_maps = {}

# 构建训练集的标签-编码映射
for col in train_data.columns.levels[0]:
    for sub_col in categoricals:
        train_series = train_data[(col, sub_col)].astype(str)
        unique_labels = train_series.unique()
        label_map = {label: idx for idx, label in enumerate(unique_labels)}
        label_maps[(col, sub_col)] = label_map
        # 转换训练集
        train_data[(col, sub_col)] = train_series.map(label_map)

# 转换测试集,未知标签用-1标记
for col in test_data.columns.levels[0]:
    for sub_col in categoricals:
        test_series = test_data[(col, sub_col)].astype(str)
        label_map = label_maps[(col, sub_col)]
        test_data[(col, sub_col)] = test_series.map(lambda x: label_map.get(x, -1))

内容的提问来源于stack exchange,提问作者Mangohero1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 12:06:24