分类特征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
关键改进点
- 避免重新拟合全部数据:仅在列无编码器时才首次拟合,后续只追加新值到编码器的
classes_中 - 旧值标签一致性:原有
classes_保持不变,旧值的标签永远和第一次编码时一致 - 新值自动分配标签:新出现的值会被追加到
classes_末尾,分配的标签为当前最大标签+1,不会干扰旧值 - 跨运行持久化:每次运行后更新并保存编码器,程序重启后加载即可复用完整映射
注意事项
- 确保预处理逻辑(如192.168地址替换)在编码前执行,避免新生成的"0"被当作新值重复处理
- 如果数据中有
NaN值,建议先统一替换为固定字符串(如"UNKNOWN"),避免编码报错 - 若需要反向转换(标签转原始值),直接调用对应编码器的
inverse_transform方法即可
内容的提问来源于stack exchange,提问作者Zeeshan Khalid
相关产品推荐
相关产品推荐

