如何基于关联多值特征构建可输入神经网络的Tensor?
问题
现有一组关联的多值特征,示例如下:
| ItemCodes | Scores |
|---|---|
| AK, NA, UY | 0.6, 0.2, 0.2 |
| KG, AK | 0.5, 0.5 |
每个Item对应一个Score,部分行可能无Item/Score。需要将包含其他数值特征的该数据集转换为可输入神经网络的格式,数据来自系统其他模块的独立API。
尝试构建ItemCodes的二进制向量(存在则为1),以及对应索引存储Score值的第二向量。仅处理ItemCodes时,可通过多热编码得到特征向量,目前使用values = tft.compute_and_apply_vocabulary(itemcodes)获取索引并在输出Tensor中设为1。但存在问题:若Item“AK”被分配到多热Tensor的索引j,如何确保Score“0.6”也被设置到第二Tensor的索引j?由于存在缺失值,ItemCodes和Score以SparseTensor形式存在,无法直接迭代。请问如何实现需求,或是否有更优的特征表示方式?
解决方案
一、确保Item与Score索引对齐的实现方法
因为ItemCodes和Scores是按位置一一对应的SparseTensor,核心是利用它们的indices维度绑定对应关系:
提前构建全局词汇表
先对ItemCodes生成固定的全局词汇表,避免每次映射索引变化:# 提前生成词汇表,VOCAB_SIZE为预估的Item总数 item_vocab = tft.vocabulary(itemcodes, vocab_size=VOCAB_SIZE) # 对ItemCodes应用词汇表,得到每个Item对应的固定索引 item_indices = tft.apply_vocabulary(itemcodes, item_vocab)基于共享索引构建对应张量
由于ItemCodes和Scores的SparseTensor具有相同的indices结构(即每行非缺失值的位置坐标一致),可以直接将Score值与Item索引绑定,生成对齐的向量:# 构建(行索引, Item索引)的二维索引结构,对应Score值 score_sparse = tf.SparseTensor( indices=tf.concat([itemcodes.indices[:, :1], item_indices[:, tf.newaxis]], axis=1), values=scores.values, dense_shape=[tf.shape(itemcodes)[0], VOCAB_SIZE] ) # 转换为稠密张量,缺失位置填充0.0 score_vector = tf.sparse.to_dense(score_sparse, default_value=0.0) # 用同样方式生成多热二进制向量 multihot_vector = tf.sparse.to_dense( tf.SparseTensor( indices=tf.concat([itemcodes.indices[:, :1], item_indices[:, tf.newaxis]], axis=1), values=tf.ones_like(item_indices, dtype=tf.float32), dense_shape=[tf.shape(itemcodes)[0], VOCAB_SIZE] ), default_value=0.0 )这样就能保证同一个Item的二进制标记和Score值落在向量的同一索引位置。
缺失值处理
无Item/Score的行,sparse_to_dense会自动填充默认值0.0,无需额外逻辑。
二、更优的特征表示方式
直接使用加权多热向量替代两个独立向量,更高效且避免对齐问题:
- 不再区分二进制向量和Score向量,将每个Item对应的Score值直接作为向量对应索引的取值,不存在的Item取0。
- 这种方式同时保留了Item的存在性和Score的权重信息,减少了输入特征维度,实现逻辑和上述
score_vector完全一致,直接将该向量作为模型输入即可。
内容的提问来源于stack exchange,提问作者Utkarsh D

