tensorflow embedding_lookup_sparse embedding_lookup

多值离散特征(muit-onehot)

推荐系统遇上深度学习(四)--多值离散特征的embedding解决方案

在处理DeepFM数据时,由于每一个离散特征只有一个取值,因此我们在处理的过程中,将原始数据处理成了两个文件,一个记录特征的索引,一个记录了特征的值,而每一列,则代表一个离散特征。

但假如,我们某一个离散特征有多个取值呢?举个例子来说,每个人喜欢的NBA球队,有的人可能喜欢火箭和湖人,有的人可能只喜欢勇士,也有的人喜欢骑士、绿军、猛龙等一大堆。对于这种特征,我们本文将其称为多值离散特征。

根据DeepFM的思想,我们需要将每一个field的特征转换为定长的embedding,即使有多个取值,也是要变换成定长的embedding。

那么,一种思路来了,比如一个用户喜欢两个球队,这个field的特征可能是[1,1,0,0,0,0,0.....0],那么我们使用两次embedding lookup,再取个平均不就好了嘛。

嗯,这的确也许可能是一种思路吧,在tensorflow中,其实有一个函数能够实现我们上述的思路,那就是tf.nn.embedding_lookup_sparse。别着急,我们一步一步来实现多值离散特征的embedding处理过程。

import tensorflow as tf
csv = [
  "1,harden|james|curry",
  "2,wrestbrook|harden|durant",
  "3,|paul|towns",
]
TAG_SET = ["harden", "james", "curry", "durant", "paul","towns","wrestbrook"]
def sparse_from_csv(csv):
  ids, post_tags_str = tf.decode_csv(csv, [[-1], [""]])
  table = tf.contrib.lookup.index_table_from_tensor(
      mapping=TAG_SET, default_value=-1) ## 这里构造了个查找表 ##
  split_tags = tf.string_split(post_tags_str, "|")
  return tf.SparseTensor(
      indices=split_tags.indices,
      values=table.lookup(split_tags.values), ## 这里给出了不同值通过表查到的index ##
      dense_shape=split_tags.dense_shape)
TAG_EMBEDDING_DIM = 3
embedding_params = tf.Variable(tf.truncated_normal([len(TAG_SET), TAG_EMBEDDING_DIM]))#截断的正态分布
tags = sparse_from_csv(csv)
embedded_tags = tf.nn.embedding_lookup_sparse(embedding_params, sp_ids=tags, sp_weights=None)
with tf.Session() as s:
  s.run([tf.global_variables_initializer(), tf.tables_initializer()])
  print(s.run([embedded_tags]))
  print(s.run(embedding_params))
[array([[-0.13585784, -0.4606956 , -0.31155238],
       [ 0.02821189, -0.80487055, -0.7014771 ],
       [ 0.2527069 ,  0.06115395, -0.22305197]], dtype=float32)]
[[-0.43968475 -1.7722744   0.2279189 ]
 [ 0.10022298 -0.08266275 -1.2985536 ]
 [-0.06811174  0.47285038  0.13597757]
 [ 0.9904324  -0.73272985 -0.9167392 ]
 [-0.7143307   0.68751687 -0.3415346 ]
 [ 1.2197444  -0.565209   -0.10456932]
 [-0.46611196  0.09039259 -1.415611  ]]

embedding_lookup

tf.nn.embedding_lookup函数的用法主要是选取一个张量里面索引对应的元素。tf.nn.embedding_lookup(params, ids):params可以是张量也可以是数组等,id就是对应的索引,其他的参数不介绍。

import tensorflow as tf
p = tf.Variable(tf.random_normal([10,1]))#生成10*1的张量
b = tf.nn.embedding_lookup(p, [1, 3])#查找张量中的序号为1和3的
 
with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    print(sess.run(p))
    print('haha')
    print(sess.run(b))
[[-1.2463812]
 [-1.870815 ]]
[[-2.490596  ]
 [-1.2463812 ]
 [-0.97433823]
 [-1.870815  ]
 [ 1.5988917 ]
 [-0.43845415]
 [-1.0347619 ]
 [-0.98937106]
 [ 0.763335  ]
 [-1.6154797 ]]

​
import tensorflow as tf
import numpy as np

a = [[0.1, 0.2, 0.3], [1.1, 1.2, 1.3], [2.1, 2.2, 2.3], [3.1, 3.2, 3.3], [4.1, 4.2, 4.3]]
a = np.asarray(a)
idx1 = tf.Variable([0, 2, 3, 1], tf.int32)
idx2 = tf.Variable([[0, 2, 3, 1], [4, 0, 2, 2]], tf.int32)
out1 = tf.nn.embedding_lookup(a, idx1)
out2 = tf.nn.embedding_lookup(a, idx2)
init = tf.global_variables_initializer()

with tf.Session() as sess:
    sess.run(init)
    print(sess.run(out1))
    print(out1)
    print('==================')
    print(sess.run(out2))
    print(out2)
[[0.1 0.2 0.3]
 [2.1 2.2 2.3]
 [3.1 3.2 3.3]
 [1.1 1.2 1.3]]
Tensor("embedding_lookup_4/Identity:0", shape=(4, 3), dtype=float64)
==================
[[[0.1 0.2 0.3]
  [2.1 2.2 2.3]
  [3.1 3.2 3.3]
  [1.1 1.2 1.3]]

 [[4.1 4.2 4.3]
  [0.1 0.2 0.3]
  [2.1 2.2 2.3]
  [2.1 2.2 2.3]]]
Tensor("embedding_lookup_5/Identity:0", shape=(2, 4, 3), dtype=float64)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值