추천 영화: 검색

TensorFlow.org에서 보기 Google Colab에서 실행 GitHub에서 소스 보기 노트북 다운로드

실제 추천 시스템은 종종 두 단계로 구성됩니다.

  1. 검색 단계에서는 가능한 모든 후보 중에서 수백 개의 초기 후보 세트를 선택합니다. 이 모델의 주요 목적은 사용자가 관심이 없는 모든 후보를 효율적으로 제거하는 것입니다. 검색 모델은 수백만 개의 후보를 처리할 수 있으므로 계산 효율성이 높아야 합니다.
  2. 순위 단계에서는 검색 모델의 출력을 가져와 미세 조정하여 가능한 한 최고의 권장 사항을 선택합니다. 그 작업은 사용자가 관심을 가질 만한 항목 집합을 가능한 후보의 최종 목록으로 좁히는 것입니다.

이 자습서에서는 첫 번째 단계인 검색에 중점을 둘 것입니다. 당신이 순위 단계에 관심이 있다면, 우리 한 번 봐 가지고 순위 튜토리얼.

검색 모델은 종종 두 개의 하위 모델로 구성됩니다.

  1. 쿼리 기능을 사용하여 쿼리 표현(일반적으로 고정 차원 임베딩 벡터)을 계산하는 쿼리 모델입니다.
  2. 후보 특징을 사용하여 후보 표현(동일한 크기의 벡터)을 계산하는 후보 모델

그런 다음 두 모델의 출력을 함께 곱하여 쿼리 후보 선호도 점수를 제공하며 점수가 높을수록 후보와 쿼리 간의 더 나은 일치를 나타냅니다.

이 자습서에서는 Movielens 데이터 세트를 사용하여 이러한 2개 타워 모델을 구축하고 훈련할 것입니다.

우리는 할 것입니다:

  1. 데이터를 가져와 훈련 및 테스트 세트로 나눕니다.
  2. 검색 모델을 구현합니다.
  3. 피팅하고 평가합니다.
  4. 대략적인 ANN(최근접 이웃) 인덱스를 구축하여 효율적인 검색을 위해 내보냅니다.

데이터세트

로부터 고전적인 데이터 세트입니다 데이터 세트 Movielens GroupLens는 미네소타 대학에서 그룹을 연구. 여기에는 일련의 사용자가 영화에 부여한 일련의 등급이 포함되어 있으며 추천 시스템 연구의 핵심 요소입니다.

데이터는 두 가지 방법으로 처리할 수 있습니다.

  1. 사용자가 어떤 영화를 보고(평가했는지), 어떤 영화를 보지 않았는지를 나타내는 것으로 해석할 수 있습니다. 이것은 사용자의 시계가 보고 싶은 것과 보고 싶지 않은 것을 알려주는 일종의 암시적 피드백입니다.
  2. 사용자가 본 영화를 얼마나 좋아했는지를 나타내는 것으로도 볼 수 있습니다. 이것은 명시적 피드백의 한 형태입니다. 사용자가 영화를 봤다는 점을 감안할 때 우리는 그들이 준 평점을 보고 그들이 얼마나 좋아했는지 대략적으로 알 수 있습니다.

이 튜토리얼에서는 검색 시스템, 즉 사용자가 시청할 가능성이 높은 카탈로그의 영화 세트를 예측하는 모델에 초점을 맞추고 있습니다. 종종 암시적 데이터가 여기에서 더 유용하므로 Movielens를 암시적 시스템으로 취급할 것입니다. 즉, 사용자가 본 모든 영화는 긍정적인 예이고 사용자가 보지 않은 모든 영화는 암시적인 부정적인 예입니다.

수입품

먼저 수입품을 제거합시다.

pip install -q tensorflow-recommenders
pip install -q --upgrade tensorflow-datasets
pip install -q scann
import os
import pprint
import tempfile

from typing import Dict, Text

import numpy as np
import tensorflow as tf
import tensorflow_datasets as tfds
import tensorflow_recommenders as tfrs

데이터세트 준비

먼저 데이터를 살펴보자.

우리의 MovieLens 데이터 세트를 사용 Tensorflow 데이터 집합을 . 로드 movielens/100k_ratings 산출 tf.data.Dataset 등급 데이터 로딩 포함하는 객체 movielens/100k_movies 낳는 tf.data.Dataset 유일한 영화 데이터를 포함하는 객체.

참고 분할을 미리 정의하지 않는 데이터 세트 MovieLens 때문에, 모든 데이터는 아래에 있음 train 분할.

# Ratings data.
ratings = tfds.load("movielens/100k-ratings", split="train")
# Features of all the available movies.
movies = tfds.load("movielens/100k-movies", split="train")
2021-10-02 11:05:34.633747: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected

등급 데이터 세트는 영화 ID, 사용자 ID, 할당된 등급, 타임스탬프, 영화 정보 및 사용자 정보의 사전을 반환합니다.

for x in ratings.take(1).as_numpy_iterator():
  pprint.pprint(x)
{'bucketized_user_age': 45.0,
 'movie_genres': array([7]),
 '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'}
2021-10-02 11:05:35.718641: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

영화 데이터 세트에는 영화 ID, 영화 제목 및 그것이 속한 장르에 대한 데이터가 포함됩니다. 장르는 정수 레이블로 인코딩됩니다.

for x in movies.take(1).as_numpy_iterator():
  pprint.pprint(x)
{'movie_genres': array([4]),
 'movie_id': b'1681',
 'movie_title': b'You So Crazy (1994)'}
2021-10-02 11:05:35.893098: W tensorflow/core/kernels/data/cache_dataset_ops.cc:768] The calling iterator did not fully read the dataset being cached. In order to avoid unexpected truncation of the dataset, the partially cached contents of the dataset  will be discarded. This can happen if you have an input pipeline similar to `dataset.cache().take(k).repeat()`. You should use `dataset.take(k).cache().repeat()` instead.

이 예에서는 등급 데이터에 중점을 둘 것입니다. 다른 자습서에서는 영화 정보 데이터를 사용하여 모델 품질을 개선하는 방법도 살펴봅니다.

우리는 단지 계속 user_idmovie_title 데이터 집합 필드를.

ratings = ratings.map(lambda x: {
    "movie_title": x["movie_title"],
    "user_id": x["user_id"],
})
movies = movies.map(lambda x: x["movie_title"])

모델을 적합하고 평가하려면 훈련 및 평가 세트로 분할해야 합니다. 산업 추천 시스템에서, 이것은 가능성이 가장 높은 시간에 수행 할 것입니다 : 시간에 데이터를 백업 \(T\) 후 상호 작용을 예측하기 위해 사용되는 \(T\).

그러나 이 간단한 예에서는 임의 분할을 사용하여 평가의 80%를 기차 세트에, 20%를 테스트 세트에 넣습니다.

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 = movies.batch(1_000)
user_ids = ratings.batch(1_000_000).map(lambda x: x["user_id"])

unique_movie_titles = np.unique(np.concatenate(list(movie_titles)))
unique_user_ids = np.unique(np.concatenate(list(user_ids)))

unique_movie_titles[:10]
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)

모델 구현

모델의 아키텍처를 선택하는 것은 모델링의 핵심 부분입니다.

2개의 타워 검색 모델을 구축하기 때문에 각 타워를 개별적으로 구축한 다음 최종 모델에서 결합할 수 있습니다.

쿼리 타워

쿼리 타워부터 시작하겠습니다.

첫 번째 단계는 쿼리 및 후보 표현의 차원을 결정하는 것입니다.

embedding_dimension = 32

값이 높을수록 더 정확할 수 있는 모델에 해당하지만 맞추기가 더 느리고 과적합되기 쉽습니다.

두 번째는 모델 자체를 정의하는 것입니다. 여기, 우리는 정수로 먼저 변환 사용자 ID에 Keras 전처리 층을 사용하고, 다음을 통해 사용자 묻어에 사람들을 변환하는거야 Embedding 층. 이전에 계산한 고유한 사용자 ID 목록을 어휘로 사용합니다.

user_model = tf.keras.Sequential([
  tf.keras.layers.StringLookup(
      vocabulary=unique_user_ids, mask_token=None),
  # We add an additional embedding to account for unknown tokens.
  tf.keras.layers.Embedding(len(unique_user_ids) + 1, embedding_dimension)
])

이런 간단한 모델은 고전에 정확하게 대응하는 행렬 인수 분해 방법. 의 서브 클래스 정의 동안 tf.keras.Model 이 간단한 모델 것은 과잉 수 있습니다, 우리는 쉽게 우리가 반환 한 바와 같이, 표준 Keras 구성 요소를 사용하여 임의의 복잡한 모델을 확장 할 수 있습니다 embedding_dimension 끝에서 - 넓은 출력.

후보 타워

우리는 후보 타워와 동일한 작업을 수행할 수 있습니다.

movie_model = 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)
])

측정항목

훈련 데이터에는 긍정적인 (사용자, 영화) 쌍이 있습니다. 우리 모델이 얼마나 좋은지 알아내려면 모델이 이 쌍에 대해 계산한 선호도 점수를 다른 모든 가능한 후보의 점수와 비교해야 합니다. 양성 쌍의 점수가 다른 모든 후보보다 높으면 모델 매우 정확합니다.

이를 위해, 우리는 사용할 수 tfrs.metrics.FactorizedTopK 메트릭을. 메트릭에는 평가를 위해 암시적 부정으로 사용되는 후보 데이터 세트라는 하나의 필수 인수가 있습니다.

의 우리의 경우에서 movies 세트, 우리 영화 모델을 통해 묻어로 변환 :

metrics = tfrs.metrics.FactorizedTopK(
  candidates=movies.batch(128).map(movie_model)
)

손실

다음 구성 요소는 모델을 훈련하는 데 사용되는 손실입니다. TFRS에는 이를 쉽게 하기 위한 여러 손실 계층과 작업이 있습니다.

이 경우, 우리는 사용 할 수 있습니다 Retrieval 함께 그 번들 손실 기능과 메트릭 계산 래퍼 편의 : 작업 개체를 :

task = tfrs.tasks.Retrieval(
  metrics=metrics
)

작업 자체는 쿼리 및 후보 임베딩을 인수로 사용하고 계산된 손실을 반환하는 Keras 계층입니다. 이를 사용하여 모델의 훈련 루프를 구현합니다.

전체 모델

이제 모든 것을 하나의 모델로 통합할 수 있습니다. TFRS는 기본 모델 클래스 (공개 tfrs.models.Model 구축 모델을 간소화) : 우리가 할 필요는 구성 요소를 설정하는 것입니다 __init__ 방법 및 구현 compute_loss 원시 기능에 복용하고 손실 값을 반환 방법 .

그러면 기본 모델이 우리 모델에 맞는 적절한 훈련 루프를 생성합니다.

class MovielensModel(tfrs.Model):

  def __init__(self, user_model, movie_model):
    super().__init__()
    self.movie_model: tf.keras.Model = movie_model
    self.user_model: tf.keras.Model = user_model
    self.task: tf.keras.layers.Layer = task

  def compute_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.Model 기본 클래스는 단순히 편리한 클래스이다 : 그것은 우리가 같은 방법을 사용하여 두 교육 및 시험 손실을 계산할 수 있습니다.

후드 아래에는 여전히 평범한 Keras 모델입니다. 당신은에서 상속하여 동일한 기능을 달성 할 수 tf.keras.Model 과 오버라이드 (override) train_steptest_step 기능 (참조 가이드 자세한 내용을) :

class NoBaseClassMovielensModel(tf.keras.Model):

  def __init__(self, user_model, movie_model):
    super().__init__()
    self.movie_model: tf.keras.Model = movie_model
    self.user_model: tf.keras.Model = user_model
    self.task: tf.keras.layers.Layer = task

  def train_step(self, features: Dict[Text, tf.Tensor]) -> tf.Tensor:

    # Set up a gradient tape to record gradients.
    with tf.GradientTape() as tape:

      # Loss computation.
      user_embeddings = self.user_model(features["user_id"])
      positive_movie_embeddings = self.movie_model(features["movie_title"])
      loss = self.task(user_embeddings, positive_movie_embeddings)

      # Handle regularization losses as well.
      regularization_loss = sum(self.losses)

      total_loss = loss + regularization_loss

    gradients = tape.gradient(total_loss, self.trainable_variables)
    self.optimizer.apply_gradients(zip(gradients, self.trainable_variables))

    metrics = {metric.name: metric.result() for metric in self.metrics}
    metrics["loss"] = loss
    metrics["regularization_loss"] = regularization_loss
    metrics["total_loss"] = total_loss

    return metrics

  def test_step(self, features: Dict[Text, tf.Tensor]) -> tf.Tensor:

    # Loss computation.
    user_embeddings = self.user_model(features["user_id"])
    positive_movie_embeddings = self.movie_model(features["movie_title"])
    loss = self.task(user_embeddings, positive_movie_embeddings)

    # Handle regularization losses as well.
    regularization_loss = sum(self.losses)

    total_loss = loss + regularization_loss

    metrics = {metric.name: metric.result() for metric in self.metrics}
    metrics["loss"] = loss
    metrics["regularization_loss"] = regularization_loss
    metrics["total_loss"] = total_loss

    return metrics

이 자습서 그러나, 우리는 사용에 충실 tfrs.Model 거리 보일러의 일부를 모델링하고 추상적에 우리의 초점을 유지하기 위해 기본 클래스를.

피팅 및 평가

모델을 정의한 후 표준 Keras 피팅 및 평가 루틴을 사용하여 모델을 피팅하고 평가할 수 있습니다.

먼저 모델을 인스턴스화하겠습니다.

model = MovielensModel(user_model, movie_model)
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()

그런 다음 모델을 학습시킵니다.

model.fit(cached_train, epochs=3)
Epoch 1/3
10/10 [==============================] - 6s 302ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0011 - factorized_top_k/top_5_categorical_accuracy: 0.0094 - factorized_top_k/top_10_categorical_accuracy: 0.0203 - factorized_top_k/top_50_categorical_accuracy: 0.1001 - factorized_top_k/top_100_categorical_accuracy: 0.1772 - loss: 69885.1129 - regularization_loss: 0.0000e+00 - total_loss: 69885.1129
Epoch 2/3
10/10 [==============================] - 3s 286ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0029 - factorized_top_k/top_5_categorical_accuracy: 0.0186 - factorized_top_k/top_10_categorical_accuracy: 0.0376 - factorized_top_k/top_50_categorical_accuracy: 0.1689 - factorized_top_k/top_100_categorical_accuracy: 0.2923 - loss: 67523.3707 - regularization_loss: 0.0000e+00 - total_loss: 67523.3707
Epoch 3/3
10/10 [==============================] - 3s 269ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0036 - factorized_top_k/top_5_categorical_accuracy: 0.0224 - factorized_top_k/top_10_categorical_accuracy: 0.0459 - factorized_top_k/top_50_categorical_accuracy: 0.1880 - factorized_top_k/top_100_categorical_accuracy: 0.3162 - loss: 66302.9609 - regularization_loss: 0.0000e+00 - total_loss: 66302.9609
<keras.callbacks.History at 0x7f560e5ea090>

당신이 TensorBoard와 교육 과정을 모니터링 할 경우 적합 () 함수에 TensorBoard 콜백을 추가 한 다음 사용 TensorBoard을 시작할 수 있습니다 %tensorboard --logdir logs/fit . 를 참조하십시오 TensorBoard 문서 자세한 내용은.

모델이 학습됨에 따라 손실이 감소하고 top-k 검색 메트릭 세트가 업데이트됩니다. 이는 전체 후보 집합에서 검색된 상위 k 항목에 참 긍정이 있는지 여부를 알려줍니다. 예를 들어 상위 5개 범주 정확도 메트릭이 0.2이면 평균적으로 참 긍정이 검색된 상위 5개 항목의 20%에 해당한다는 것을 알 수 있습니다.

이 예에서는 평가뿐만 아니라 훈련 중에 메트릭을 평가합니다. 대규모 후보 집합에서는 이 작업이 매우 느릴 수 있으므로 훈련에서는 메트릭 계산을 끄고 평가에서만 실행하는 것이 현명할 수 있습니다.

마지막으로 테스트 세트에서 모델을 평가할 수 있습니다.

model.evaluate(cached_test, return_dict=True)
5/5 [==============================] - 2s 149ms/step - factorized_top_k/top_1_categorical_accuracy: 7.5000e-04 - factorized_top_k/top_5_categorical_accuracy: 0.0099 - factorized_top_k/top_10_categorical_accuracy: 0.0226 - factorized_top_k/top_50_categorical_accuracy: 0.1245 - factorized_top_k/top_100_categorical_accuracy: 0.2324 - loss: 31079.0635 - regularization_loss: 0.0000e+00 - total_loss: 31079.0635
{'factorized_top_k/top_1_categorical_accuracy': 0.000750000006519258,
 'factorized_top_k/top_5_categorical_accuracy': 0.009850000031292439,
 'factorized_top_k/top_10_categorical_accuracy': 0.02264999970793724,
 'factorized_top_k/top_50_categorical_accuracy': 0.12449999898672104,
 'factorized_top_k/top_100_categorical_accuracy': 0.23235000669956207,
 'loss': 28244.771484375,
 'regularization_loss': 0,
 'total_loss': 28244.771484375}

테스트 세트 성능은 훈련 성능보다 훨씬 나쁩니다. 이는 다음 두 가지 요인 때문입니다.

  1. 우리 모델은 단순히 기억할 수 있기 때문에 본 데이터에 대해 더 나은 성능을 보일 가능성이 높습니다. 이 과적합 현상은 모델에 많은 매개변수가 있을 때 특히 강력합니다. 모델 정규화와 모델이 보이지 않는 데이터에 더 잘 일반화되도록 도와주는 사용자 및 영화 기능의 사용에 의해 중재될 수 있습니다.
  2. 이 모델은 사용자가 이미 본 영화 중 일부를 다시 추천하고 있습니다. 이 알려진 긍정적인 시계는 상위 K 추천에서 테스트 영화를 밀어낼 수 있습니다.

두 번째 현상은 테스트 권장 사항에서 이전에 본 영화를 제외하여 해결할 수 있습니다. 이 접근 방식은 추천 시스템 문헌에서는 비교적 일반적이지만 이 자습서에서는 따르지 않습니다. 과거 시계를 추천하지 않는 것이 중요하다면 적절하게 지정된 모델이 과거 사용자 기록 및 컨텍스트 정보에서 이 동작을 자동으로 학습할 것으로 예상해야 합니다. 또한 동일한 품목을 여러 번 추천하는 것이 적절한 경우가 많습니다(예: 늘푸른 TV 시리즈 또는 정기적으로 구매하는 품목).

예측하기

이제 모델이 있으므로 예측을 할 수 있기를 원합니다. 우리는 사용할 수 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'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

물론, BruteForce 계층은 여러 가지 후보와 모델을 제공 할 너무 느린 될 것입니다. 다음 섹션에서는 대략적인 검색 인덱스를 사용하여 속도를 높이는 방법을 보여줍니다.

모델 서빙

모델이 학습된 후에는 배포 방법이 필요합니다.

2개 타워 검색 모델에서 검색에는 두 가지 구성 요소가 있습니다.

  • 쿼리의 기능을 가져와 쿼리 임베딩으로 변환하는 서비스 쿼리 모델,
  • 서빙 후보 모델. 이것은 가장 자주 쿼리 모델에 의해 생성된 쿼리에 대한 응답으로 후보를 빠르게 대략적으로 조회할 수 있는 근사최근접이웃(ANN) 인덱스의 형태를 취합니다.

TFRS에서는 두 구성 요소를 모두 내보낼 수 있는 단일 모델로 패키징할 수 있으므로 원시 사용자 ID를 사용하고 해당 사용자의 인기 영화 제목을 반환하는 모델을 제공합니다. 이것은에 모델을 수출을 통해 이루어집니다 SavedModel 이 가능하여 제공 할 수 있습니다 형식, TensorFlow 서빙 .

이 같은 모델을 배포하려면, 우리는 단순히 수출 BruteForce 우리가 위에서 만든 레이어 :

# 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]}")
2021-10-02 11:05:54.109254: W tensorflow/python/util/util.cc:348] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
WARNING:absl:Found untraced functions such as query_with_exclusions while saving (showing 1 of 1). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: /tmp/tmp7otg6id7/model/assets
INFO:tensorflow:Assets written to: /tmp/tmp7otg6id7/model/assets
Recommendations: [b'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

예측 속도를 높이기 위해 대략적인 검색 인덱스를 내보낼 수도 있습니다. 이를 통해 수천만 명의 후보자로부터 권장 사항을 효율적으로 표시할 수 있습니다.

이를 위해, 우리는 사용할 수 scann 패키지를. 이 TFRS의 선택적 의존성이며, 우리는 호출하여이 튜토리얼의 시작 부분에 별도로 설치 !pip install -q scann .

일단 설치되면 우리는 TFRS 사용할 수 있습니다 ScaNN 레이어를 :

scann_index = tfrs.layers.factorized_top_k.ScaNN(model.user_model)
scann_index.index_from_dataset(
  tf.data.Dataset.zip((movies.batch(100), movies.batch(100).map(model.movie_model)))
)
<tensorflow_recommenders.layers.factorized_top_k.ScaNN at 0x7f560caffc10>

이 층은 대략 조회를 수행합니다 :이 차종은 수십 배 더 빠르게 많은 후보 세트에 약간 덜 정확한 검색,하지만.

# Get recommendations.
_, titles = scann_index(tf.constant(["42"]))
print(f"Recommendations for user 42: {titles[0, :3]}")
Recommendations for user 42: [b'Sleepless in Seattle (1993)' b'Father of the Bride Part II (1995)'
 b'Hunchback of Notre Dame, The (1996)']

봉사를 내보내기 수출로 쉽게 BruteForce 레이어를 :

# Export the query model.
with tempfile.TemporaryDirectory() as tmp:
  path = os.path.join(tmp, "model")

  # Save the index.
  tf.saved_model.save(
      index,
      path,
      options=tf.saved_model.SaveOptions(namespace_whitelist=["Scann"])
  )

  # 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]}")
WARNING:absl:Found untraced functions such as query_with_exclusions while saving (showing 1 of 1). These functions will not be directly callable after loading.
INFO:tensorflow:Assets written to: /tmp/tmp_rde8grm/model/assets
INFO:tensorflow:Assets written to: /tmp/tmp_rde8grm/model/assets
Recommendations: [b'Bridges of Madison County, The (1995)'
 b'Father of the Bride Part II (1995)' b'Rudy (1993)']

빠른 대략적인 검색 모델을 사용하고 튜닝에 대한 자세한 내용은, 우리 한 번 봐 가지고 효율적인 서빙 튜토리얼.

아이템별 추천

이 모델에서 우리는 사용자 영화 모델을 만들었습니다. 그러나 일부 응용 프로그램(예: 제품 세부 정보 페이지)의 경우 항목 간(예: 영화 간 또는 제품 간) 권장 사항을 수행하는 것이 일반적입니다.

이와 같은 훈련 모델은 이 자습서에 표시된 것과 동일한 패턴을 따르지만 다른 훈련 데이터를 사용합니다. 여기에서는 사용자와 영화탑이 있었고 (사용자, 영화) 쌍을 사용하여 교육했습니다. 항목 대 항목 모델에서는 두 개의 항목 타워(쿼리 및 후보 항목용)가 있고 (쿼리 항목, 후보 항목) 쌍을 사용하여 모델을 훈련합니다. 제품 세부 정보 페이지를 클릭하여 구성할 수 있습니다.

다음 단계

이것으로 검색 튜토리얼을 마칩니다.

여기에 제시된 내용을 확장하려면 다음을 살펴보십시오.

  1. 멀티태스킹 모델 학습: 평점 및 클릭을 공동으로 최적화합니다.
  2. 영화 메타데이터 사용: 콜드 스타트를 완화하기 위해 더 복잡한 영화 모델 구축.