import numpy as np import tensorflow as tf import tensorflow_datasets as tfds import tensorflow_recommenders as tfrs from typing importDict, Text
# 评分数据 # Ratings data. ratings = tfds.load('movielens/100k-ratings', split="train") # Features of all the available movies. movies = tfds.load('movielens/100k-movies', split="train")
# Select the basic features. ratings = ratings.map(lambda x: {"movie_title": x["movie_title"],"user_id": x["user_id"]}) movies = movies.map(lambda x: x["movie_title"])
# 定义两个模型和检索任务。 # Define user and movie models. user_model = tf.keras.Sequential([ user_ids_vocabulary, tf.keras.layers.Embedding(user_ids_vocabulary.vocab_size(), 64) ]) movie_model = tf.keras.Sequential([ movie_titles_vocabulary, tf.keras.layers.Embedding(movie_titles_vocabulary.vocab_size(), 64) ])
# Define your objectives. task = tfrs.tasks.Retrieval(metrics=tfrs.metrics.FactorizedTopK( movies.batch(128).map(movie_model) ) )
# 创建模型、训练模型并生成预测: # Create a retrieval model. model = MovieLensModel(user_model, movie_model, task) model.compile(optimizer=tf.keras.optimizers.Adagrad(0.5))
# Train for 3 epochs. model.fit(ratings.batch(4096), epochs=3)
# Use brute-force search to set up retrieval using the trained representations. index = tfrs.layers.factorized_top_k.BruteForce(model.user_model) index.index_from_dataset(movies.batch(100).map(lambda title: (title, model.movie_model(title))))
# Get some recommendations. _, titles = index(np.array(["42"])) print(f"Top 3 recommendations for user 42: {titles[0, :3]}")
# 定义模型 classMovieLensModel(tfrs.Model): # We derive from a custom base class to help reduce boilerplate. Under the hood, # these are still plain Keras Models.
# Set up user and movie representations. self.user_model = user_model self.movie_model = movie_model # Set up a retrieval task. self.task = task
defcompute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor: # Define how the loss is computed. user_embeddings = self.user_model(features["user_id"]) movie_embeddings = self.movie_model(features["movie_title"])
import os import pprint import tempfile import numpy as np import tensorflow as tf import tensorflow_datasets as tfds import tensorflow_recommenders as tfrs from typing importDict, Text
# 请注意,由于MovieLens数据集没有预定义的分割,因此所有数据都在训练分割下。 # Ratings data. ratings = tfds.load("movielens/100k-ratings", split="train") # Features of all the available movies. movies = tfds.load("movielens/100k-movies", split="train")
# array([b"'Til There Was You (1997)", b'1-900 (1994)', # b'101 Dalmatians (1996)', b'12 Angry Men (1957)', b'187 (1997)', # b'2 Days in the Valley (1996)', # b'20,000 Leagues Under the Sea (1954)', # b'2001: A Space Odyssey (1968)', # b'3 Ninjas: High Noon At Mega Mountain (1998)', # b'39 Steps, The (1935)'], dtype=object)
defcompute_loss(self, features: Dict[Text, tf.Tensor], training=False) -> tf.Tensor: # We pick out the user features and pass them into the user model. user_embeddings = self.user_model(features["user_id"]) # And pick out the movie features and pass them into the movie model, # getting embeddings back. positive_movie_embeddings = self.movie_model(features["movie_title"])
# The task computes the loss and the metrics. return self.task(user_embeddings, positive_movie_embeddings)
# 模型预测:我们可以使用tfrs.layers.factorized_top_k.BruteForce层来做到这一点。 # Create a model that takes in raw query features, and index = tfrs.layers.factorized_top_k.BruteForce(model.user_model) # recommends movies out of the entire movies dataset. index.index_from_dataset( tf.data.Dataset.zip((movies.batch(100), movies.batch(100).map(model.movie_model))) )
# Get recommendations. _, titles = index(tf.constant(["42"])) print(f"Recommendations for user 42: {titles[0, :3]}")
# Recommendations for user 42: [b'Christmas Carol, A (1938)' b'Rudy (1993)' b'Bridges of Madison County, The (1995)']
# Export the query model. with tempfile.TemporaryDirectory() as tmp: path = os.path.join(tmp, "model") # Save the index. tf.saved_model.save(index, path) # Load it back; can also be done in TensorFlow Serving. loaded = tf.saved_model.load(path) # Pass a user id in, get top predicted movie titles back. scores, titles = loaded(["42"])
print(f"Recommendations: {titles[0][:3]}")
# Recommendations: [b'Christmas Carol, A (1938)' b'Rudy (1993)' b'Bridges of Madison County, The (1995)']