多值离散问题:有的特征只有一个固定的取值,但是有的特征有不确定个数的取值,在tensorflow中特征输入又需要一样的长度。比如一个电影的类型可以有多种等,对电影类型进行嵌入时就会遇到问题。多个类型时,可以把多个类型的嵌入向量求和、求平均、根号等等。
一直不熟悉tensorflow,刚开始这个问题卡了我很久,还是记录一下吧。
刚开始遇到这个问题,其实思路求平均等很简单,只不过自己不熟悉tensorflow,刚开始不知道如何自定义的处理,就按照网上搜到的这个方法。
TAG_SET = ["A","B","C","D","E"]#所有可能的取值
tags_str=["A|B|C",
"E|",
"C|D",
]#必须是List 每个元素是str
table = contrib.lookup.index_table_from_tensor(mapping=TAG_SET, default_value=-1)
split_tags = tf.string_split(tags_str,"|")
tags=tf.SparseTensor(indices=split_tags.indices,
values=table.lookup(split_tags.values),
dense_shape=split_tags.dense_shape)
A_embed_marix=tf.Variable(tf.random_uniform([len(TAG_SET),5],-1,1))
A_embed_layer=tf.nn.embedding_lookup_sparse(A_embed_marix,sp_ids=tags,sp_weights=None)
with tf.Session() as sess:
sess.run([tf.global_variables_initializer(),tf.tables_initializer()])
a,b=sess.run([A_embed_marix,A_embed_layer])
print(a)
print(b)
注意的一些问题:
①TAG_SET是所有可能的特征取值
②传入的原特征数据应该是字符类型的list(不知道是否一定是str 必须是list)
③tf.tables_initializer()必须初始化
④使用placeholder 我是先传入(n,1)的tensor 然后降维变成list的
①每条数据最多有len(TAG_SET)个取值
将所有特征取值编号 用字典代替(取值:id)再用一个最大id表示填充取值
将每条数据转化成[id1,id2,…id填充,id填充] 长度是len(TAG_SET)+1
②嵌入层还是len(TAG_SET)+1×嵌入dim,但是最后一行嵌入层取值全为0(代表最大id填充取值)
③这样传入的数据是n×len(TAG_SET)+1,
经过嵌入层,变成n×len(TAG_SET)+1×嵌入dim,
然后使用tf的函数对axis=1这一维度求和等 变成n×嵌入dim
求平均的话,会都除以len(TAG_SET)+1 应该除以非填充id个数 暂时不知道咋处理
TAG_SET = ["A","B","C","D","E"]#所有可能的取值
TAG_MAP={v:i for i,v in enumerate(TAG_SET)}
TAG_MAP['PAD']=len(TAG_SET)
print(TAG_MAP)
x=tf.Variable([[0,1,2,5,5,5],#ABC
[4,5,5,5,5,5],#E
[2,3,5,5,5,5],#CD
])
#嵌入层维度5
A_embed_marix=tf.Variable(tf.random_uniform([len(TAG_SET),5],-1,1))#所有特征取值的嵌入层
pad_embed=tf.zeros([1,5],tf.float32)#填充id的嵌入层全为0
A_embed_marix=tf.concat([A_embed_marix,pad_embed],axis=0)#加上填充之后的嵌入层
A_embed_layer=tf.nn.embedding_lookup(A_embed_marix,ids=x)#(?,特征所有取值数+1,嵌入层dim)(?,6,5)
A_embed_layer=tf.reduce_sum(A_embed_layer,axis=1)#(?,嵌入层dim)(?,5)
with tf.Session() as sess:
sess.run([tf.global_variables_initializer(),tf.tables_initializer()])
a,b=sess.run([A_embed_marix,A_embed_layer])
print(a)
print(b)
刚开始完全不懂一些tf的函数,但还是感觉这种方法灵活些,或者使用one-hot将原数据表示,和嵌入层矩阵相乘,就是求和了,总之1的处理绝对是正确的 2的处理我感觉是可行的,但是目前如何取平均 根号等还没解决
参考文章:
https://blog.csdn.net/qq_35946969/article/details/89489185
https://www.jianshu.com/p/63359e928b99