Softmax深度推荐模型中特定用户Embedding提取方法
如何从Softmax推荐模型中提取特定用户嵌入生成个性化推荐
推荐系统召回阶段的核心逻辑是计算用户嵌入Ψ(X)与物品嵌入Vj的相似度,取相似度最高的物品作为候选推荐结果。
示例代码中create_network()函数的output就是定义的用户嵌入Ψ(X),不需要修改模型结构,直接通过单样本前向推理即可提取特定用户的嵌入,具体方法如下:
实现步骤
- 模型训练收敛后,在
model变量作用域下开启参数复用,确保推理时加载的是训练完成的权重,和测试阶段的参数复用逻辑一致。 - 整理目标用户的全量特征,必须和训练时用到的特征字段、预处理逻辑完全匹配(比如用户历史评分电影、用户属性等特征),构造batch_size=1的特征输入字典,格式和训练、测试阶段喂入模型的batch格式完全对齐。
- 将构造好的单用户特征字典传入
create_network()执行前向计算,得到的形状为[1, embedding_dim]的输出张量,就是该特定用户对应的Ψ(X)嵌入向量。 - 拿到用户嵌入后,直接和全量电影嵌入矩阵做转置矩阵乘法(即向量点积,对应相似度计算),返回点积得分最高的TopK个电影,就是该用户的个性化推荐结果,和代码中计算Precision@10指标时的预测逻辑完全一致。
注意:如果输入特征和训练阶段的预处理逻辑不一致,得到的用户嵌入会偏离训练分布,直接导致推荐效果异常。
完整参考代码
def build_softmax_model(rated_movies, embedding_cols, hidden_dims): """构建面向MovieLens数据集的Softmax推荐模型 参数说明: rated_movies: 训练样本对应的DataFrame embedding_cols: 特征名(字符串)到嵌入列对象的映射字典,会传入tf.feature_column.input_layer()构建输入层 hidden_dims: 各隐藏层的维度,整数列表格式 返回值: CFModel对象 """ def create_network(features): """将输入特征字典映射为用户嵌入 参数说明: features: 输入字符串张量组成的字典 返回值: outputs: 形状为[batch_size, embedding_dim]的张量 """ # 为每个稀疏特征构建词袋嵌入 inputs = tf.feature_column.input_layer(features, embedding_cols) # 堆叠隐藏层 input_dim = inputs.shape[1].value for i, output_dim in enumerate(hidden_dims): w = tf.get_variable( "hidden%d_w_" % i, shape=[input_dim, output_dim], initializer=tf.truncated_normal_initializer( stddev=1./np.sqrt(output_dim))) / 10. outputs = tf.matmul(inputs, w) input_dim = output_dim inputs = outputs return outputs train_rated_movies, test_rated_movies = split_dataframe(rated_movies) train_batch = make_batch(train_rated_movies, 200) test_batch = make_batch(test_rated_movies, 100) with tf.variable_scope("model", reuse=False): # 训练阶段 train_user_embeddings = create_network(train_batch) train_labels = select_random(train_batch["label"]) with tf.variable_scope("model", reuse=True): # 测试阶段 test_user_embeddings = create_network(test_batch) test_labels = select_random(test_batch["label"]) movie_embeddings = tf.get_variable( "input_layer/movie_id_embedding/embedding_weights") test_loss = softmax_loss( test_user_embeddings, movie_embeddings, test_labels) train_loss = softmax_loss( train_user_embeddings, movie_embeddings, train_labels) _, test_precision_at_10 = tf.metrics.precision_at_k( labels=test_labels, predictions=tf.matmul(test_user_embeddings, movie_embeddings, transpose_b=True), k=10) metrics = ( {"train_loss": train_loss, "test_loss": test_loss}, {"test_precision_at_10": test_precision_at_10} ) embeddings = {"movie_id": movie_embeddings} return CFModel(embeddings, train_loss, metrics)
说明:代码中的CFModel是借助SGD实现模型训练的辅助类。
内容的提问来源于stack exchange,提问作者heisenberg
相关产品推荐
相关产品推荐

