推荐系统如何用TensorFlow实现经典的深度学习模型(Embedding+MLP)

本文介绍了经典的DeepCrossing模型,该模型结合了Embedding和MLP(多层感知机)用于广告推荐。模型结构包括特征层、Embedding层、堆叠层、多层神经网络层和评分层。在特征选择上,考虑了类别型和数值型特征,并使用TensorFlow实现。模型训练中,选用三层MLP结构,最终通过Sigmoid输出层进行二分类预测。
摘要由CSDN通过智能技术生成

Embedding+MLP模型的结构

  • MLP(Multilayer Perceptron)是多层感知机的缩写。感知机是神经元的另外一种叫法,所以多层感知机就是多层神经网络。

最经典的模型Deep Crossing

  • 微软在2016年提出的深度学习模型Deep Crossing,将其应用于广告推荐这个业务场景。它是一个经典的Embedding+MLP模型结构,我们可以看到,Deep Crossing从下到上可以分为5层:Feature层、Embedding层、Stacking层、MLP层和Scoring层。
    在这里插入图片描述
  • Feature层也叫特征输入层(最底层),作为整个模型的输入。Feature有两种情况第一种是连接Embedding层、第二种是直接连接Stacking层,主要区别在于:Feature #1代表的是类别型特征经过One-hot编码后生成的特征向量,而Feature #2代表的是数值型特征。One-hot特征由于稀疏性,不能直接输入到后续的神经网络中进行训练,所以需要通过连接到Embedding层的方式,将其转换成比较稠密的Embedding向量。
  • Embedding层是为了把稀疏的One-hot向量转换成稠密的Embedding向量而设置的,需要注意的是Embedding层并不是全部连接起来的,而是每一个特征对应一个Embedding层,不同Embedding层之间互不干涉。
  • Stacking层中文名堆叠层也叫连接(Concatenate)层,作用是把不同的Embedding特征和数值型特征拼接在一起,形成新的包含全部特征的特征向量。
  • MLP层就是我们开头提到的多层神经网络层,图中的Deep Crossing采用的是Multiple Residual Units层,也叫做多层残差网络。Deep Crossing针对特定的问题选择了残差神经元,其实还有很多种例如Relu、tanh、sigmoid。MLP层的特点是全连接,不同层的神经元两两之间都有连接。
  • Scoring层也叫输出层。深度学习最终要预测的目标就是一个分类的概率。如果是点击率预估就是一个二分类问题,那我们就可以采用逻辑回归作为输出层神经元,而如果是类似图像分类这样的多分类问题,我们往往在输出层采用softmax这样的多分类模型。
  • 总结:对于类别特征,先利用Embedding层进行特征稠密化,再利用Stacking层连接其他特征,输入MLP的多层结构,最后用Scoring层预估结果

Embedding+MLP模型的实战

特征选择和模型设计

  • 特征选择表格:
    在这里插入图片描述
  • 接下来就是MLP部分的模型设计了。选择一个三层的MLP结构,其中前两层是128维的FC层。采用好/差评标签作为样本标签,因此要解决的是一个类CTR预估的二分类问题,对于二分类问题,我们最后一层采用单个Sigmoid神经元作为输出层就可以了。

基于TensorFlow的模型实现

  • 第一步导入TensorFlow包,相关代码:
import tensorflow as tf

#文件url路径自己定义
TRAIN_URL = "file:///e:/SparrowRecSys/src/main/resources/webroot/sampledata/trainingSamples.csv"
TEST_URL = "file:///e:/SparrowRecSys/src/main/resources/webroot/sampledata/testSamples.csv"

training_samples_file_path = tf.keras.utils.get_file("trainingSamples.csv", TRAIN_URL)
test_samples_file_path = tf.keras.utils.get_file("testSamples.csv", TEST_URL)
  • 第二步是载入训练数据,相关代码:
# label_name指定了CSV数据集中的标签列;batch_size指定了训练过程中,一次输入几条训练数据进行梯度下降训练
def get_dataset(file_path):
    dataset = tf.data.experimental.make_csv_dataset(
        file_path,
        batch_size=12,
        label_name='label',
        na_value="0",
        num_epochs=1,
        ignore_errors=True)
    return dataset

train_dataset = get_dataset(training_samples_file_path)
test_dataset = get_dataset(test_samples_file_path)
  • 第三步是载入类别型特征,相关代码:
#定义风格词表
genre_vocab = ['Film-Noir', 'Action', 'Adventure', 'Horror', 'Romance', 'War', 'Comedy', 'Western', 'Documentary',
               'Sci-Fi', 'Drama', 'Thriller',
               'Crime', 'Fantasy', 'Animation', 'IMAX', 'Mystery', 'Children', 'Musical']


GENRE_FEATURES = {
    'userGenre1': genre_vocab,
    'userGenre2': genre_vocab,
    'userGenre3': genre_vocab,
    'userGenre4': genre_vocab,
    'userGenre5': genre_vocab,
    'movieGenre1': genre_vocab,
    'movieGenre2': genre_vocab,
    'movieGenre3': genre_vocab
}


categorical_columns = []
for feature, vocab in GENRE_FEATURES.items():
#字符串型的特征转换成One-hot特征
    cat_col = tf.feature_column.categorical_column_with_vocabulary_list(
        key=feature, vocabulary_list=vocab)
    emb_col = tf.feature_column.embedding_column(cat_col, 10)
    categorical_columns.append(emb_col)

#ID转换成One-hot特征
movie_col = tf.feature_column.categorical_column_with_identity(key='movieId', num_buckets=1001)
movie_emb_col = tf.feature_column.embedding_column(movie_col, 10)
categorical_columns.append(movie_emb_col)

#ID转换成One-hot特征
user_col = tf.feature_column.categorical_column_with_identity(key='userId', num_buckets=30001)
user_emb_col = tf.feature_column.embedding_column(user_col, 10)
categorical_columns.append(user_emb_c
  • 第四步是数值型特征的处理,相关代码:
#无需embedding的特征直接带入stacking层
numerical_columns = [tf.feature_column.numeric_column('releaseYear'),
                   tf.feature_column.numeric_column('movieRatingCount'),
                     tf.feature_column.numeric_column('movieAvgRating'),
                     tf.feature_column.numeric_column('movieRatingStddev'),
                     tf.feature_column.numeric_column('userRatingCount'),
                     tf.feature_column.numeric_column('userAvgRating'),
                     tf.feature_column.numeric_column('userRatingStddev')]

  • 第五步是定义模型结构,相关代码:
#直接利用DenseFeatures把类别型Embedding特征和数值型特征连接在一起形成稠密特征向量,然后依次经过两层128维的FC层,最后通过sigmoid输出神经元产生最终预估值。
model = tf.keras.Sequential([
    tf.keras.layers.DenseFeatures(numerical_columns + categorical_columns),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(128, activation='relu'),
    tf.keras.layers.Dense(1, activation='sigmoid'),
])

  • 第六步是定义模型训练相关的参数,相关代码:
#损失函数使用的是BCE-Loss;优化器使用的是Adam;指标选用了Accuracy精度
model.compile(
    loss='binary_crossentropy',
    optimizer='adam',
    metrics=['accuracy'])
  • 第七步是模型的训练和评估,相关代码:
#训练
model.fit(train_dataset, epochs=10)
#评估测试集
test_loss, test_accuracy = model.evaluate(test_dataset)

print('\n\nTest Loss {}, Test Accuracy {}'.format(test_loss, test_accuracy)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值