পার্শ্ব বৈশিষ্ট্য ব্যবহার: বৈশিষ্ট্য preprocessing

TensorFlow.org এ দেখুন Google Colab-এ চালান GitHub-এ উৎস দেখুন নোটবুক ডাউনলোড করুন

সুপারিশকারী মডেল তৈরি করতে গভীর শিক্ষার কাঠামো ব্যবহার করার একটি দুর্দান্ত সুবিধা হল সমৃদ্ধ, নমনীয় বৈশিষ্ট্য উপস্থাপনা তৈরি করার স্বাধীনতা।

এটি করার প্রথম ধাপ হল বৈশিষ্ট্যগুলি প্রস্তুত করা, কারণ কাঁচা বৈশিষ্ট্যগুলি সাধারণত একটি মডেলে অবিলম্বে ব্যবহারযোগ্য হবে না।

উদাহরণ স্বরূপ:

  • ব্যবহারকারী এবং আইটেম আইডি স্ট্রিং (শিরোনাম, ব্যবহারকারীর নাম) বা বড়, অসংলগ্ন পূর্ণসংখ্যা (ডাটাবেস আইডি) হতে পারে।
  • আইটেম বিবরণ কাঁচা টেক্সট হতে পারে.
  • মিথস্ক্রিয়া টাইমস্ট্যাম্প কাঁচা ইউনিক্স টাইমস্ট্যাম্প হতে পারে।

মডেল নির্মাণে উপযোগী হওয়ার জন্য এগুলি যথাযথভাবে রূপান্তরিত করা প্রয়োজন:

  • ব্যবহারকারী এবং আইটেম আইডিগুলিকে এমবেডিং ভেক্টরগুলিতে অনুবাদ করতে হবে: উচ্চ-মাত্রিক সংখ্যাসূচক উপস্থাপনা যা প্রশিক্ষণের সময় সামঞ্জস্য করা হয় যাতে মডেলটিকে তার উদ্দেশ্যটি আরও ভালভাবে ভবিষ্যদ্বাণী করতে সহায়তা করে।
  • কাঁচা পাঠ্যকে টোকেনাইজ করা দরকার (ছোট অংশে বিভক্ত যেমন পৃথক শব্দ) এবং এম্বেডিং-এ অনুবাদ করা।
  • সংখ্যাসূচক বৈশিষ্ট্যগুলিকে স্বাভাবিক করতে হবে যাতে তাদের মানগুলি 0 এর কাছাকাছি একটি ছোট ব্যবধানে থাকে।

সৌভাগ্যবশত, TensorFlow ব্যবহার করে আমরা আলাদা প্রিপ্রসেসিং ধাপের পরিবর্তে আমাদের মডেলের এই ধরনের প্রিপ্রসেসিং অংশ তৈরি করতে পারি। এটি শুধুমাত্র সুবিধাজনক নয়, এটি নিশ্চিত করে যে আমাদের প্রি-প্রসেসিং প্রশিক্ষণের সময় এবং পরিবেশনের সময় ঠিক একই রকম। এটি এমন মডেলগুলিকে স্থাপন করা নিরাপদ এবং সহজ করে তোলে যার মধ্যে এমনকি অত্যন্ত পরিশীলিত প্রাক-প্রক্রিয়াকরণ অন্তর্ভুক্ত রয়েছে।

এই টিউটোরিয়াল, আমরা প্রস্তাবকারী উপর ফোকাস করতে যাচ্ছি এবং preprocessing আমরা যা করতে হবে MovieLens ডেটা সেটটি । আপনি যদি একটি recommender সিস্টেম ফোকাস ছাড়া একটি বড় টিউটোরিয়ালে আগ্রহী হন, তাহলে পূর্ণ কটাক্ষপাত আছে Keras preprocessing নির্দেশিকা

মুভিলেন্স ডেটাসেট

চলুন প্রথমে দেখে নেই আমরা মুভিলেন্স ডেটাসেট থেকে কী কী বৈশিষ্ট্য ব্যবহার করতে পারি:

pip install -q --upgrade tensorflow-datasets
import pprint

import tensorflow_datasets as tfds

ratings = tfds.load("movielens/100k-ratings", split="train")

for x in ratings.take(1).as_numpy_iterator():
  pprint.pprint(x)
2021-10-02 11:59:46.956587: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
{'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:59:47.327679: 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.

এখানে কয়েকটি মূল বৈশিষ্ট্য রয়েছে:

  • মুভির শিরোনাম একটি মুভি সনাক্তকারী হিসাবে দরকারী।
  • ইউজার আইডি ইউজার আইডেন্টিফায়ার হিসেবে উপযোগী।
  • টাইমস্ট্যাম্প আমাদের সময়ের প্রভাব মডেল করতে অনুমতি দেবে.

প্রথম দুটি হল সুনির্দিষ্ট বৈশিষ্ট্য; টাইমস্ট্যাম্প একটি অবিচ্ছিন্ন বৈশিষ্ট্য।

এম্বেডিং এ শ্রেণীগত বৈশিষ্ট্য বাঁক

একটি শ্রেণীগত বৈশিষ্ট্য একটি বৈশিষ্ট্য যা একটি ক্রমাগত পরিমাণ প্রকাশ করার নয়, বরং নির্দিষ্ট মান একটি সেট এক সময় লাগে।

বেশিরভাগ গভীর শিক্ষার মডেল এই বৈশিষ্ট্যগুলিকে উচ্চ-মাত্রিক ভেক্টরে পরিণত করে প্রকাশ করে। মডেল প্রশিক্ষণের সময়, মডেলটিকে তার উদ্দেশ্যকে আরও ভালভাবে ভবিষ্যদ্বাণী করতে সাহায্য করার জন্য সেই ভেক্টরের মান সমন্বয় করা হয়।

উদাহরণস্বরূপ, ধরুন আমাদের লক্ষ্য হল ভবিষ্যদ্বাণী করা কোন ব্যবহারকারী কোন সিনেমাটি দেখতে যাচ্ছেন। এটি করার জন্য, আমরা প্রতিটি ব্যবহারকারী এবং প্রতিটি চলচ্চিত্রকে একটি এমবেডিং ভেক্টর দ্বারা প্রতিনিধিত্ব করি। প্রাথমিকভাবে, এই এম্বেডিংগুলি এলোমেলো মানগুলি গ্রহণ করবে - কিন্তু প্রশিক্ষণের সময়, আমরা সেগুলিকে সামঞ্জস্য করব যাতে ব্যবহারকারীদের এমবেডিং এবং তারা যে মুভিগুলি দেখেন তা একসাথে শেষ হয়৷

কাঁচা শ্রেণীগত বৈশিষ্ট্যগুলি গ্রহণ করা এবং এম্বেডিংয়ে পরিণত করা সাধারণত একটি দ্বি-পদক্ষেপ প্রক্রিয়া:

  1. প্রথমত, আমাদের কাঁচা মানগুলিকে সংলগ্ন পূর্ণসংখ্যাগুলির একটি পরিসরে অনুবাদ করতে হবে, সাধারণত একটি ম্যাপিং তৈরি করে (একটি "শব্দভাণ্ডার" বলা হয়) যা কাঁচা মানগুলিকে ("স্টার ওয়ারস") পূর্ণসংখ্যাতে ম্যাপ করে (বলুন, 15)।
  2. দ্বিতীয়ত, আমাদের এই পূর্ণসংখ্যা নিতে হবে এবং এম্বেডিং-এ পরিণত করতে হবে।

শব্দভান্ডার সংজ্ঞায়িত করা

প্রথম ধাপ হল একটি শব্দভান্ডার সংজ্ঞায়িত করা। কেরাস প্রিপ্রসেসিং লেয়ার ব্যবহার করে আমরা এটি সহজেই করতে পারি।

import numpy as np
import tensorflow as tf

movie_title_lookup = tf.keras.layers.StringLookup()

লেয়ারটির নিজেই এখনও একটি শব্দভান্ডার নেই, তবে আমরা আমাদের ডেটা ব্যবহার করে এটি তৈরি করতে পারি।

movie_title_lookup.adapt(ratings.map(lambda x: x["movie_title"]))

print(f"Vocabulary: {movie_title_lookup.get_vocabulary()[:3]}")
Vocabulary: ['[UNK]', 'Star Wars (1977)', 'Contact (1997)']

একবার আমাদের কাছে এটি হয়ে গেলে আমরা এম্বেডিং আইডিতে কাঁচা টোকেন অনুবাদ করতে স্তরটি ব্যবহার করতে পারি:

movie_title_lookup(["Star Wars (1977)", "One Flew Over the Cuckoo's Nest (1975)"])
<tf.Tensor: shape=(2,), dtype=int64, numpy=array([ 1, 58])>

মনে রাখবেন যে স্তরের শব্দভান্ডারে এক (বা একাধিক!) অজানা (বা "শব্দভান্ডারের বাইরে", OOV) টোকেন অন্তর্ভুক্ত রয়েছে। এটি সত্যিই সুবিধাজনক: এর মানে হল যে স্তরটি শ্রেণীবদ্ধ মানগুলি পরিচালনা করতে পারে যা শব্দভাণ্ডারে নেই। ব্যবহারিক পরিভাষায়, এর মানে হল যে মডেলটি শব্দভান্ডার নির্মাণের সময় দেখা যায়নি এমন বৈশিষ্ট্যগুলি ব্যবহার করেও শিখতে এবং সুপারিশ করতে পারে।

বৈশিষ্ট্য হ্যাশিং ব্যবহার করে

বস্তুত, StringLookup স্তর আমাদের একাধিক OOV সূচকের কনফিগার করতে পারেন। যদি আমরা তা করি, শব্দভান্ডারে নেই এমন যেকোন কাঁচা মান নির্ধারকভাবে OOV সূচকগুলির একটিতে হ্যাশ করা হবে। আমাদের কাছে যত বেশি এই ধরনের সূচক রয়েছে, তত কম এটি যে দুটি ভিন্ন কাঁচা বৈশিষ্ট্যের মান একই OOV সূচকে হ্যাশ হবে। ফলস্বরূপ, যদি আমাদের কাছে এই ধরনের পর্যাপ্ত সূচক থাকে তবে মডেলটি টোকেন তালিকা বজায় রাখার অসুবিধা ছাড়াই একটি সুস্পষ্ট শব্দভাণ্ডার সহ একটি মডেল সম্পর্কে প্রশিক্ষণ দিতে সক্ষম হওয়া উচিত।

আমরা এটিকে এর যৌক্তিক চরমে নিয়ে যেতে পারি এবং সম্পূর্ণরূপে বৈশিষ্ট্য হ্যাশিংয়ের উপর নির্ভর করতে পারি, কোন শব্দভান্ডার ছাড়াই। এই বাস্তবায়িত হয় tf.keras.layers.Hashing স্তর।

# We set up a large number of bins to reduce the chance of hash collisions.
num_hashing_bins = 200_000

movie_title_hashing = tf.keras.layers.Hashing(
    num_bins=num_hashing_bins
)

আমরা শব্দভান্ডার তৈরি করার প্রয়োজন ছাড়াই আগের মতো লুকআপ করতে পারি:

movie_title_hashing(["Star Wars (1977)", "One Flew Over the Cuckoo's Nest (1975)"])
<tf.Tensor: shape=(2,), dtype=int64, numpy=array([101016,  96565])>

এমবেডিং সংজ্ঞায়িত করা

এখন আমরা পূর্ণসংখ্যা আইডি আছে, আমরা ব্যবহার করতে পারি Embedding embeddings মধ্যে যারা ঘুরে স্তর।

একটি এমবেডিং স্তরের দুটি মাত্রা রয়েছে: প্রথম মাত্রাটি আমাদেরকে বলে যে আমরা কতগুলি স্বতন্ত্র বিভাগ এম্বেড করতে পারি; দ্বিতীয়টি আমাদের বলে যে তাদের প্রত্যেকের প্রতিনিধিত্বকারী ভেক্টরটি কত বড় হতে পারে।

চলচ্চিত্রের শিরোনামগুলির জন্য এমবেডিং স্তর তৈরি করার সময়, আমরা আমাদের শিরোনাম শব্দভান্ডারের আকারে (বা হ্যাশিং বিনের সংখ্যা) প্রথম মান সেট করতে যাচ্ছি। দ্বিতীয়টি আমাদের উপর নির্ভর করে: এটি যত বড় হবে, মডেলটির ক্ষমতা তত বেশি, তবে এটি ফিট করা এবং পরিবেশন করা তত ধীর।

movie_title_embedding = tf.keras.layers.Embedding(
    # Let's use the explicit vocabulary lookup.
    input_dim=movie_title_lookup.vocab_size(),
    output_dim=32
)
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.

আমরা দুটিকে একসাথে একটি একক স্তরে রাখতে পারি যা কাঁচা টেক্সট নেয় এবং এম্বেডিং দেয়।

movie_title_model = tf.keras.Sequential([movie_title_lookup, movie_title_embedding])

ঠিক তেমনি, আমরা সরাসরি আমাদের চলচ্চিত্রের শিরোনামগুলির জন্য এম্বেডিং পেতে পারি:

movie_title_model(["Star Wars (1977)"])
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'list'> input: ['Star Wars (1977)']
Consider rewriting this model with the Functional API.
WARNING:tensorflow:Layers in a Sequential model should only have a single input tensor, but we receive a <class 'list'> input: ['Star Wars (1977)']
Consider rewriting this model with the Functional API.
<tf.Tensor: shape=(1, 32), dtype=float32, numpy=
array([[-0.00255408,  0.00941082,  0.02599109, -0.02758816, -0.03652344,
        -0.03852248, -0.03309812, -0.04343383,  0.03444691, -0.02454401,
         0.00619583, -0.01912323, -0.03988413,  0.03595274,  0.00727529,
         0.04844356,  0.04739804,  0.02836904,  0.01647964, -0.02924066,
        -0.00425701,  0.01747661,  0.0114414 ,  0.04916174,  0.02185034,
        -0.00399858,  0.03934855,  0.03666003,  0.01980535, -0.03694187,
        -0.02149243, -0.03765338]], dtype=float32)>

আমরা ব্যবহারকারীর এম্বেডিংয়ের সাথে একই কাজ করতে পারি:

user_id_lookup = tf.keras.layers.StringLookup()
user_id_lookup.adapt(ratings.map(lambda x: x["user_id"]))

user_id_embedding = tf.keras.layers.Embedding(user_id_lookup.vocab_size(), 32)

user_id_model = tf.keras.Sequential([user_id_lookup, user_id_embedding])
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.

ক্রমাগত বৈশিষ্ট্য স্বাভাবিককরণ

ক্রমাগত বৈশিষ্ট্য এছাড়াও স্বাভাবিককরণ প্রয়োজন. উদাহরণস্বরূপ, timestamp বৈশিষ্ট্য পর্যন্ত খুব বড় একটা গভীর মডেল সরাসরি ব্যবহার করা হয়:

for x in ratings.take(3).as_numpy_iterator():
  print(f"Timestamp: {x['timestamp']}.")
Timestamp: 879024327.
Timestamp: 875654590.
Timestamp: 882075110.

আমরা এটি ব্যবহার করার আগে আমাদের এটি প্রক্রিয়া করতে হবে। যদিও আমরা এটি করতে পারি এমন অনেক উপায় রয়েছে, বিচক্ষণতা এবং মানককরণ দুটি সাধারণ।

প্রমিতকরণ

প্রমিতকরণ rescales বৈশিষ্ট্যের গড় বিয়োগ এবং তার স্ট্যানডার্ড ডেভিয়েশন দ্বারা বিভাজক দ্বারা তাদের পরিসীমা স্বাভাবিক বৈশিষ্ট্যগুলিও উপস্থিত রয়েছে। এটি একটি সাধারণ প্রিপ্রসেসিং রূপান্তর।

এই সহজে ব্যবহার করা সম্ভব tf.keras.layers.Normalization স্তর:

timestamp_normalization = tf.keras.layers.Normalization(
    axis=None
)
timestamp_normalization.adapt(ratings.map(lambda x: x["timestamp"]).batch(1024))

for x in ratings.take(3).as_numpy_iterator():
  print(f"Normalized timestamp: {timestamp_normalization(x['timestamp'])}.")
Normalized timestamp: [-0.84293723].
Normalized timestamp: [-1.4735204].
Normalized timestamp: [-0.27203268].

বিচক্ষণতা

আরেকটি সাধারণ রূপান্তর হল একটি ক্রমাগত বৈশিষ্ট্যকে বেশ কয়েকটি শ্রেণীবদ্ধ বৈশিষ্ট্যে পরিণত করা। যদি আমাদের সন্দেহ করার কারণ থাকে যে একটি বৈশিষ্ট্যের প্রভাব ক্রমাগত নয় তাহলে এটি ভাল বোধগম্য হয়।

এটি করার জন্য, আমাদের প্রথমে বালতিগুলির সীমানা স্থাপন করতে হবে যা আমরা বিচক্ষণতার জন্য ব্যবহার করব। সবচেয়ে সহজ উপায় হল বৈশিষ্ট্যটির সর্বনিম্ন এবং সর্বোচ্চ মান সনাক্ত করা এবং ফলাফলের ব্যবধানকে সমানভাবে ভাগ করা:

max_timestamp = ratings.map(lambda x: x["timestamp"]).reduce(
    tf.cast(0, tf.int64), tf.maximum).numpy().max()
min_timestamp = ratings.map(lambda x: x["timestamp"]).reduce(
    np.int64(1e9), tf.minimum).numpy().min()

timestamp_buckets = np.linspace(
    min_timestamp, max_timestamp, num=1000)

print(f"Buckets: {timestamp_buckets[:3]}")
Buckets: [8.74724710e+08 8.74743291e+08 8.74761871e+08]

বালতি সীমানা দেওয়া হলে আমরা টাইমস্ট্যাম্পগুলিকে এমবেডিংয়ে রূপান্তর করতে পারি:

timestamp_embedding_model = tf.keras.Sequential([
  tf.keras.layers.Discretization(timestamp_buckets.tolist()),
  tf.keras.layers.Embedding(len(timestamp_buckets) + 1, 32)
])

for timestamp in ratings.take(1).map(lambda x: x["timestamp"]).batch(1).as_numpy_iterator():
  print(f"Timestamp embedding: {timestamp_embedding_model(timestamp)}.")
Timestamp embedding: [[-0.02532113 -0.00415025  0.00458465  0.02080876  0.03103903 -0.03746337
   0.04010465 -0.01709593 -0.00246077 -0.01220842  0.02456966 -0.04816503
   0.04552222  0.03535838  0.00769508  0.04328252  0.00869263  0.01110227
   0.02754457 -0.02659499 -0.01055292 -0.03035731  0.00463334 -0.02848787
  -0.03416766  0.02538678 -0.03446608 -0.0384447  -0.03032914 -0.02391632
   0.02637175 -0.01158618]].

পাঠ্য বৈশিষ্ট্য প্রক্রিয়াকরণ

আমরা আমাদের মডেলে পাঠ্য বৈশিষ্ট্য যোগ করতে চাই। সাধারণত, পণ্যের বিবরণের মতো জিনিসগুলি বিনামূল্যের টেক্সট হয়, এবং আমরা আশা করতে পারি যে আমাদের মডেল আরও ভাল সুপারিশ করতে, বিশেষ করে একটি কোল্ড-স্টার্ট বা লম্বা টেল পরিস্থিতিতে তাদের মধ্যে থাকা তথ্য ব্যবহার করতে শিখতে পারে।

যদিও মুভিলেন্স ডেটাসেট আমাদের সমৃদ্ধ পাঠ্য বৈশিষ্ট্য দেয় না, আমরা এখনও চলচ্চিত্রের শিরোনাম ব্যবহার করতে পারি। এটি আমাদের এই সত্যটি ধরতে সাহায্য করতে পারে যে খুব অনুরূপ শিরোনাম সহ সিনেমাগুলি একই সিরিজের অন্তর্গত হতে পারে।

টেক্সট-এ আমাদের প্রথম যে রূপান্তরটি প্রয়োগ করতে হবে তা হল টোকেনাইজেশন (গঠক শব্দ বা শব্দ-টুকরোতে বিভক্ত করা), তারপরে শব্দভাণ্ডার শেখা, তারপরে এম্বেডিং।

Keras tf.keras.layers.TextVectorization স্তর আমাদের জন্য প্রথম দুই ধাপ করতে পারেন:

title_text = tf.keras.layers.TextVectorization()
title_text.adapt(ratings.map(lambda x: x["movie_title"]))

আসুন এটি চেষ্টা করে দেখুন:

for row in ratings.batch(1).map(lambda x: x["movie_title"]).take(1):
  print(title_text(row))
tf.Tensor([[ 32 266 162   2 267 265  53]], shape=(1, 7), dtype=int64)

প্রতিটি শিরোনাম টোকেনের একটি ক্রমানুসারে অনুবাদ করা হয়, আমরা টোকেনাইজ করেছি প্রতিটি অংশের জন্য একটি।

লেয়ারটি সঠিক টোকেনাইজেশন ব্যবহার করছে কিনা তা যাচাই করতে আমরা শেখা শব্দভান্ডার পরীক্ষা করতে পারি:

title_text.get_vocabulary()[40:45]
['first', '1998', '1977', '1971', 'monty']

এটি সঠিক দেখায়: স্তরটি পৃথক শব্দে শিরোনাম টোকেনাইজ করছে।

প্রক্রিয়াকরণ শেষ করতে, আমাদের এখন পাঠ্যটি এম্বেড করতে হবে। যেহেতু প্রতিটি শিরোনামে একাধিক শব্দ রয়েছে, তাই আমরা প্রতিটি শিরোনামের জন্য একাধিক এম্বেডিং পাব। একটি ডনস্ট্রিম মডেলে ব্যবহারের জন্য এগুলি সাধারণত একটি একক এম্বেডিংয়ে সংকুচিত হয়। RNN বা ট্রান্সফরমারের মত মডেলগুলি এখানে উপযোগী, কিন্তু সমস্ত শব্দের এম্বেডিংকে একত্রে গড় করা একটি ভাল সূচনা বিন্দু।

সবগুলোকে একত্রে রাখ

এই উপাদানগুলির জায়গায়, আমরা একটি মডেল তৈরি করতে পারি যা সমস্ত প্রিপ্রসেসিং একসাথে করে।

ব্যবহারকারী মডেল

সম্পূর্ণ ব্যবহারকারী মডেল নিম্নলিখিত মত দেখতে পারে:

class UserModel(tf.keras.Model):

  def __init__(self):
    super().__init__()

    self.user_embedding = tf.keras.Sequential([
        user_id_lookup,
        tf.keras.layers.Embedding(user_id_lookup.vocab_size(), 32),
    ])
    self.timestamp_embedding = tf.keras.Sequential([
      tf.keras.layers.Discretization(timestamp_buckets.tolist()),
      tf.keras.layers.Embedding(len(timestamp_buckets) + 2, 32)
    ])
    self.normalized_timestamp = tf.keras.layers.Normalization(
        axis=None
    )

  def call(self, inputs):

    # Take the input dictionary, pass it through each input layer,
    # and concatenate the result.
    return tf.concat([
        self.user_embedding(inputs["user_id"]),
        self.timestamp_embedding(inputs["timestamp"]),
        tf.reshape(self.normalized_timestamp(inputs["timestamp"]), (-1, 1))
    ], axis=1)

আসুন এটি চেষ্টা করে দেখুন:

user_model = UserModel()

user_model.normalized_timestamp.adapt(
    ratings.map(lambda x: x["timestamp"]).batch(128))

for row in ratings.batch(1).take(1):
  print(f"Computed representations: {user_model(row)[0, :3]}")
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
Computed representations: [-0.04705765 -0.04739009 -0.04212048]

সিনেমার মডেল

আমরা সিনেমা মডেলের জন্য একই কাজ করতে পারি:

class MovieModel(tf.keras.Model):

  def __init__(self):
    super().__init__()

    max_tokens = 10_000

    self.title_embedding = tf.keras.Sequential([
      movie_title_lookup,
      tf.keras.layers.Embedding(movie_title_lookup.vocab_size(), 32)
    ])
    self.title_text_embedding = tf.keras.Sequential([
      tf.keras.layers.TextVectorization(max_tokens=max_tokens),
      tf.keras.layers.Embedding(max_tokens, 32, mask_zero=True),
      # We average the embedding of individual words to get one embedding vector
      # per title.
      tf.keras.layers.GlobalAveragePooling1D(),
    ])

  def call(self, inputs):
    return tf.concat([
        self.title_embedding(inputs["movie_title"]),
        self.title_text_embedding(inputs["movie_title"]),
    ], axis=1)

আসুন এটি চেষ্টা করে দেখুন:

movie_model = MovieModel()

movie_model.title_text_embedding.layers[0].adapt(
    ratings.map(lambda x: x["movie_title"]))

for row in ratings.batch(1).take(1):
  print(f"Computed representations: {movie_model(row)[0, :3]}")
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
WARNING:tensorflow:vocab_size is deprecated, please use vocabulary_size.
Computed representations: [-0.01670959  0.02128791  0.04631067]

পরবর্তী পদক্ষেপ

উপরের দুটি মডেলের সাথে আমরা সুপারিশকারী মডেলে সমৃদ্ধ বৈশিষ্ট্যগুলি উপস্থাপন করার জন্য প্রথম পদক্ষেপ নিয়েছি: এটিকে আরও এগিয়ে নিতে এবং কীভাবে এটি একটি কার্যকর গভীর সুপারিশকারী মডেল তৈরি করতে ব্যবহার করা যেতে পারে তা অন্বেষণ করতে, আমাদের গভীর সুপারিশকারী টিউটোরিয়ালটি দেখুন৷