फिल्मों की सिफारिश करना: अनुक्रमिक मॉडल का उपयोग करके पुनर्प्राप्ति

TensorFlow.org पर देखें Google Colab में चलाएं GitHub पर स्रोत देखें नोटबुक डाउनलोड करें

इस ट्यूटोरियल में, हम एक अनुक्रमिक पुनर्प्राप्ति मॉडल बनाने जा रहे हैं। अनुक्रमिक अनुशंसा एक लोकप्रिय मॉडल है जो उन वस्तुओं के अनुक्रम को देखता है जिनके साथ उपयोगकर्ताओं ने पहले बातचीत की है और फिर अगले आइटम की भविष्यवाणी करता है। यहां प्रत्येक अनुक्रम में वस्तुओं का क्रम मायने रखता है, इसलिए हम अनुक्रमिक संबंध को मॉडल करने के लिए एक आवर्तक तंत्रिका नेटवर्क का उपयोग करने जा रहे हैं। अधिक जानकारी के लिए, इस का संदर्भ लें GRU4Rec कागज

आयात

आइए पहले अपनी निर्भरता और आयात को रास्ते से हटा दें।

pip install -q tensorflow-recommenders
pip install -q --upgrade tensorflow-datasets
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

डेटासेट तैयार करना

इसके बाद, हमें अपना डेटासेट तैयार करने की आवश्यकता है। हम लाभ उठाने के लिए जा रहे हैं डेटा पीढ़ी उपयोगिता इस में TensorFlow लाइट उपकरण पर मौजूद सिफ़ारिश संदर्भ एप्लिकेशन

, और movies.dat (स्तंभों: MovieID, शीर्षक, शैलियों): MovieLens 1M डेटा ratings.dat (UserID, MovieID, रेटिंग, टाइमस्टैम्प कॉलम) शामिल हैं। उदाहरण पीढ़ी स्क्रिप्ट 1M डेटासेट डाउनलोड करती है, दोनों फाइलें लेती है, केवल 2 से अधिक रेटिंग रखती है, उपयोगकर्ता मूवी इंटरैक्शन टाइमलाइन बनाती है, नमूना गतिविधियों को लेबल के रूप में और 10 पिछली उपयोगकर्ता गतिविधियों को भविष्यवाणी के संदर्भ के रूप में बनाती है।

wget -nc https://raw.githubusercontent.com/tensorflow/examples/master/lite/examples/recommendation/ml/data/example_generation_movielens.py
python -m example_generation_movielens  --data_dir=data/raw  --output_dir=data/examples  --min_timeline_length=3  --max_context_length=10  --max_context_movie_genre_length=10  --min_rating=2  --train_data_fraction=0.9  --build_vocabs=False
--2021-12-02 12:10:29--  https://raw.githubusercontent.com/tensorflow/examples/master/lite/examples/recommendation/ml/data/example_generation_movielens.py
Resolving raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.108.133, 185.199.110.133, 185.199.111.133, ...
Connecting to raw.githubusercontent.com (raw.githubusercontent.com)|185.199.108.133|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 18040 (18K) [text/plain]
Saving to: ‘example_generation_movielens.py’

example_generation_ 100%[===================>]  17.62K  --.-KB/s    in 0s      

2021-12-02 12:10:29 (107 MB/s) - ‘example_generation_movielens.py’ saved [18040/18040]

I1202 12:10:32.036267 140629273970496 example_generation_movielens.py:460] Downloading and extracting data.
Downloading data from http://files.grouplens.org/datasets/movielens/ml-1m.zip
5922816/5917549 [==============================] - 1s 0us/step
5931008/5917549 [==============================] - 1s 0us/step
I1202 12:10:33.549675 140629273970496 example_generation_movielens.py:406] Reading data to dataframes.
/tmpfs/src/tf_docs_env/lib/python3.7/site-packages/pandas/util/_decorators.py:311: ParserWarning: Falling back to the 'python' engine because the 'c' engine does not support regex separators (separators > 1 char and different from '\s+' are interpreted as regex); you can avoid this warning by specifying engine='python'.
  return func(*args, **kwargs)
I1202 12:10:37.734699 140629273970496 example_generation_movielens.py:408] Generating movie rating user timelines.
I1202 12:10:40.836473 140629273970496 example_generation_movielens.py:410] Generating train and test examples.
6040/6040 [==============================] - 76s 13ms/step
I1202 12:11:57.162662 140629273970496 example_generation_movielens.py:421] Writing generated training examples.
844195/844195 [==============================] - 14s 17us/step
I1202 12:12:11.266682 140629273970496 example_generation_movielens.py:424] Writing generated testing examples.
93799/93799 [==============================] - 2s 17us/step
I1202 12:12:22.758407 140629273970496 example_generation_movielens.py:473] Generated dataset: {'train_size': 844195, 'test_size': 93799, 'train_file': 'data/examples/train_movielens_1m.tfrecord', 'test_file': 'data/examples/test_movielens_1m.tfrecord'}

जेनरेट किए गए डेटासेट का नमूना यहां दिया गया है।

0 : {
  features: {
    feature: {
      key  : "context_movie_id"
      value: { int64_list: { value: [ 1124, 2240, 3251, ..., 1268 ] } }
    }
    feature: {
      key  : "context_movie_rating"
      value: { float_list: {value: [ 3.0, 3.0, 4.0, ..., 3.0 ] } }
    }
    feature: {
      key  : "context_movie_year"
      value: { int64_list: { value: [ 1981, 1980, 1985, ..., 1990 ] } }
    }
    feature: {
      key  : "context_movie_genre"
      value: { bytes_list: { value: [ "Drama", "Drama", "Mystery", ..., "UNK" ] } }
    }
    feature: {
      key  : "label_movie_id"
      value: { int64_list: { value: [ 3252 ] }  }
    }
  }
}

आप देख सकते हैं कि इसमें संदर्भ मूवी आईडी का अनुक्रम, और एक लेबल मूवी आईडी (अगली फिल्म), साथ ही मूवी वर्ष, रेटिंग और शैली जैसी संदर्भ सुविधाएं शामिल हैं।

हमारे मामले में हम केवल संदर्भ मूवी आईडी और लेबल मूवी आईडी के अनुक्रम का उपयोग करेंगे। आप उल्लेख कर सकते हैं करने के लिए इस्तेमाल संदर्भ ट्यूटोरियल सुविधाओं अतिरिक्त संदर्भ विशेषताएं जोड़ने के बारे में अधिक जानने के।

train_filename = "./data/examples/train_movielens_1m.tfrecord"
train = tf.data.TFRecordDataset(train_filename)

test_filename = "./data/examples/test_movielens_1m.tfrecord"
test = tf.data.TFRecordDataset(test_filename)

feature_description = {
    'context_movie_id': tf.io.FixedLenFeature([10], tf.int64, default_value=np.repeat(0, 10)),
    'context_movie_rating': tf.io.FixedLenFeature([10], tf.float32, default_value=np.repeat(0, 10)),
    'context_movie_year': tf.io.FixedLenFeature([10], tf.int64, default_value=np.repeat(1980, 10)),
    'context_movie_genre': tf.io.FixedLenFeature([10], tf.string, default_value=np.repeat("Drama", 10)),
    'label_movie_id': tf.io.FixedLenFeature([1], tf.int64, default_value=0),
}

def _parse_function(example_proto):
  return tf.io.parse_single_example(example_proto, feature_description)

train_ds = train.map(_parse_function).map(lambda x: {
    "context_movie_id": tf.strings.as_string(x["context_movie_id"]),
    "label_movie_id": tf.strings.as_string(x["label_movie_id"])
})

test_ds = test.map(_parse_function).map(lambda x: {
    "context_movie_id": tf.strings.as_string(x["context_movie_id"]),
    "label_movie_id": tf.strings.as_string(x["label_movie_id"])
})

for x in train_ds.take(1).as_numpy_iterator():
  pprint.pprint(x)
{'context_movie_id': array([b'2589', b'202', b'1038', b'1767', b'951', b'129', b'1256', b'955',
       b'3097', b'3462'], dtype=object),
 'label_movie_id': array([b'3629'], dtype=object)}

अब हमारे ट्रेन/परीक्षण डेटासेट में केवल ऐतिहासिक मूवी आईडी का एक क्रम और अगली मूवी आईडी का एक लेबल शामिल है। ध्यान दें कि हम प्रयोग [10] के रूप में संदर्भ की लंबाई उदाहरण generateion चरण में सुविधाओं tf.Example पार्स दौरान सुविधाओं के आकार है क्योंकि हम 10 द्वारा बताए गए अनुसार।

मॉडल का निर्माण शुरू करने से पहले हमें एक और चीज़ की आवश्यकता है - हमारी मूवी आईडी के लिए शब्दावली।

movies = tfds.load("movielens/1m-movies", split='train')
movies = movies.map(lambda x: x["movie_id"])
movie_ids = movies.batch(1_000)
unique_movie_ids = np.unique(np.concatenate(list(movie_ids)))

अनुक्रमिक मॉडल लागू करना

हमारे में बुनियादी पुनर्प्राप्ति ट्यूटोरियल , हम उपयोगकर्ता के लिए एक क्वेरी टावर, और उम्मीदवार फिल्म के लिए उम्मीदवार टो का उपयोग करें। हालांकि, दो-टावर वास्तुकला सामान्यीकरण योग्य है और सीमित नहीं है जोड़ा। आप इसका उपयोग के रूप में हम में ध्यान दें आइटम करने के लिए आइटम सिफारिश करने के लिए कर सकते हैं बुनियादी पुनर्प्राप्ति ट्यूटोरियल

यहां हम अभी भी टू-टॉवर आर्किटेक्चर का उपयोग करने जा रहे हैं। Specificially, हम एक साथ क्वेरी टॉवर का उपयोग सुरक्षा पूर्ण बारम्बार यूनिट (GRU) परत ऐतिहासिक फिल्मों के अनुक्रम सांकेतिक शब्दों में बदलना, और उम्मीदवार फिल्म के लिए एक ही उम्मीदवार टावर रखने के लिए।

embedding_dimension = 32

query_model = tf.keras.Sequential([
    tf.keras.layers.StringLookup(
      vocabulary=unique_movie_ids, mask_token=None),
    tf.keras.layers.Embedding(len(unique_movie_ids) + 1, embedding_dimension), 
    tf.keras.layers.GRU(embedding_dimension),
])

candidate_model = tf.keras.Sequential([
  tf.keras.layers.StringLookup(
      vocabulary=unique_movie_ids, mask_token=None),
  tf.keras.layers.Embedding(len(unique_movie_ids) + 1, embedding_dimension)
])

मेट्रिक्स, कार्य और पूर्ण मॉडल को मूल पुनर्प्राप्ति मॉडल के समान परिभाषित किया गया है।

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

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

class Model(tfrs.Model):

    def __init__(self, query_model, candidate_model):
        super().__init__()
        self._query_model = query_model
        self._candidate_model = candidate_model

        self._task = task

    def compute_loss(self, features, training=False):
        watch_history = features["context_movie_id"]
        watch_next_label = features["label_movie_id"]

        query_embedding = self._query_model(watch_history)       
        candidate_embedding = self._candidate_model(watch_next_label)

        return self._task(query_embedding, candidate_embedding, compute_metrics=not training)

फिटिंग और मूल्यांकन

अब हम अपने अनुक्रमिक पुनर्प्राप्ति मॉडल को संकलित, प्रशिक्षित और मूल्यांकन कर सकते हैं।

model = Model(query_model, candidate_model)
model.compile(optimizer=tf.keras.optimizers.Adagrad(learning_rate=0.1))
cached_train = train_ds.shuffle(10_000).batch(12800).cache()
cached_test = test_ds.batch(2560).cache()
model.fit(cached_train, epochs=3)
Epoch 1/3
67/67 [==============================] - 25s 291ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_5_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_10_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_50_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_100_categorical_accuracy: 0.0000e+00 - loss: 107448.4467 - regularization_loss: 0.0000e+00 - total_loss: 107448.4467
Epoch 2/3
67/67 [==============================] - 2s 25ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_5_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_10_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_50_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_100_categorical_accuracy: 0.0000e+00 - loss: 100932.0125 - regularization_loss: 0.0000e+00 - total_loss: 100932.0125
Epoch 3/3
67/67 [==============================] - 2s 25ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_5_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_10_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_50_categorical_accuracy: 0.0000e+00 - factorized_top_k/top_100_categorical_accuracy: 0.0000e+00 - loss: 99336.2015 - regularization_loss: 0.0000e+00 - total_loss: 99336.2015
<keras.callbacks.History at 0x7f0904d5b410>
model.evaluate(cached_test, return_dict=True)
37/37 [==============================] - 10s 235ms/step - factorized_top_k/top_1_categorical_accuracy: 0.0146 - factorized_top_k/top_5_categorical_accuracy: 0.0780 - factorized_top_k/top_10_categorical_accuracy: 0.1358 - factorized_top_k/top_50_categorical_accuracy: 0.3735 - factorized_top_k/top_100_categorical_accuracy: 0.5058 - loss: 15478.0652 - regularization_loss: 0.0000e+00 - total_loss: 15478.0652
{'factorized_top_k/top_1_categorical_accuracy': 0.014605699107050896,
 'factorized_top_k/top_5_categorical_accuracy': 0.07804987579584122,
 'factorized_top_k/top_10_categorical_accuracy': 0.1358330100774765,
 'factorized_top_k/top_50_categorical_accuracy': 0.3735221028327942,
 'factorized_top_k/top_100_categorical_accuracy': 0.5058262944221497,
 'loss': 9413.1240234375,
 'regularization_loss': 0,
 'total_loss': 9413.1240234375}

यह अनुक्रमिक पुनर्प्राप्ति ट्यूटोरियल का समापन करता है।