Film önermek: geri alma

TensorFlow.org'da görüntüleyin Google Colab'da çalıştırın Kaynağı GitHub'da görüntüleyin Not defterini indir

Gerçek dünya tavsiye sistemleri genellikle iki aşamadan oluşur:

  1. Geri alma aşaması, olası tüm adaylar arasından yüzlerce adaydan oluşan bir başlangıç ​​kümesinin seçilmesinden sorumludur. Bu modelin temel amacı, kullanıcının ilgilenmediği tüm adayları verimli bir şekilde ayıklamaktır. Alma modeli milyonlarca adayla ilgilenebileceğinden, hesaplama açısından verimli olmalıdır.
  2. Sıralama aşaması, erişim modelinin çıktılarını alır ve mümkün olan en iyi avuç tavsiyeyi seçmek için bunları ince ayarlar. Görevi, kullanıcının ilgilenebileceği öğe kümesini olası adayların kısa bir listesine daraltmaktır.

Bu derste, ilk aşamaya, geri almaya odaklanacağız. Eğer sıralama aşamada ilgilenen varsa, bizim de bakabilirsiniz sıralama öğretici.

Alma modelleri genellikle iki alt modelden oluşur:

  1. Sorgu özelliklerini kullanarak sorgu temsilini (normalde sabit boyutlu bir gömme vektörü) hesaplayan bir sorgu modeli.
  2. Aday özellikleri kullanarak aday temsilini (eşit boyutlu bir vektör) hesaplayan bir aday model

İki modelin çıktıları daha sonra bir sorgu-aday yakınlık puanı vermek için birlikte çarpılır, daha yüksek puanlar aday ve sorgu arasında daha iyi bir eşleşmeyi ifade eder.

Bu öğreticide, Movielens veri kümesini kullanarak böyle iki kuleli bir model oluşturup eğiteceğiz.

Biz gidiyoruz:

  1. Verilerimizi alın ve bir eğitim ve test setine bölün.
  2. Bir geri alma modeli uygulayın.
  3. Sığdırın ve değerlendirin.
  4. Yaklaşık bir en yakın komşular (ANN) dizini oluşturarak verimli hizmet için dışa aktarın.

veri kümesi

Klasik bir veri kümesi olan veri kümesi Movielens GroupLens Minnesota Üniversitesinde grup araştırma. Bir dizi kullanıcı tarafından filmlere verilen bir dizi derecelendirmeyi içerir ve bir öneri sistemi araştırmasıdır.

Veriler iki şekilde ele alınabilir:

  1. Kullanıcıların hangi filmleri izlediğini (ve puan verdiğini) ve hangilerini izlemediğini ifade ettiği şeklinde yorumlanabilir. Bu, kullanıcıların saatlerinin bize hangi şeyleri görmeyi tercih ettiklerini ve hangilerini görmemeyi tercih ettiklerini söylediği örtük bir geri bildirim biçimidir.
  2. Kullanıcıların izledikleri filmleri ne kadar beğendiklerinin ifadesi olarak da görülebilir. Bu, açık bir geri bildirim biçimidir: Bir kullanıcının bir film izlediğini düşünürsek, verdikleri puana bakarak kabaca ne kadar beğendiklerini söyleyebiliriz.

Bu öğreticide, bir geri alma sistemine odaklanıyoruz: Katalogdan kullanıcının izlemesi muhtemel olan bir dizi filmi tahmin eden bir model. Genellikle örtük veriler burada daha faydalıdır ve bu nedenle Movielens'i örtük bir sistem olarak ele alacağız. Bu, kullanıcının izlediği her filmin olumlu bir örnek olduğu ve izlemediği her filmin örtük olumsuz bir örnek olduğu anlamına gelir.

ithalat

Önce ithalatımızı aradan çıkaralım.

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

Veri kümesinin hazırlanması

Önce verilere bir bakalım.

Biz dan MovieLens veri kümesi kullanmak Tensorflow Veri kümeleri . Yükleme movielens/100k_ratings bir verir tf.data.Dataset derecelendirme verilerini ve yükleme içeren nesneyi movielens/100k_movies verimi bir tf.data.Dataset ancak filmler verileri içeren nesne.

Not splitleri önceden tanımlanmış sahip değil veri kümesi MovieLens beri, tüm veriler altında olduğunu train bölünmüş.

# 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

Derecelendirme veri kümesi, film kimliği, kullanıcı kimliği, atanan derecelendirme, zaman damgası, film bilgileri ve kullanıcı bilgilerini içeren bir sözlük döndürür:

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.

Filmler veri kümesi, film kimliğini, film adını ve ait olduğu türlere ilişkin verileri içerir. Türlerin tamsayı etiketleriyle kodlandığını unutmayın.

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.

Bu örnekte, derecelendirme verilerine odaklanacağız. Diğer öğreticiler, model kalitesini iyileştirmek için film bilgisi verilerinin nasıl kullanılacağını da keşfeder.

Biz sadece tutmak user_id ve movie_title veri kümesi alanları.

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

Modeli sığdırmak ve değerlendirmek için onu bir eğitim ve değerlendirme kümesine ayırmamız gerekir. Endüstriyel bir recommender sistemde, bu büyük olasılıkla zaman bitmiş olacaktır: Zaman veri yukarı \(T\) sonra etkileşimlerini tahmin için kullanılacak \(T\).

Ancak bu basit örnekte, derecelendirmelerin %80'ini tren setine ve %20'sini test setine koyarak rastgele bir bölme kullanalım.

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)

Verilerde bulunan benzersiz kullanıcı kimliklerini ve film adlarını da bulalım.

Bu önemlidir çünkü kategorik özelliklerimizin ham değerlerini modellerimizde vektörleri gömmek için eşleştirebilmemiz gerekir. Bunu yapmak için, ham özellik değerini bitişik bir aralıktaki bir tamsayıya eşleyen bir kelime dağarcığına ihtiyacımız var: bu, gömme tablolarımızda karşılık gelen gömmelere bakmamızı sağlar.

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)

Bir modelin uygulanması

Modelimizin mimarisini seçmek modellemenin önemli bir parçasıdır.

İki kuleli bir alma modeli oluşturduğumuz için, her bir kuleyi ayrı ayrı inşa edebilir ve ardından nihai modelde birleştirebiliriz.

sorgu kulesi

Sorgu kulesiyle başlayalım.

İlk adım, sorgunun boyutluluğuna ve aday temsillerine karar vermektir:

embedding_dimension = 32

Daha yüksek değerler, daha doğru olabilecek modellere karşılık gelir, ancak aynı zamanda sığdırmak için daha yavaş ve fazla takmaya daha yatkın olacaktır.

İkincisi, modelin kendisini tanımlamaktır. Burada, tamsayılar ilk dönüştürme kullanıcı kimlikleri için Keras ön işleme katmanları kullanın ve daha sonra bir ile kullanıcı embeddings için bu dönüştürmek için gidiyoruz Embedding tabakasının. Kelime hazinesi olarak daha önce hesapladığımız benzersiz kullanıcı kimlikleri listesini kullandığımızı unutmayın:

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

Böyle basit bir model klasik tam olarak karşılık matris ayrıştırma yaklaşım. Bir alt sınıfı tanımlayan iken tf.keras.Model bu basit model için overkill olabilir, biz kolayca bir dönüş sürece, standart Keras bileşenlerini kullanarak karmaşık olan rasgele modele uzatabilirsiniz embedding_dimension sonunda Enine çıktı.

aday kule

Aynı şeyi aday kule ile de yapabiliriz.

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

Metrikler

Eğitim verimizde pozitif (kullanıcı, film) çiftleri var. Modelimizin ne kadar iyi olduğunu anlamak için, modelin bu çift için hesapladığı yakınlık puanını diğer tüm olası adayların puanlarıyla karşılaştırmamız gerekir: pozitif çiftin puanı diğer tüm adaylardan daha yüksekse, modelimiz son derece doğrudur.

Bunu yapmak için, biz kullanabilirsiniz tfrs.metrics.FactorizedTopK metrik. Metrik için gerekli bir argüman var: değerlendirme için örtük negatifler olarak kullanılan adayların veri seti.

Var bizim durumda, movies veri kümesi, filmimizin modeli aracılığıyla tespitlerinin dönüştürülür:

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

Kayıp

Bir sonraki bileşen, modelimizi eğitmek için kullanılan kayıptır. TFRS'nin bunu kolaylaştırmak için çeşitli kayıp katmanları ve görevleri vardır.

Bu durumda, biz faydalanmak edeceğiz Retrieval birlikte o demetleri kayıp fonksiyonu ve metrik hesaplama sarıcı bir kolaylık: Görev nesnesi:

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

Görevin kendisi, sorgu ve aday yerleştirmelerini argüman olarak alan ve hesaplanan kaybı döndüren bir Keras katmanıdır: bunu modelin eğitim döngüsünü uygulamak için kullanacağız.

tam model

Şimdi hepsini bir modelde birleştirebiliriz. TFRS bir temel modeli sınıfını (açığa tfrs.models.Model bina modellerini kolaylaştırır): Yapmamız gereken tüm bileşenleri kurmaktır __init__ yöntemi ve uygulama compute_loss ham özellikleri alıp bir kayıp değerini döndüren yöntem .

Temel model daha sonra modelimize uyacak uygun eğitim döngüsünü oluşturmaya özen gösterecektir.

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 taban sınıfı basitçe kolaylık sınıftır: Bu bize aynı yöntemi kullanarak hem eğitim ve test kayıplarını hesaplamak için izin verir.

Kaputun altında hala sade bir Keras modeli. Sen devralmasını tarafından aynı işlevselliği elde edebiliriz tf.keras.Model ve ağır basan train_step ve test_step fonksiyonları (bkz kılavuzu detayları için):

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

Bu öğreticiler ise, kullandığımız sopa tfrs.Model uzak Demirbaş bazı modelleme ve soyut odaklanmış durumdayız için temel sınıfını.

Takma ve değerlendirme

Modeli tanımladıktan sonra, modeli sığdırmak ve değerlendirmek için standart Keras uydurma ve değerlendirme rutinlerini kullanabiliriz.

Önce modeli somutlaştıralım.

model = MovielensModel(user_model, movie_model)
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))

Ardından eğitim ve değerlendirme verilerini karıştırın, gruplayın ve önbelleğe alın.

cached_train = train.shuffle(100_000).batch(8192).cache()
cached_test = test.batch(4096).cache()

Ardından modeli eğitin:

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>

Eğer TensorBoard ile eğitim sürecini izlemek istiyorsanız, size uygun () işlevine bir TensorBoard geri arama ekleyin ve sonra kullanarak TensorBoard başlayabilirsiniz %tensorboard --logdir logs/fit . Bakınız TensorBoard belgelerinde daha fazla ayrıntı için.

Model ilerledikçe, kayıp düşüyor ve bir dizi birinci sınıf alma metriği güncelleniyor. Bunlar bize, gerçek pozitifin tüm aday kümesinden alınan ilk k öğede olup olmadığını söyler. Örneğin, 0,2'lik bir ilk 5 kategorik doğruluk metriği bize, ortalama olarak, gerçek pozitifin zamanın %20'sinde ilk alınan 5 öğede olduğunu söyler.

Bu örnekte, değerlendirmenin yanı sıra eğitim sırasında metrikleri de değerlendirdiğimizi unutmayın. Bu, büyük aday kümelerinde oldukça yavaş olabileceğinden, eğitimde metrik hesaplamayı kapatmak ve yalnızca değerlendirmede çalıştırmak akıllıca olabilir.

Son olarak modelimizi test setinde değerlendirebiliriz:

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}

Test seti performansı, eğitim performansından çok daha kötü. Bu iki faktörden kaynaklanmaktadır:

  1. Modelimizin gördüğü veriler üzerinde daha iyi performans göstermesi muhtemeldir, çünkü onu ezberleyebilir. Bu aşırı uydurma fenomeni, modellerin birçok parametresi olduğunda özellikle güçlüdür. Modelin düzenli hale getirilmesi ve modelin görünmeyen verilere daha iyi genelleştirilmesine yardımcı olan kullanıcı ve film özelliklerinin kullanımı ile aracılık edilebilir.
  2. Model, bazı kullanıcıların önceden izlemiş olduğu filmleri yeniden öneriyor. Olumlu olduğu bilinen bu saatler, test filmlerini en iyi K önerilerinin dışına çıkarabilir.

İkinci fenomen, daha önce izlenen filmleri test önerilerinden çıkararak çözülebilir. Bu yaklaşım, öneri sistemleri literatüründe nispeten yaygındır, ancak bu eğitimlerde bunu takip etmiyoruz. Geçmiş saatleri önermemek önemliyse, uygun şekilde belirtilen modellerin bu davranışı geçmiş kullanıcı geçmişinden ve bağlamsal bilgilerden otomatik olarak öğrenmesini beklemeliyiz. Ek olarak, aynı öğeyi birden çok kez önermek genellikle uygundur (örneğin, her zaman yeşil kalan bir TV dizisi veya düzenli olarak satın alınan bir öğe).

tahminlerde bulunmak

Artık elimizde bir model olduğuna göre tahminlerde bulunmak istiyoruz. Biz kullanabilirsiniz tfrs.layers.factorized_top_k.BruteForce bunu katmanı.

# 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)']

Tabii ki, BruteForce katman birçok olası adaylar ile bir model hizmet etmek çok yavaş olacak. Aşağıdaki bölümler, yaklaşık bir alma dizini kullanarak bunun nasıl hızlandırılacağını gösterir.

Model sunumu

Model eğitildikten sonra, onu dağıtmak için bir yola ihtiyacımız var.

İki kuleli bir alma modelinde hizmetin iki bileşeni vardır:

  • sorgunun özelliklerini alan ve bunları bir sorgu gömmesine dönüştüren bir hizmet sorgu modeli ve
  • hizmet eden bir aday modeli. Bu genellikle, sorgu modeli tarafından üretilen bir sorguya yanıt olarak adayların hızlı bir şekilde yaklaşık olarak aranmasına izin veren yaklaşık bir en yakın komşular (ANN) indeksi şeklini alır.

TFRS'de, her iki bileşen de tek bir dışa aktarılabilir modelde paketlenebilir, bu da bize ham kullanıcı kimliğini alan ve o kullanıcı için en iyi filmlerin başlıklarını döndüren bir model verir. Bu modeli ihraç yoluyla yapılır SavedModel mümkün kullanarak hizmet etmek yapar biçimi, TensorFlow Porsiyon .

Böyle bir model dağıtmak için, biz sadece ihracat BruteForce Yukarıda oluşturulan katman:

# 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)']

Ayrıca, tahminleri hızlandırmak için yaklaşık bir alma endeksini dışa aktarabiliriz. Bu, on milyonlarca adaydan oluşan kümelerin önerilerini verimli bir şekilde ortaya çıkarmayı mümkün kılacaktır.

Bunu yapmak için, biz kullanabilirsiniz scann paketi. Bu TFRS'nin isteğe bağlı bir bağımlılık ve biz çağırarak bu yazının başında ayrı ayrı yüklü !pip install -q scann .

Yüklendikten sonra biz TFRS kullanabilirsiniz ScaNN katmanını:

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>

Bu katman yaklaşık aramaları gerçekleştirecek: Bu markaları büyüklük siparişleri daha hızlı büyük aday setlerinde biraz daha az doğru erişilmesi ancak.

# 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)']

Hizmet için İhracat ihracat kadar kolaydır BruteForce katmanını:

# 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)']

Hızlı yaklaşık alma modellerini kullanarak ve ayarlama hakkında daha fazla bilgi edinmek için bir göz verimli hizmet öğretici.

Öğeden öğeye öneri

Bu modelde bir kullanıcı-film modeli oluşturduk. Ancak, bazı uygulamalarda (örneğin, ürün detay sayfaları) öğeden öğeye (örneğin, filmden filme veya üründen ürüne) önerilerin gerçekleştirilmesi yaygındır.

Bunun gibi eğitim modelleri, bu öğreticide gösterilenle aynı modeli izleyecektir, ancak farklı eğitim verileriyle. Burada bir kullanıcımız ve bir film kulemiz vardı ve onları eğitmek için (kullanıcı, film) çiftlerini kullandık. Öğeden öğeye bir modelde, iki öğe kulemiz (sorgu ve aday öğe için) olurdu ve modeli (sorgu öğesi, aday öğe) çiftlerini kullanarak eğitirdik. Bunlar, ürün detay sayfalarındaki tıklamalardan oluşturulabilir.

Sonraki adımlar

Bu, alma öğreticisini tamamlar.

Burada sunulanları genişletmek için şuna bir göz atın:

  1. Çoklu görev modellerini öğrenme: derecelendirmeler ve tıklamalar için ortak optimizasyon.
  2. Film meta verilerini kullanma: Soğuk başlatmayı hafifletmek için daha karmaşık bir film modeli oluşturma.