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

分类特征Label Encoding:跨运行保持标签一致性方案问询

解决方案:持久化且兼容新值的Label Encoding实现

问题分析

原代码的核心问题在于每次调用fit_transform会重新拟合整个列的所有值,哪怕加载了之前的编码器,也会覆盖原有标签映射。这直接导致:

  • 旧值的标签在多次运行时可能改变
  • 无法正确处理新出现的数值(会打乱原有标签序列)

修正后的代码

from sklearn.preprocessing import LabelEncoder
import pickle
import numpy as np

def label_encoding(df_logs):
    # 加载已有的标签映射,无则初始化空字典
    try:
        with open('label_mapping.pkl', 'rb') as f:
            label_mapping = pickle.load(f)
    except FileNotFoundError:
        label_mapping = {}

    cols_to_encode = [
        'Attack', 'Category', 'DstLocation', 'Os', 'SignName', 'SrcLocation', 'Target',
        'UserName', 'VSys', 'slot', 'Action', 'Policy', 'Profile', 'Protocol-Name',
        'Application', 'Source-zone', 'CloseReason', 'Destination-zone', 'ModuleName',
        'ModuleBrief', 'RecieveInterface', 'Policy-name', 'IP-address', 'Source-address', 'Destination-address'
    ]

    # 预处理特定列
    df_logs['Source-address'] = df_logs['Source-address'].apply(lambda x: '0' if x.startswith('192.168') else x)
    df_logs['Destination-address'] = df_logs['Destination-address'].apply(lambda x: '0' if x.startswith('192.168') else x)

    for col in cols_to_encode:
        # 获取当前列的所有唯一值
        current_values = df_logs[col].unique()
        
        # 初始化或加载对应列的编码器
        if col not in label_mapping:
            le = LabelEncoder()
            le.fit(current_values)
            label_mapping[col] = le
        else:
            le = label_mapping[col]
            # 找出当前列中未被编码器记录的新值
            existing_classes = set(le.classes_)
            new_values = [val for val in current_values if val not in existing_classes]
            
            if new_values:
                # 更新编码器的classes_,保持原有标签不变,新值追加到末尾
                new_classes = np.concatenate([le.classes_, new_values])
                le.classes_ = new_classes
        
        # 转换当前列(此时旧值标签不变,新值会分配新的递增标签)
        df_logs[col] = le.transform(df_logs[col])

    # 保存更新后的标签映射
    with open('label_mapping.pkl', 'wb') as f:
        pickle.dump(label_mapping, f)

    return df_logs

关键改进点

  1. 避免重新拟合全部数据:仅在列无编码器时才首次拟合,后续只追加新值到编码器的classes_中
  2. 旧值标签一致性:原有classes_保持不变,旧值的标签永远和第一次编码时一致
  3. 新值自动分配标签:新出现的值会被追加到classes_末尾,分配的标签为当前最大标签+1,不会干扰旧值
  4. 跨运行持久化:每次运行后更新并保存编码器,程序重启后加载即可复用完整映射

注意事项

  • 确保预处理逻辑(如192.168地址替换)在编码前执行,避免新生成的"0"被当作新值重复处理
  • 如果数据中有NaN值,建议先统一替换为固定字符串(如"UNKNOWN"),避免编码报错
  • 若需要反向转换(标签转原始值),直接调用对应编码器的inverse_transform方法即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 08:23:31