【Tensorflow 2.12 电影推荐系统之排序模型】

学习笔记

Tensorflow 2.12 智能电影推荐系统搭建学习笔记~

Tensorflow是谷歌开源的机器学习框架,可以帮助我们轻松地构建和部署机器学习模型。这里记录学习使用tensorflow-recommenders来构建一个电影推荐排序模型。
版本:python3.1.0、tensorflow2.12.0~

导入相关模块

# 导入os模块,主要提供系统相关的函数,如文件操作等,这里主要用于保存模型
import os
# pretty print,适合打印复杂的数据结构对象
import pprint
# 用于创建临时文件和目录
import tempfile
# 字典以及文本处理模块
from typing import Dict, Text
# 一个用于进行科学计算的Python库,它提供了高性能的多维数组对象(ndarray)以及用于处理这些数组的各种函数和工具
import numpy as np
# 导入TensorFlow
import tensorflow as tf
import tensorflow_recommenders as tfrs
# TensorFlow示例数据加载模块
import tensorflow_datasets as tfds

准备数据

加载数据

Movielens数据集是明尼苏达大学的GroupLens研究小组的经典数据集。它包含了一组用户对电影的评分,是推荐系统研究的重要数据集。

# 加载用户观看电影评分数据集(评分可以认为是显示反馈,通过评分可以知道用户对电影的喜爱程度,从而进行有效的推荐)
ratings = tfds.load("movielens/100k-ratings", split="train")

数据预处理

# 去掉没用到的特征,保留用户ID,观看的电影标题以及用户对该电影的评分
# 数据:{'bucketized_user_age': 45.0,'movie_genres': array([7], dtype=int64),'movie_id': b'357','movie_title': b"One Flew Over the Cuckoo's Nest (1975)",'raw_user_age': 46.0,'timestamp': 879024327,'user_gender': True,'user_id': b'138','user_occupation_label': 4,'user_occupation_text': b'doctor','user_rating': 4.0,'user_zip_code': b'53211'}
ratings = ratings.map(lambda x: {
    "movie_title": x["movie_title"],
    "user_id": x["user_id"],
    "user_rating": x["user_rating"]
})
# 设置随机数种子
tf.random.set_seed(42)
# 打乱数据
shuffled = ratings.shuffle(100_000, seed=42, reshuffle_each_iteration=False)
# 切分训练数据以及测试数据
train = shuffled.take(80_000)
test = shuffled.skip(80_000).take(20_000)

获取词汇表

获取用户Id以及电影标题的词汇表,后续以词汇表将原始特征值映射到连续范围内的整数,方便训练时在嵌入表中查找相应的嵌入向量。

# 获取数据集中的电影标题
movie_titles = ratings.batch(1_000_000).map(lambda x: x["movie_title"])
# 获取数据集中的用户ID
user_ids = ratings.batch(1_000_000).map(lambda x: x["user_id"])
# 排重处理,获取唯一电影标题词汇表
unique_movie_titles = np.unique(np.concatenate(list(movie_titles)))
# 排重处理,获取唯一用户ID词汇表
unique_user_ids = np.unique(np.concatenate(list(user_ids)))

构建模型

定义评分排序模型

tf.keras.Model 是 TensorFlow 的核心组件,用于构建和表示深度学习模型。在 TensorFlow 中,一个模型基本上是一个前向传播(forward pass)函数,它接受输入并输出预测。这里继承tf.keras.model类来构建自定义模型,在__init__ 方法中定义模型的结构,在call方法实现前向传播。

class RankingModel(tf.keras.Model):
  # 在__init__ 方法中定义模型的结构
  def __init__(self):
    super().__init__()
    # 定义嵌入维度
    embedding_dimension = 32
    # 计算用户特征embeddings的模型
    self.user_embeddings = tf.keras.Sequential([
      tf.keras.layers.StringLookup(vocabulary=unique_user_ids, mask_token=None),
      tf.keras.layers.Embedding(len(unique_user_ids) + 1, embedding_dimension)
    ])
    # 计算电影特征embeddings的模型
    self.movie_embeddings = tf.keras.Sequential([
      tf.keras.layers.StringLookup(vocabulary=unique_movie_titles, mask_token=None),
      tf.keras.layers.Embedding(len(unique_movie_titles) + 1, embedding_dimension)
    ])
    # 进行评分预测的模型
    self.ratings = tf.keras.Sequential([
      # 添加全连接层,输出为256维,激活函数使用relu
      tf.keras.layers.Dense(256, activation="relu"),
      # 添加全连接层,输出为64维,激活函数使用relu
      tf.keras.layers.Dense(64, activation="relu"),
      # 最后添加一个输出层,输出预测评分
      tf.keras.layers.Dense(1)
    ])
  # 在call方法中实现前向传播,输入参数,输出预测
  def call(self, inputs):
    # 获取输入数据:用户ID、电影标题
    user_id, movie_title = inputs
    # 计算用户特征embedding
    user_embedding = self.user_embeddings(user_id)
    # 计算电影特征embedding
    movie_embedding = self.movie_embeddings(movie_title)
    # 把用户embedding和电影embedding合成一个向量,作为评分模型的输入参数,最后返回评分模型预测的评分
    return self.ratings(tf.concat([user_embedding, movie_embedding], axis=1))
# 模拟预测用户ID42对电影的评分,这里还未经过训练,所以结果可能不准确
RankingModel()((["42"], ["One Flew Over the Cuckoo's Nest (1975)"]))

ReLU(Rectified Linear Unit,修正线性单元)是一种常用的激活函数,用于神经网络的非线性变换。
它定义为输入x大于零时的恒等函数,即f(x) = max(0, x)。
ReLU函数的特点:当输入大于零时,输出等于输入,即f(x) = x;当输入小于等于零时,输出为零,即f(x) = 0。
ReLU函数的优点:计算简单,只需比较输入和零的大小;加速神经网络的收敛速度;具有稀疏激活性,即只有部分神经元会激活,可以提高模型的泛化能力。
在深度学习中,ReLU函数通常用作隐藏层的激活函数,可以帮助神经网络学习非线性关系。

定义损失函数以及模型评估指标

定义排序模型的损失函数以及评估指标,损失函数使用MeanSquaredError(MSE,均方误差),评估指标使用RootMeanSquaredError(RMSE,均方根误差)。

均方误差(Mean Squared Error,MSE)是一种常用的衡量预测或估计误差大小的度量。
它表示的是每个实际值与预测值之间的平均平方差。计算公式为:
MSE = Σ[(actual_value - estimated_value)^2] / number_of_samples,其中,Σ表示求和,number_of_samples是样本的数量。
均方误差越小,说明预测或估计的准确性越高。
在实际应用中,很多机器学习算法的优化目标就是最小化均方误差。

均方根误差(Root Mean Squared Error,RMSE),又称为标准误差,是对一组测量中的特大或特小误差反映非常敏感的误差指标。
它定义为观测值与真值偏差的平方和观测次数n比值的平方根。在有限测量次数中,均方根误差可以用下式表示:√[∑di^2/n]=Re,式中n为测量次数,di为一组测量值与真值的偏差。

# 使用tfrs提供的wapper类,方便开发者进行排序模型相关的损失以及指标计算。
task = tfrs.tasks.Ranking(
  loss = tf.keras.losses.MeanSquaredError(),
  metrics=[tf.keras.metrics.RootMeanSquaredError()]
)

定义完整的评分排序模型

定义完整的评分排序模型,这里继承tensorflow-recommenders封装过的tfrs.models.Model类,简化了推荐模型的构建。

class MovielensModel(tfrs.models.Model):
  # 初始化方法
  def __init__(self):
    super().__init__()
    self.ranking_model: tf.keras.Model = RankingModel()
    self.task: tf.keras.layers.Layer = task
  # 预测方法,定义模型如何预测结果
  def call(self, features: Dict[str, tf.Tensor]) -> tf.Tensor:
    return self.ranking_model((features["user_id"], features["movie_title"]))
  # 计算损失以及指标
  def compute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor:
    # 获取实际评分
    labels = features.pop("user_rating")
    # 获取预测评分
    rating_predictions = self(features)
    # 计算损失和指标
    return self.task(labels=labels, predictions=rating_predictions)

训练和评估

创建排序模型实例

# 创建模型实例
model = MovielensModel()
# 指定优化器,使用自适应梯度下降优化算法,同时设置学习速率为0.1,然后编译模型
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))

缓存数据

# 缓存数据,加快训练时访问数据的效率
cached_train = train.shuffle(100_000).batch(8192).cache()
cached_test = test.batch(4096).cache()

训练

# 开始训练,一共训练3个迭代,每个迭代包含多个批次
model.fit(cached_train, epochs=3)

训练日志,可以看到损失一直在下降:

Epoch 1/3
10/10 [==============================] - 3s 33ms/step - root_mean_squared_error: 2.2411 - loss: 4.6050 - regularization_loss: 0.0000e+00 - total_loss: 4.6050
Epoch 2/3
10/10 [==============================] - 0s 26ms/step - root_mean_squared_error: 1.1204 - loss: 1.2575 - regularization_loss: 0.0000e+00 - total_loss: 1.2575
Epoch 3/3
10/10 [==============================] - 0s 25ms/step - root_mean_squared_error: 1.1123 - loss: 1.2395 - regularization_loss: 0.0000e+00 - total_loss: 1.2395

评估

# 使用测试数据集评估模型
model.evaluate(cached_test, return_dict=True)

评估日志:

5/5 [==============================] - 1s 11ms/step - root_mean_squared_error: 1.1064 - loss: 1.2188 - regularization_loss: 0.0000e+00 - total_loss: 1.2188

预测

# 预测用户ID42对三部电影的评分
test_ratings = {}
test_movie_titles = ["M*A*S*H (1970)", "Dances with Wolves (1990)", "Speed (1994)"]
for movie_title in test_movie_titles:
  test_ratings[movie_title] = model({
      "user_id": np.array(["42"]),
      "movie_title": np.array([movie_title])
  })
# 打印电影标题以及评分
print("Ratings:")
for title, score in sorted(test_ratings.items(), key=lambda x: x[1], reverse=True):
  print(f"{title}: {score}")

导出和加载模型

最后,同样可以把训练完的模型保存下来,方便后续直接加载进行预测,而不用重新进行训练。

# 保存模型
tf.saved_model.save(model, "export")
# 加载模型
loaded = tf.saved_model.load("export")
# 进行预测
loaded({"user_id": np.array(["42"]), "movie_title": ["Speed (1994)"]}).numpy()

结尾

学习构建一个简单的推荐排序模型到这里就结束了~
官网:https://tensorflow.google.cn/recommenders/examples/basic_ranking

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
TensorFlow 2.12是一个机器学习框架的版本。要安装TensorFlow 2.12,你可以按照以下步骤进行操作: 1. 直接安装TensorFlow:从2022年12月起,tensorflow-gpu已经合并到tensorflow包中了。你可以使用以下命令安装TensorFlow 2.12.0版本: ``` pip install tensorflow==2.12.0 -i https://pypi.tuna.tsinghua.edu.cn/simple ``` 2. 激活环境:如果你使用的是conda环境,可以使用以下命令激活tensorflow2_cpu环境: ``` conda activate tensorflow2_cpu ``` 3. 安装TensorFlow 2.12.0(CPU版本):如果你想安装CPU版本的TensorFlow 2.12.0,可以使用以下命令: ``` pip install tensorflow-cpu==2.12.0 -i https://pypi.tuna.tsinghua.edu.cn/simple/ ``` 4. 适配notebook:如果你想在Jupyter Notebook中使用TensorFlow 2.12.0,可以使用以下命令安装ipykernel并将其适配到tensorflow2_cpu环境: ``` pip install ipykernel python -m ipykernel install --name tensorflow2_cpu ``` 需要注意的是,截至到写这篇回答时(2023.4.4),国内的pip源可能还没有更新TensorFlow 2.12.0的包名,所以建议使用官方源或者等待一段时间再尝试安装。如果安装出错,可以多次尝试,可能是因为网络不好导致的。 #### 引用[.reference_title] - *1* [【已解决】【Tensorflow2.12.0版本以后合并CPU和GPU版】Tensorflow-gpu==2.12.0 安装失败解决办法](https://blog.csdn.net/void_zk/article/details/131379478)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [tensorflow1 tensorflow 2 安装配置(cpu+gpu)新版gpu2.12](https://blog.csdn.net/ziqibit/article/details/129959068)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值