如何使用embedding层权重作为类别特征的替代特征提升信息质量
Embedding权重映射回原数据集的实现方案
核心逻辑是通过训练阶段保存的「原始类别值-整数编码ID」映射表,把embedding权重和原始类别特征做关联,具体步骤如下:
步骤1:提取embedding权重表
首先把模型中提取的权重转成带编码ID的结构化表:
import pandas as pd import numpy as np # 提取embedding权重,shape为 (类别总数, embedding维度) emb_weights = model.get_layer('embedding1').get_weights()[0] # 生成embedding表,index就是类别对应的整数编码ID emb_df = pd.DataFrame(emb_weights, columns=['item_name_eb1', 'item_name_eb2', 'item_name_eb3']) emb_df = emb_df.reset_index().rename(columns={'index': 'item_name_id'})
步骤2:生成「原始类别-编码ID」映射表
根据你训练前编码的方式选择对应方案:
- 场景1:用
sklearn.LabelEncoder编码
# le为训练阶段使用的LabelEncoder实例 id2item = {id_: item for item, id_ in zip(le.classes_, le.transform(le.classes_))} map_df = pd.DataFrame(id2item.items(), columns=['item_name_id', 'item_name'])
- 场景2:用
Keras.Tokenizer编码
# tokenizer为训练阶段使用的Tokenizer实例 item2id = tokenizer.word_index # 注意keras默认word_index从1开始,0为padding位,若embedding层包含padding位要自行补全对应行 map_df = pd.DataFrame(item2id.items(), columns=['item_name', 'item_name_id'])
- 场景3:自定义字典编码,直接把自定义映射字典转成上述格式的
map_df即可。
步骤3:关联映射得到最终数据集
# 先合并映射表和embedding表,得到每个item_name对应的embedding值 item_emb_map = map_df.merge(emb_df, on='item_name_id', how='left') # 和原数据集合并,把embedding列拼入原数据 df = df.merge(item_emb_map[['item_name', 'item_name_eb1', 'item_name_eb2', 'item_name_eb3']], on='item_name', how='left') # 若需要替换原类别特征,删除原始item_name列即可 df = df.drop(columns=['item_name'])
该方案基于pandas向量化操作实现,不需要逐行遍历,百万级样本也可在秒级完成映射。
注意事项
- 如果丢失了训练阶段使用的类别编码映射表,无法完成映射,因为embedding权重的索引和原始类别值没有对应关系,下次训练时请注意提前保存编码映射文件。
- 若合并后出现embedding列为空的情况,说明原数据中存在训练阶段未出现过的新类别,可给这部分样本的embedding字段赋值全0,或训练时提前预留未知类别的编码位。
内容的提问来源于stack exchange,提问作者Phạm Tâm
相关产品推荐
相关产品推荐

