diff --git a/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/architecture.jpg b/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/architecture.jpg new file mode 100644 index 0000000000..05e81acfa3 Binary files /dev/null and b/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/architecture.jpg differ diff --git a/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_13_60.png b/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_13_60.png new file mode 100644 index 0000000000..72409279ad Binary files /dev/null and b/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_13_60.png differ diff --git a/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_9_90.png b/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_9_90.png new file mode 100644 index 0000000000..0fb9ff322f Binary files /dev/null and b/examples/keras_rs/img/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_9_90.png differ diff --git a/examples/keras_rs/ipynb/two_stage_rs_with_marketing_interaction.ipynb b/examples/keras_rs/ipynb/two_stage_rs_with_marketing_interaction.ipynb new file mode 100644 index 0000000000..66c3ce85c0 --- /dev/null +++ b/examples/keras_rs/ipynb/two_stage_rs_with_marketing_interaction.ipynb @@ -0,0 +1,699 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# Two Stage Recommender System with Marketing Interaction\n", + "\n", + "**Author:** Mansi Mehta
\n", + "**Date created:** 26/11/2025
\n", + "**Last modified:** 26/11/2025
\n", + "**Description:** Recommender System with Ranking and Retrival model for Marketing interaction." + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Introduction**\n", + "\n", + "This tutorial demonstrates a critical business scenario: a user lands on a website, and a\n", + "marketing engine must decide which specific ad to display from an inventory of thousands.\n", + "The goal is to maximize the Click-Through Rate (CTR). Showing irrelevant ads wastes\n", + "marketing budget and annoys the user. Therefore, we need a system that predicts the\n", + "probability of a specific user clicking on a specific ad based on their demographics and\n", + "browsing habits.\n", + "\n", + "**Architecture**\n", + "1. **The Retrieval Stage:** Efficiently select an initial set of roughly 10-100\n", + "candidates from millions of possibilities. It weeds out items the user is definitely not\n", + "interested in.\n", + "User Tower: Embeds user features (ID, demographics, behavior) into a vector.\n", + "Item Tower: Embeds ad features (Ad ID, Topic) into a vector.\n", + "Interaction: The dot product of these two vectors represents similarity.\n", + "2. **The Ranking Stage:** It takes the output of the retrieval model and fine-tune the\n", + "order to select the single best ad to show.\n", + "A Deep Neural Network (MLP).\n", + "Interaction: It takes the User Embedding, Ad Embedding, and their similarity score to\n", + "predict a precise probability (0% to 100%) that the user will click.\n", + "\n", + "![jpg](/img/examples/keras_rs/two_stage_rs_with_marketing_interaction/architecture.jpg)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Dataset**\n", + "We will use the [Ad Click\n", + "Prediction](https://www.kaggle.com/datasets/mafrojaakter/ad-click-data) Dataset from\n", + "Kaggle\n", + "\n", + "**Feature Distribution of dataset:**\n", + "User Tower describes who is looking and features contains i.e Gender, City, Country, Age,\n", + "Daily Internet Usage, Daily Time Spent on Site, and Area Income.\n", + "Item Tower describes what is being shown and features contains Ad Topic Line, Ad ID.\n", + "\n", + "In this tutorial, we are going to build and train a Two-Tower (User Tower and Ad Tower)\n", + "model using the Ad Click Prediction dataset from Kaggle.\n", + "We're going to:\n", + "1. **Data Pipeline:** Get our data and preprocess it for both Retrieval (implicit\n", + "feedback) and Ranking (explicit labels).\n", + "2. **Retrieval:** Implement and train a Two-Tower model to generate candidates.\n", + "3. **Ranking:** Implement and train a Neural Ranking model to predict click probabilities.\n", + "4. **Inference:** Run an end-to-end test (Retrieval --> Ranking) to generate\n", + "recommendations for a specific user." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "!!pip install -q keras-rs" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "import os\n", + "\n", + "os.environ[\"KERAS_BACKEND\"] = \"tensorflow\"\n", + "import keras\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import tensorflow as tf\n", + "import pandas as pd\n", + "import keras_rs\n", + "import tensorflow_datasets as tfds\n", + "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", + "from keras import layers\n", + "from concurrent.futures import ThreadPoolExecutor\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Preparing Dataset**" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "!pip install -q kaggle\n", + "!# Download the dataset (requires Kaggle API key in ~/.kaggle/kaggle.json)\n", + "!kaggle datasets download -d mafrojaakter/ad-click-data --unzip -p ./ad_click_dataset" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "data_path = \"./ad_click_dataset/Ad_click_data.csv\"\n", + "if not os.path.exists(data_path):\n", + " # Fallback for filenames with spaces or different casing\n", + " data_path = \"./ad_click_dataset/Ad Click Data.csv\"\n", + "\n", + "ads_df = pd.read_csv(data_path)\n", + "# Clean column names\n", + "ads_df.columns = ads_df.columns.str.strip()\n", + "# Rename the column name\n", + "ads_df = ads_df.rename(\n", + " columns={\n", + " \"Male\": \"gender\",\n", + " \"Ad Topic Line\": \"ad_topic\",\n", + " \"City\": \"city\",\n", + " \"Country\": \"country\",\n", + " \"Daily Time Spent on Site\": \"time_on_site\",\n", + " \"Daily Internet Usage\": \"internet_usage\",\n", + " \"Area Income\": \"area_income\",\n", + " }\n", + ")\n", + "# Add user_id and add_id column\n", + "ads_df[\"user_id\"] = \"user_\" + ads_df.index.astype(str)\n", + "ads_df[\"ad_id\"] = \"ad_\" + ads_df[\"ad_topic\"].astype(\"category\").cat.codes.astype(str)\n", + "# Remove nulls and normalize\n", + "ads_df = ads_df.dropna()\n", + "# normalize\n", + "numeric_cols = [\"time_on_site\", \"internet_usage\", \"area_income\", \"Age\"]\n", + "scaler = MinMaxScaler()\n", + "ads_df[numeric_cols] = scaler.fit_transform(ads_df[numeric_cols])\n", + "\n", + "# Split the train and test datasets\n", + "x_train, x_test = train_test_split(ads_df, test_size=0.2, random_state=42)\n", + "\n", + "\n", + "def dict_to_tensor_features(df_features, continuous_features):\n", + " tensor_dict = {}\n", + " for k, v in df_features.items():\n", + " if k in continuous_features:\n", + " tensor_dict[k] = tf.expand_dims(tf.constant(v, dtype=\"float32\"), axis=-1)\n", + " else:\n", + " v_str = np.array(v).astype(str).tolist()\n", + " tensor_dict[k] = tf.expand_dims(tf.constant(v_str, dtype=\"string\"), axis=-1)\n", + " return tensor_dict\n", + "\n", + "\n", + "def create_retrieval_dataset(\n", + " data_df,\n", + " all_ads_features,\n", + " all_ad_ids,\n", + " user_features_list,\n", + " ad_features_list,\n", + " continuous_features_list,\n", + "):\n", + "\n", + " # Filter for Positive Interactions (Cicks)\n", + " positive_interactions = data_df[data_df[\"Clicked on Ad\"] == 1].copy()\n", + "\n", + " if positive_interactions.empty:\n", + " return None\n", + "\n", + " def sample_negative(positive_ad_id):\n", + " neg_ad_id = positive_ad_id\n", + " while neg_ad_id == positive_ad_id:\n", + " neg_ad_id = np.random.choice(all_ad_ids)\n", + " return neg_ad_id\n", + "\n", + " def create_triplets_row(pos_row):\n", + " pos_ad_id = pos_row.ad_id\n", + " neg_ad_id = sample_negative(pos_ad_id)\n", + "\n", + " neg_ad_row = all_ads_features[all_ads_features[\"ad_id\"] == neg_ad_id].iloc[0]\n", + " user_features_dict = {\n", + " name: getattr(pos_row, name) for name in user_features_list\n", + " }\n", + " pos_ad_features_dict = {\n", + " name: getattr(pos_row, name) for name in ad_features_list\n", + " }\n", + " neg_ad_features_dict = {name: neg_ad_row[name] for name in ad_features_list}\n", + "\n", + " return {\n", + " \"user\": user_features_dict,\n", + " \"positive_ad\": pos_ad_features_dict,\n", + " \"negative_ad\": neg_ad_features_dict,\n", + " }\n", + "\n", + " with ThreadPoolExecutor(max_workers=8) as executor:\n", + " triplets = list(\n", + " executor.map(\n", + " create_triplets_row, positive_interactions.itertuples(index=False)\n", + " )\n", + " )\n", + "\n", + " triplets_df = pd.DataFrame(triplets)\n", + " user_df = triplets_df[\"user\"].apply(pd.Series)\n", + " pos_ad_df = triplets_df[\"positive_ad\"].apply(pd.Series)\n", + " neg_ad_df = triplets_df[\"negative_ad\"].apply(pd.Series)\n", + "\n", + " user_features_tensor = dict_to_tensor_features(\n", + " user_df.to_dict(\"list\"), continuous_features_list\n", + " )\n", + " pos_ad_features_tensor = dict_to_tensor_features(\n", + " pos_ad_df.to_dict(\"list\"), continuous_features_list\n", + " )\n", + " neg_ad_features_tensor = dict_to_tensor_features(\n", + " neg_ad_df.to_dict(\"list\"), continuous_features_list\n", + " )\n", + "\n", + " features = {\n", + " \"user\": user_features_tensor,\n", + " \"positive_ad\": pos_ad_features_tensor,\n", + " \"negative_ad\": neg_ad_features_tensor,\n", + " }\n", + " y_true = tf.ones((triplets_df.shape[0], 1), dtype=tf.float32)\n", + " dataset = tf.data.Dataset.from_tensor_slices((features, y_true))\n", + " buffer_size = len(triplets_df)\n", + " dataset = (\n", + " dataset.shuffle(buffer_size=buffer_size)\n", + " .batch(64)\n", + " .cache()\n", + " .prefetch(tf.data.AUTOTUNE)\n", + " )\n", + " return dataset\n", + "\n", + "\n", + "user_clicked_ads = (\n", + " x_train[x_train[\"Clicked on Ad\"] == 1]\n", + " .groupby(\"user_id\")[\"ad_id\"]\n", + " .apply(set)\n", + " .to_dict()\n", + ")\n", + "\n", + "for u in x_train[\"user_id\"].unique():\n", + " if u not in user_clicked_ads:\n", + " user_clicked_ads[u] = set()\n", + "\n", + "AD_FEATURES = [\"ad_id\", \"ad_topic\"]\n", + "USER_FEATURES = [\n", + " \"user_id\",\n", + " \"gender\",\n", + " \"city\",\n", + " \"country\",\n", + " \"time_on_site\",\n", + " \"internet_usage\",\n", + " \"area_income\",\n", + " \"Age\",\n", + "]\n", + "continuous_features = [\"time_on_site\", \"internet_usage\", \"area_income\", \"Age\"]\n", + "\n", + "all_ads_features = x_train[AD_FEATURES].drop_duplicates().reset_index(drop=True)\n", + "all_ad_ids = all_ads_features[\"ad_id\"].tolist()\n", + "\n", + "retrieval_train_dataset = create_retrieval_dataset(\n", + " data_df=x_train,\n", + " all_ads_features=all_ads_features,\n", + " all_ad_ids=all_ad_ids,\n", + " user_features_list=USER_FEATURES,\n", + " ad_features_list=AD_FEATURES,\n", + " continuous_features_list=continuous_features,\n", + ")\n", + "\n", + "retrieval_test_dataset = create_retrieval_dataset(\n", + " data_df=x_test,\n", + " all_ads_features=all_ads_features,\n", + " all_ad_ids=all_ad_ids,\n", + " user_features_list=USER_FEATURES,\n", + " ad_features_list=AD_FEATURES,\n", + " continuous_features_list=continuous_features,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Implement the Retrival Model**\n", + "For the Retrieval stage, we will build a Two-Tower Model.\n", + "\n", + "**The Architecture Components:**\n", + "\n", + "1. User Tower:User features (User ID, demographics, behavior metrics like time_on_site).\n", + "It encodes these mixed features into a fixed-size vector representation called the User\n", + "Embedding.\n", + "2. Item (Ad) Tower:Ad features (Ad ID, Ad Topic Line).It encodes these features into a\n", + "fixed-size vector representation called the Item Embedding.\n", + "3. Interaction (Similarity):We calculate the Dot Product between the User Embedding and\n", + "the Item Embedding." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "keras.utils.set_random_seed(42)\n", + "\n", + "vocab_map = {\n", + " \"user_id\": x_train[\"user_id\"].unique(),\n", + " \"gender\": x_train[\"gender\"].astype(str).unique(),\n", + " \"city\": x_train[\"city\"].unique(),\n", + " \"country\": x_train[\"country\"].unique(),\n", + " \"ad_id\": x_train[\"ad_id\"].unique(),\n", + " \"ad_topic\": x_train[\"ad_topic\"].unique(),\n", + "}\n", + "cont_feats = [\"time_on_site\", \"internet_usage\", \"area_income\", \"Age\"]\n", + "\n", + "normalizers = {}\n", + "for f in cont_feats:\n", + " norm = layers.Normalization(axis=None)\n", + " norm.adapt(x_train[f].values.astype(\"float32\"))\n", + " normalizers[f] = norm\n", + "\n", + "\n", + "def build_tower(feature_names, continuous_names=None, embed_dim=64, name=\"tower\"):\n", + " inputs, embeddings = {}, []\n", + "\n", + " for feat in feature_names:\n", + " if feat in vocab_map:\n", + " inp = keras.Input(shape=(1,), dtype=tf.string, name=feat)\n", + " inputs[feat] = inp\n", + " vocab = list(vocab_map[feat])\n", + " x = layers.StringLookup(vocabulary=vocab)(inp)\n", + " x = layers.Embedding(\n", + " len(vocab) + 1, embed_dim, embeddings_regularizer=\"l2\"\n", + " )(x)\n", + " embeddings.append(layers.Flatten()(x))\n", + "\n", + " if continuous_names:\n", + " for feat in continuous_names:\n", + " inp = keras.Input(shape=(1,), dtype=tf.float32, name=feat)\n", + " inputs[feat] = inp\n", + " embeddings.append(normalizers[feat](inp))\n", + "\n", + " x = layers.Concatenate()(embeddings)\n", + " x = layers.Dense(128, activation=\"relu\")(x)\n", + " x = layers.Dropout(0.2)(x)\n", + " x = layers.Dense(64, activation=\"relu\")(x)\n", + " output = layers.Dense(embed_dim)(layers.Dropout(0.2)(x))\n", + "\n", + " return keras.Model(inputs=inputs, outputs=output, name=name)\n", + "\n", + "\n", + "user_tower = build_tower(\n", + " [\"user_id\", \"gender\", \"city\", \"country\"], cont_feats, name=\"user_tower\"\n", + ")\n", + "ad_tower = build_tower([\"ad_id\", \"ad_topic\"], name=\"ad_tower\")\n", + "\n", + "\n", + "def bpr_hinge_loss(y_true, y_pred):\n", + " margin = 1.0\n", + " return -tf.math.log(tf.nn.sigmoid(y_pred) + 1e-10)\n", + "\n", + "\n", + "class RetrievalModel(keras.Model):\n", + " def __init__(self, user_tower_instance, ad_tower_instance, **kwargs):\n", + " super().__init__(**kwargs)\n", + " self.user_tower = user_tower\n", + " self.ad_tower = ad_tower\n", + " self.ln_user = layers.LayerNormalization()\n", + " self.ln_ad = layers.LayerNormalization()\n", + "\n", + " def call(self, inputs):\n", + " u_emb = self.ln_user(self.user_tower(inputs[\"user\"]))\n", + " pos_emb = self.ln_ad(self.ad_tower(inputs[\"positive_ad\"]))\n", + " neg_emb = self.ln_ad(self.ad_tower(inputs[\"negative_ad\"]))\n", + " pos_score = keras.ops.sum(u_emb * pos_emb, axis=1, keepdims=True)\n", + " neg_score = keras.ops.sum(u_emb * neg_emb, axis=1, keepdims=True)\n", + " return pos_score - neg_score\n", + "\n", + " def get_embeddings(self, inputs):\n", + " u_emb = self.ln_user(self.user_tower(inputs[\"user\"]))\n", + " ad_emb = self.ln_ad(self.ad_tower(inputs[\"positive_ad\"]))\n", + " dot_interaction = keras.ops.sum(u_emb * ad_emb, axis=1, keepdims=True)\n", + " return u_emb, ad_emb, dot_interaction\n", + "\n", + "\n", + "retrieval_model = RetrievalModel(user_tower, ad_tower)\n", + "retrieval_model.compile(\n", + " optimizer=keras.optimizers.Adam(learning_rate=1e-3), loss=bpr_hinge_loss\n", + ")\n", + "history = retrieval_model.fit(retrieval_train_dataset, epochs=30)\n", + "\n", + "pd.DataFrame(history.history).plot(\n", + " subplots=True, layout=(1, 3), figsize=(12, 4), title=\"Retrival Model Metrics\"\n", + ")\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Predictions of Retrival Model**\n", + "Two-Tower model is trained, we need to use it to generate candidates.\n", + "\n", + "We can implement inference pipeline using three steps:\n", + "1. Indexing: We can run the Item Tower once for all available ads to generate their\n", + "embeddings.\n", + "2. Query Encoding: When a user arrives, we pass their features through the User Tower to\n", + "generate a User Embedding.\n", + "3. Nearest Neighbor Search: We search the index to find the Ad Embeddings closest to the\n", + "User Embedding (highest dot product).\n", + "\n", + "Keras-RS [BruteForceRetrieval\n", + "layer](https://keras.io/keras_rs/api/retrieval_layers/brute_force_retrieval/) calculates\n", + "dot product between the user and every single item in the index to find exact top-K\n", + "matches" + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "USER_CATEGORICAL = [\"user_id\", \"gender\", \"city\", \"country\"]\n", + "CONTINUOUS_FEATURES = [\"time_on_site\", \"internet_usage\", \"area_income\", \"Age\"]\n", + "USER_FEATURES = USER_CATEGORICAL + CONTINUOUS_FEATURES\n", + "\n", + "\n", + "class BruteForceRetrievalWrapper:\n", + " def __init__(self, model, ads_df, ad_features, user_features, k=10):\n", + " self.model, self.k = model, k\n", + " self.user_features = user_features\n", + " unique_ads = ads_df[ad_features].drop_duplicates(\"ad_id\").reset_index(drop=True)\n", + " self.ids = unique_ads[\"ad_id\"].values\n", + " self.topic_map = dict(zip(unique_ads[\"ad_id\"], unique_ads[\"ad_topic\"]))\n", + " ad_inputs = {\n", + " \"ad_id\": tf.constant(self.ids.astype(str)),\n", + " \"ad_topic\": tf.constant(unique_ads[\"ad_topic\"].astype(str).values),\n", + " }\n", + " self.candidate_embs = model.ln_ad(model.ad_tower(ad_inputs))\n", + "\n", + " def query_batch(self, user_df):\n", + " inputs = {\n", + " k: tf.constant(\n", + " user_df[k].values.astype(float if k in CONTINUOUS_FEATURES else str)\n", + " )\n", + " for k in self.user_features\n", + " if k in user_df.columns\n", + " }\n", + " u_emb = self.model.ln_user(self.model.user_tower(inputs))\n", + " scores = tf.linalg.matmul(u_emb, self.candidate_embs, transpose_b=True)\n", + " top_scores, top_indices = tf.math.top_k(scores, k=self.k)\n", + " return top_scores.numpy(), top_indices.numpy()\n", + "\n", + " def decode_results(self, scores, indices):\n", + " results = []\n", + " for row_scores, row_indices in zip(scores, indices):\n", + " retrieved_ids = self.ids[row_indices]\n", + " results.append(\n", + " [\n", + " {\"ad_id\": aid, \"ad_topic\": self.topic_map[aid], \"score\": float(s)}\n", + " for aid, s in zip(retrieved_ids, row_scores)\n", + " ]\n", + " )\n", + " return results\n", + "\n", + "\n", + "retrieval_engine = BruteForceRetrievalWrapper(\n", + " model=retrieval_model,\n", + " ads_df=ads_df,\n", + " ad_features=[\"ad_id\", \"ad_topic\"],\n", + " user_features=USER_FEATURES,\n", + " k=10,\n", + ")\n", + "sample_user = pd.DataFrame([x_test.iloc[0]])\n", + "scores, indices = retrieval_engine.query_batch(sample_user)\n", + "top_ads = retrieval_engine.decode_results(scores, indices)[0]" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Implementation of Ranking Model**\n", + "Retrieval model only calculates a simple similarity score (Dot Product). It doesn't\n", + "account for complex feature interactions.\n", + "So we need to build ranking model after words retrival model.\n", + "\n", + "**Architecture**\n", + "1. **Feature Extraction:** We reuse the trained User Tower and Ad Tower from the\n", + "Retrieval stage. We freeze these towers (trainable = False) so their weights don't\n", + "change.\n", + "2. **Interaction:** Instead of just a dot product, we concatenate three inputs- The User\n", + "EmbeddingThe Ad EmbeddingThe Dot Product (Similarity)\n", + "3. **Scorer(MLP):** These concatenated inputs are fed into a Multi-Layer Perceptron\u2014a\n", + "stack of Dense layers. This network learns the non-linear relationships between the user\n", + "and the ad.\n", + "4. **Output:** The final layer uses a Sigmoid activation to output a single probability\n", + "between 0.0 and 1.0 (Likelihood of a Click)." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "retrieval_model.trainable = False\n", + "\n", + "\n", + "def create_ranking_ds(df):\n", + " inputs = {\n", + " \"user\": dict_to_tensor_features(df[USER_FEATURES], continuous_features),\n", + " \"positive_ad\": dict_to_tensor_features(df[AD_FEATURES], continuous_features),\n", + " }\n", + " return (\n", + " tf.data.Dataset.from_tensor_slices(\n", + " (inputs, df[\"Clicked on Ad\"].values.astype(\"float32\"))\n", + " )\n", + " .shuffle(10000)\n", + " .batch(256)\n", + " .prefetch(tf.data.AUTOTUNE)\n", + " )\n", + "\n", + "\n", + "ranking_train_dataset = create_ranking_ds(x_train)\n", + "ranking_test_dataset = create_ranking_ds(x_test)\n", + "\n", + "\n", + "class RankingModel(keras.Model):\n", + " def __init__(self, retrieval_model, **kwargs):\n", + " super().__init__(**kwargs)\n", + " self.retrieval = retrieval_model\n", + " self.mlp = keras.Sequential(\n", + " [\n", + " layers.Dense(256, activation=\"relu\"),\n", + " layers.Dropout(0.2),\n", + " layers.Dense(128, activation=\"relu\"),\n", + " layers.Dropout(0.2),\n", + " layers.Dense(64, activation=\"relu\"),\n", + " layers.Dense(1, activation=\"sigmoid\"),\n", + " ]\n", + " )\n", + "\n", + " def call(self, inputs):\n", + " u_emb, ad_emb, dot = self.retrieval.get_embeddings(inputs)\n", + " return self.mlp(keras.ops.concatenate([u_emb, ad_emb, dot], axis=-1))\n", + "\n", + "\n", + "ranking_model = RankingModel(retrieval_model)\n", + "ranking_model.compile(\n", + " optimizer=keras.optimizers.Adam(1e-4),\n", + " loss=\"binary_crossentropy\",\n", + " metrics=[\"AUC\", \"accuracy\"],\n", + ")\n", + "history1 = ranking_model.fit(ranking_train_dataset, epochs=20)\n", + "\n", + "pd.DataFrame(history1.history).plot(\n", + " subplots=True, layout=(1, 3), figsize=(12, 4), title=\"Ranking Model Metrics\"\n", + ")\n", + "plt.show()\n", + "\n", + "ranking_model.evaluate(ranking_test_dataset)" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "colab_type": "text" + }, + "source": [ + "# **Predictions of Ranking Model**\n", + "The retrieval model gave us a list of ads that are generally relevant (high dot product\n", + "similarity). The ranking model will now calculate the specific probability (0% to 100%)\n", + "that the user will click each of those ads.\n", + "\n", + "The Ranking model expects pairs of (User, Ad). Since we are scoring 10 ads for 1 user, we\n", + "cannot just pass the user features once.We effectively take user's features 10 times to\n", + "create a batch." + ] + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": { + "colab_type": "code" + }, + "outputs": [], + "source": [ + "\n", + "def rerank_ads_for_user(user_row, retrieved_ads, ranking_model):\n", + " ads_df = pd.DataFrame(retrieved_ads)\n", + " num_ads = len(ads_df)\n", + " user_inputs = {\n", + " k: tf.fill(\n", + " (num_ads, 1),\n", + " str(user_row[k]) if k not in continuous_features else float(user_row[k]),\n", + " )\n", + " for k in USER_FEATURES\n", + " }\n", + " ad_inputs = {\n", + " k: tf.reshape(tf.constant(ads_df[k].astype(str).values), (-1, 1))\n", + " for k in AD_FEATURES\n", + " }\n", + " scores = (\n", + " ranking_model({\"user\": user_inputs, \"positive_ad\": ad_inputs}).numpy().flatten()\n", + " )\n", + " ads_df[\"ranking_score\"] = scores\n", + " return ads_df.sort_values(\"ranking_score\", ascending=False).to_dict(\"records\")\n", + "\n", + "\n", + "sample_user = x_test.iloc[0]\n", + "scores, indices = retrieval_engine.query_batch(pd.DataFrame([sample_user]))\n", + "top_ads = retrieval_engine.decode_results(scores, indices)[0]\n", + "final_ranked_ads = rerank_ads_for_user(sample_user, top_ads, ranking_model)\n", + "print(f\"User: {sample_user['user_id']}\")\n", + "print(f\"{'Ad ID':<10} | {'Topic':<30} | {'Retrival Score':<11} | {'Rank Probability'}\")\n", + "for item in final_ranked_ads:\n", + " print(\n", + " f\"{item['ad_id']:<10} | {item['ad_topic'][:28]:<30} | {item['score']:.4f} |{item['ranking_score']*100:.2f}%\"\n", + " )" + ] + } + ], + "metadata": { + "accelerator": "GPU", + "colab": { + "collapsed_sections": [], + "name": "two_stage_rs_with_marketing_interaction", + "private_outputs": false, + "provenance": [], + "toc_visible": true + }, + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.7.0" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} \ No newline at end of file diff --git a/examples/keras_rs/md/two_stage_rs_with_marketing_interaction.md b/examples/keras_rs/md/two_stage_rs_with_marketing_interaction.md new file mode 100644 index 0000000000..87c31267c8 --- /dev/null +++ b/examples/keras_rs/md/two_stage_rs_with_marketing_interaction.md @@ -0,0 +1,836 @@ +# Two Stage Recommender System with Marketing Interaction + +**Author:** Mansi Mehta
+**Date created:** 26/11/2025
+**Last modified:** 26/11/2025
+**Description:** Recommender System with Ranking and Retrival model for Marketing interaction. + + + [**View in Colab**](https://colab.research.google.com/github/keras-team/keras-io/blob/master/examples/keras_rs/ipynb/two_stage_rs_with_marketing_interaction.ipynb) [**GitHub source**](https://github.com/keras-team/keras-io/blob/master/examples/keras_rs/two_stage_rs_with_marketing_interaction.py) + + + +# **Introduction** + +This tutorial demonstrates a critical business scenario: a user lands on a website, and a +marketing engine must decide which specific ad to display from an inventory of thousands. +The goal is to maximize the Click-Through Rate (CTR). Showing irrelevant ads wastes +marketing budget and annoys the user. Therefore, we need a system that predicts the +probability of a specific user clicking on a specific ad based on their demographics and +browsing habits. + +**Architecture** +1. **The Retrieval Stage:** Efficiently select an initial set of roughly 10-100 +candidates from millions of possibilities. It weeds out items the user is definitely not +interested in. +User Tower: Embeds user features (ID, demographics, behavior) into a vector. +Item Tower: Embeds ad features (Ad ID, Topic) into a vector. +Interaction: The dot product of these two vectors represents similarity. +2. **The Ranking Stage:** It takes the output of the retrieval model and fine-tune the +order to select the single best ad to show. +A Deep Neural Network (MLP). +Interaction: It takes the User Embedding, Ad Embedding, and their similarity score to +predict a precise probability (0% to 100%) that the user will click. + +![jpg](/img/examples/keras_rs/two_stage_rs_with_marketing_interaction/architecture.jpg) + +# **Dataset** +We will use the [Ad Click +Prediction](https://www.kaggle.com/datasets/mafrojaakter/ad-click-data) Dataset from +Kaggle + +**Feature Distribution of dataset:** +User Tower describes who is looking and features contains i.e Gender, City, Country, Age, +Daily Internet Usage, Daily Time Spent on Site, and Area Income. +Item Tower describes what is being shown and features contains Ad Topic Line, Ad ID. + +In this tutorial, we are going to build and train a Two-Tower (User Tower and Ad Tower) +model using the Ad Click Prediction dataset from Kaggle. +We're going to: +1. **Data Pipeline:** Get our data and preprocess it for both Retrieval (implicit +feedback) and Ranking (explicit labels). +2. **Retrieval:** Implement and train a Two-Tower model to generate candidates. +3. **Ranking:** Implement and train a Neural Ranking model to predict click probabilities. +4. **Inference:** Run an end-to-end test (Retrieval --> Ranking) to generate +recommendations for a specific user. + + +```python +!!pip install -q keras-rs +``` + + + +```python +import os + +os.environ["KERAS_BACKEND"] = "tensorflow" +import keras +import matplotlib.pyplot as plt +import numpy as np +import tensorflow as tf +import pandas as pd +import keras_rs +import tensorflow_datasets as tfds +from mpl_toolkits.axes_grid1 import make_axes_locatable +from keras import layers +from concurrent.futures import ThreadPoolExecutor +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import MinMaxScaler + +``` +
+``` +['', + '\x1b[1m[\x1b[0m\x1b[34;49mnotice\x1b[0m\x1b[1;39;49m]\x1b[0m\x1b[39;49m A new release of pip is available: \x1b[0m\x1b[31;49m23.2.1\x1b[0m\x1b[39;49m -> \x1b[0m\x1b[32;49m25.3\x1b[0m', + '\x1b[1m[\x1b[0m\x1b[34;49mnotice\x1b[0m\x1b[1;39;49m]\x1b[0m\x1b[39;49m To update, run: \x1b[0m\x1b[32;49mpip install --upgrade pip\x1b[0m'] +``` +
+ +# **Preparing Dataset** + + +```python +!pip install -q kaggle +!# Download the dataset (requires Kaggle API key in ~/.kaggle/kaggle.json) +!kaggle datasets download -d mafrojaakter/ad-click-data --unzip -p ./ad_click_dataset +``` + + +
+``` +[notice] To update, run: pip install --upgrade pip + +Dataset URL: https://www.kaggle.com/datasets/mafrojaakter/ad-click-data +License(s): unknown + +Downloading ad-click-data.zip to ./ad_click_dataset +``` +
+ + 0%| | 0.00/37.6k [00:00 +``` +Epoch 1/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 2s 2ms/step - loss: 2.8117 + +Epoch 2/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 1.3631 + +Epoch 3/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 1.0918 + +Epoch 4/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.9143 + +Epoch 5/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.7872 + +Epoch 6/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.6925 + +Epoch 7/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.6203 + +Epoch 8/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.5641 + +Epoch 9/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.5190 + +Epoch 10/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.4817 + +Epoch 11/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.4499 + +Epoch 12/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.4220 + +Epoch 13/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 8ms/step - loss: 0.3970 + +Epoch 14/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 6ms/step - loss: 0.3743 + +Epoch 15/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.3537 + +Epoch 16/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 2ms/step - loss: 0.3346 + +Epoch 17/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.3171 + +Epoch 18/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.3009 + +Epoch 19/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2858 + +Epoch 20/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2718 + +Epoch 21/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2587 + +Epoch 22/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2465 + +Epoch 23/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2350 + +Epoch 24/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2243 + +Epoch 25/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2142 + +Epoch 26/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.2046 + +Epoch 27/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.1956 + +Epoch 28/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.1871 + +Epoch 29/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.1791 + +Epoch 30/30 + +6/6 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - loss: 0.1715 +``` + + +![png](/img/examples/keras_rs/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_9_90.png) + + + +# **Predictions of Retrival Model** +Two-Tower model is trained, we need to use it to generate candidates. + +We can implement inference pipeline using three steps: +1. Indexing: We can run the Item Tower once for all available ads to generate their +embeddings. +2. Query Encoding: When a user arrives, we pass their features through the User Tower to +generate a User Embedding. +3. Nearest Neighbor Search: We search the index to find the Ad Embeddings closest to the +User Embedding (highest dot product). + +Keras-RS [BruteForceRetrieval +layer](https://keras.io/keras_rs/api/retrieval_layers/brute_force_retrieval/) calculates +dot product between the user and every single item in the index to find exact top-K +matches + + +```python +USER_CATEGORICAL = ["user_id", "gender", "city", "country"] +CONTINUOUS_FEATURES = ["time_on_site", "internet_usage", "area_income", "Age"] +USER_FEATURES = USER_CATEGORICAL + CONTINUOUS_FEATURES + + +class BruteForceRetrievalWrapper: + def __init__(self, model, ads_df, ad_features, user_features, k=10): + self.model, self.k = model, k + self.user_features = user_features + unique_ads = ads_df[ad_features].drop_duplicates("ad_id").reset_index(drop=True) + self.ids = unique_ads["ad_id"].values + self.topic_map = dict(zip(unique_ads["ad_id"], unique_ads["ad_topic"])) + ad_inputs = { + "ad_id": tf.constant(self.ids.astype(str)), + "ad_topic": tf.constant(unique_ads["ad_topic"].astype(str).values), + } + self.candidate_embs = model.ln_ad(model.ad_tower(ad_inputs)) + + def query_batch(self, user_df): + inputs = { + k: tf.constant( + user_df[k].values.astype(float if k in CONTINUOUS_FEATURES else str) + ) + for k in self.user_features + if k in user_df.columns + } + u_emb = self.model.ln_user(self.model.user_tower(inputs)) + scores = tf.linalg.matmul(u_emb, self.candidate_embs, transpose_b=True) + top_scores, top_indices = tf.math.top_k(scores, k=self.k) + return top_scores.numpy(), top_indices.numpy() + + def decode_results(self, scores, indices): + results = [] + for row_scores, row_indices in zip(scores, indices): + retrieved_ids = self.ids[row_indices] + results.append( + [ + {"ad_id": aid, "ad_topic": self.topic_map[aid], "score": float(s)} + for aid, s in zip(retrieved_ids, row_scores) + ] + ) + return results + + +retrieval_engine = BruteForceRetrievalWrapper( + model=retrieval_model, + ads_df=ads_df, + ad_features=["ad_id", "ad_topic"], + user_features=USER_FEATURES, + k=10, +) +sample_user = pd.DataFrame([x_test.iloc[0]]) +scores, indices = retrieval_engine.query_batch(sample_user) +top_ads = retrieval_engine.decode_results(scores, indices)[0] +``` + +# **Implementation of Ranking Model** +Retrieval model only calculates a simple similarity score (Dot Product). It doesn't +account for complex feature interactions. +So we need to build ranking model after words retrival model. + +**Architecture** +1. **Feature Extraction:** We reuse the trained User Tower and Ad Tower from the +Retrieval stage. We freeze these towers (trainable = False) so their weights don't +change. +2. **Interaction:** Instead of just a dot product, we concatenate three inputs- The User +EmbeddingThe Ad EmbeddingThe Dot Product (Similarity) +3. **Scorer(MLP):** These concatenated inputs are fed into a Multi-Layer Perceptron—a +stack of Dense layers. This network learns the non-linear relationships between the user +and the ad. +4. **Output:** The final layer uses a Sigmoid activation to output a single probability +between 0.0 and 1.0 (Likelihood of a Click). + + +```python +retrieval_model.trainable = False + + +def create_ranking_ds(df): + inputs = { + "user": dict_to_tensor_features(df[USER_FEATURES], continuous_features), + "positive_ad": dict_to_tensor_features(df[AD_FEATURES], continuous_features), + } + return ( + tf.data.Dataset.from_tensor_slices( + (inputs, df["Clicked on Ad"].values.astype("float32")) + ) + .shuffle(10000) + .batch(256) + .prefetch(tf.data.AUTOTUNE) + ) + + +ranking_train_dataset = create_ranking_ds(x_train) +ranking_test_dataset = create_ranking_ds(x_test) + + +class RankingModel(keras.Model): + def __init__(self, retrieval_model, **kwargs): + super().__init__(**kwargs) + self.retrieval = retrieval_model + self.mlp = keras.Sequential( + [ + layers.Dense(256, activation="relu"), + layers.Dropout(0.2), + layers.Dense(128, activation="relu"), + layers.Dropout(0.2), + layers.Dense(64, activation="relu"), + layers.Dense(1, activation="sigmoid"), + ] + ) + + def call(self, inputs): + u_emb, ad_emb, dot = self.retrieval.get_embeddings(inputs) + return self.mlp(keras.ops.concatenate([u_emb, ad_emb, dot], axis=-1)) + + +ranking_model = RankingModel(retrieval_model) +ranking_model.compile( + optimizer=keras.optimizers.Adam(1e-4), + loss="binary_crossentropy", + metrics=["AUC", "accuracy"], +) +history1 = ranking_model.fit(ranking_train_dataset, epochs=20) + +pd.DataFrame(history1.history).plot( + subplots=True, layout=(1, 3), figsize=(12, 4), title="Ranking Model Metrics" +) +plt.show() + +ranking_model.evaluate(ranking_test_dataset) +``` + +
+``` +Epoch 1/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 1s 5ms/step - AUC: 0.6079 - accuracy: 0.4961 - loss: 0.6890 + +Epoch 2/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.8329 - accuracy: 0.5748 - loss: 0.6423 + +Epoch 3/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 5ms/step - AUC: 0.9284 - accuracy: 0.7467 - loss: 0.5995 + +Epoch 4/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9636 - accuracy: 0.8766 - loss: 0.5599 + +Epoch 5/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - AUC: 0.9763 - accuracy: 0.9213 - loss: 0.5229 + +Epoch 6/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9824 - accuracy: 0.9304 - loss: 0.4876 + +Epoch 7/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9862 - accuracy: 0.9331 - loss: 0.4540 + +Epoch 8/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - AUC: 0.9880 - accuracy: 0.9357 - loss: 0.4224 + +Epoch 9/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9898 - accuracy: 0.9436 - loss: 0.3920 + +Epoch 10/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9911 - accuracy: 0.9475 - loss: 0.3633 + +Epoch 11/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - AUC: 0.9914 - accuracy: 0.9528 - loss: 0.3361 + +Epoch 12/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - AUC: 0.9923 - accuracy: 0.9580 - loss: 0.3103 + +Epoch 13/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9925 - accuracy: 0.9619 - loss: 0.2866 + +Epoch 14/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9931 - accuracy: 0.9633 - loss: 0.2643 + +Epoch 15/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9935 - accuracy: 0.9633 - loss: 0.2436 + +Epoch 16/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9938 - accuracy: 0.9659 - loss: 0.2247 + +Epoch 17/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9942 - accuracy: 0.9646 - loss: 0.2076 + +Epoch 18/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 3ms/step - AUC: 0.9945 - accuracy: 0.9659 - loss: 0.1918 + +Epoch 19/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9947 - accuracy: 0.9672 - loss: 0.1777 + +Epoch 20/20 + +3/3 ━━━━━━━━━━━━━━━━━━━━ 0s 4ms/step - AUC: 0.9953 - accuracy: 0.9685 - loss: 0.1645 +``` +
+ +![png](/img/examples/keras_rs/two_stage_rs_with_marketing_interaction/two_stage_rs_with_marketing_interaction_13_60.png) + + + + +
+``` +1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 230ms/step - AUC: 0.9904 - accuracy: 0.9476 - loss: 0.2319 + +[0.2318607121706009, 0.9903508424758911, 0.9476439952850342] +``` +
+ +# **Predictions of Ranking Model** +The retrieval model gave us a list of ads that are generally relevant (high dot product +similarity). The ranking model will now calculate the specific probability (0% to 100%) +that the user will click each of those ads. + +The Ranking model expects pairs of (User, Ad). Since we are scoring 10 ads for 1 user, we +cannot just pass the user features once.We effectively take user's features 10 times to +create a batch. + + +```python + +def rerank_ads_for_user(user_row, retrieved_ads, ranking_model): + ads_df = pd.DataFrame(retrieved_ads) + num_ads = len(ads_df) + user_inputs = { + k: tf.fill( + (num_ads, 1), + str(user_row[k]) if k not in continuous_features else float(user_row[k]), + ) + for k in USER_FEATURES + } + ad_inputs = { + k: tf.reshape(tf.constant(ads_df[k].astype(str).values), (-1, 1)) + for k in AD_FEATURES + } + scores = ( + ranking_model({"user": user_inputs, "positive_ad": ad_inputs}).numpy().flatten() + ) + ads_df["ranking_score"] = scores + return ads_df.sort_values("ranking_score", ascending=False).to_dict("records") + + +sample_user = x_test.iloc[0] +scores, indices = retrieval_engine.query_batch(pd.DataFrame([sample_user])) +top_ads = retrieval_engine.decode_results(scores, indices)[0] +final_ranked_ads = rerank_ads_for_user(sample_user, top_ads, ranking_model) +print(f"User: {sample_user['user_id']}") +print(f"{'Ad ID':<10} | {'Topic':<30} | {'Retrival Score':<11} | {'Rank Probability'}") +for item in final_ranked_ads: + print( + f"{item['ad_id']:<10} | {item['ad_topic'][:28]:<30} | {item['score']:.4f} |{item['ranking_score']*100:.2f}%" + ) +``` + +
+``` +User: user_216 +Ad ID | Topic | Retrival Score | Rank Probability +ad_305 | Front-line fault-tolerant in | 8.2131 |99.27% +ad_318 | Front-line upward-trending g | 7.6231 |99.17% +ad_758 | Right-sized multi-tasking so | 7.1814 |99.06% +ad_767 | Robust object-oriented Graph | 7.2068 |99.02% +ad_620 | Polarized modular function | 7.2857 |98.92% +ad_522 | Open-architected full-range | 7.0892 |98.82% +ad_771 | Robust web-enabled attitude | 7.3828 |98.81% +ad_810 | Sharable optimal capacity | 6.7046 |98.69% +ad_31 | Ameliorated well-modulated c | 6.9498 |98.40% +ad_104 | Configurable 24/7 hub | 6.7244 |98.39% +``` +
diff --git a/examples/keras_rs/two_stage_rs_with_marketing_interaction.py b/examples/keras_rs/two_stage_rs_with_marketing_interaction.py new file mode 100644 index 0000000000..b2c1e572ca --- /dev/null +++ b/examples/keras_rs/two_stage_rs_with_marketing_interaction.py @@ -0,0 +1,556 @@ +""" +Title: Two Stage Recommender System with Marketing Interaction +Author: Mansi Mehta +Date created: 26/11/2025 +Last modified: 26/11/2025 +Description: Recommender System with Ranking and Retrival model for Marketing interaction. +Accelerator: GPU +""" + +""" +# **Introduction** + +This tutorial demonstrates a critical business scenario: a user lands on a website, and a +marketing engine must decide which specific ad to display from an inventory of thousands. +The goal is to maximize the Click-Through Rate (CTR). Showing irrelevant ads wastes +marketing budget and annoys the user. Therefore, we need a system that predicts the +probability of a specific user clicking on a specific ad based on their demographics and +browsing habits. + +**Architecture** +1. **The Retrieval Stage:** Efficiently select an initial set of roughly 10-100 +candidates from millions of possibilities. It weeds out items the user is definitely not +interested in. +User Tower: Embeds user features (ID, demographics, behavior) into a vector. +Item Tower: Embeds ad features (Ad ID, Topic) into a vector. +Interaction: The dot product of these two vectors represents similarity. +2. **The Ranking Stage:** It takes the output of the retrieval model and fine-tune the +order to select the single best ad to show. +A Deep Neural Network (MLP). +Interaction: It takes the User Embedding, Ad Embedding, and their similarity score to +predict a precise probability (0% to 100%) that the user will click. + +![jpg](/img/examples/keras_rs/two_stage_rs_with_marketing_interaction/architecture.jpg) +""" + +""" +# **Dataset** +We will use the [Ad Click +Prediction](https://www.kaggle.com/datasets/mafrojaakter/ad-click-data) Dataset from +Kaggle + +**Feature Distribution of dataset:** +User Tower describes who is looking and features contains i.e Gender, City, Country, Age, +Daily Internet Usage, Daily Time Spent on Site, and Area Income. +Item Tower describes what is being shown and features contains Ad Topic Line, Ad ID. + +In this tutorial, we are going to build and train a Two-Tower (User Tower and Ad Tower) +model using the Ad Click Prediction dataset from Kaggle. +We're going to: +1. **Data Pipeline:** Get our data and preprocess it for both Retrieval (implicit +feedback) and Ranking (explicit labels). +2. **Retrieval:** Implement and train a Two-Tower model to generate candidates. +3. **Ranking:** Implement and train a Neural Ranking model to predict click probabilities. +4. **Inference:** Run an end-to-end test (Retrieval --> Ranking) to generate +recommendations for a specific user. +""" + +"""shell +!pip install -q keras-rs +""" + +import os + +os.environ["KERAS_BACKEND"] = "tensorflow" +import keras +import matplotlib.pyplot as plt +import numpy as np +import tensorflow as tf +import pandas as pd +import keras_rs +import tensorflow_datasets as tfds +from mpl_toolkits.axes_grid1 import make_axes_locatable +from keras import layers +from concurrent.futures import ThreadPoolExecutor +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import MinMaxScaler + + +""" +# **Preparing Dataset** +""" + +"""shell +pip install -q kaggle +# Download the dataset (requires Kaggle API key in ~/.kaggle/kaggle.json) +kaggle datasets download -d mafrojaakter/ad-click-data --unzip -p ./ad_click_dataset +""" +data_path = "./ad_click_dataset/Ad_click_data.csv" +if not os.path.exists(data_path): + # Fallback for filenames with spaces or different casing + data_path = "./ad_click_dataset/Ad Click Data.csv" + +ads_df = pd.read_csv(data_path) +# Clean column names +ads_df.columns = ads_df.columns.str.strip() +# Rename the column name +ads_df = ads_df.rename( + columns={ + "Male": "gender", + "Ad Topic Line": "ad_topic", + "City": "city", + "Country": "country", + "Daily Time Spent on Site": "time_on_site", + "Daily Internet Usage": "internet_usage", + "Area Income": "area_income", + } +) +# Add user_id and add_id column +ads_df["user_id"] = "user_" + ads_df.index.astype(str) +ads_df["ad_id"] = "ad_" + ads_df["ad_topic"].astype("category").cat.codes.astype(str) +# Remove nulls and normalize +ads_df = ads_df.dropna() +# normalize +numeric_cols = ["time_on_site", "internet_usage", "area_income", "Age"] +scaler = MinMaxScaler() +ads_df[numeric_cols] = scaler.fit_transform(ads_df[numeric_cols]) + +# Split the train and test datasets +x_train, x_test = train_test_split(ads_df, test_size=0.2, random_state=42) + + +def dict_to_tensor_features(df_features, continuous_features): + tensor_dict = {} + for k, v in df_features.items(): + if k in continuous_features: + tensor_dict[k] = tf.expand_dims(tf.constant(v, dtype="float32"), axis=-1) + else: + v_str = np.array(v).astype(str).tolist() + tensor_dict[k] = tf.expand_dims(tf.constant(v_str, dtype="string"), axis=-1) + return tensor_dict + + +def create_retrieval_dataset( + data_df, + all_ads_features, + all_ad_ids, + user_features_list, + ad_features_list, + continuous_features_list, +): + + # Filter for Positive Interactions (Cicks) + positive_interactions = data_df[data_df["Clicked on Ad"] == 1].copy() + + if positive_interactions.empty: + return None + + def sample_negative(positive_ad_id): + neg_ad_id = positive_ad_id + while neg_ad_id == positive_ad_id: + neg_ad_id = np.random.choice(all_ad_ids) + return neg_ad_id + + def create_triplets_row(pos_row): + pos_ad_id = pos_row.ad_id + neg_ad_id = sample_negative(pos_ad_id) + + neg_ad_row = all_ads_features[all_ads_features["ad_id"] == neg_ad_id].iloc[0] + user_features_dict = { + name: getattr(pos_row, name) for name in user_features_list + } + pos_ad_features_dict = { + name: getattr(pos_row, name) for name in ad_features_list + } + neg_ad_features_dict = {name: neg_ad_row[name] for name in ad_features_list} + + return { + "user": user_features_dict, + "positive_ad": pos_ad_features_dict, + "negative_ad": neg_ad_features_dict, + } + + with ThreadPoolExecutor(max_workers=8) as executor: + triplets = list( + executor.map( + create_triplets_row, positive_interactions.itertuples(index=False) + ) + ) + + triplets_df = pd.DataFrame(triplets) + user_df = triplets_df["user"].apply(pd.Series) + pos_ad_df = triplets_df["positive_ad"].apply(pd.Series) + neg_ad_df = triplets_df["negative_ad"].apply(pd.Series) + + user_features_tensor = dict_to_tensor_features( + user_df.to_dict("list"), continuous_features_list + ) + pos_ad_features_tensor = dict_to_tensor_features( + pos_ad_df.to_dict("list"), continuous_features_list + ) + neg_ad_features_tensor = dict_to_tensor_features( + neg_ad_df.to_dict("list"), continuous_features_list + ) + + features = { + "user": user_features_tensor, + "positive_ad": pos_ad_features_tensor, + "negative_ad": neg_ad_features_tensor, + } + y_true = tf.ones((triplets_df.shape[0], 1), dtype=tf.float32) + dataset = tf.data.Dataset.from_tensor_slices((features, y_true)) + buffer_size = len(triplets_df) + dataset = ( + dataset.shuffle(buffer_size=buffer_size) + .batch(64) + .cache() + .prefetch(tf.data.AUTOTUNE) + ) + return dataset + + +user_clicked_ads = ( + x_train[x_train["Clicked on Ad"] == 1] + .groupby("user_id")["ad_id"] + .apply(set) + .to_dict() +) + +for u in x_train["user_id"].unique(): + if u not in user_clicked_ads: + user_clicked_ads[u] = set() + +AD_FEATURES = ["ad_id", "ad_topic"] +USER_FEATURES = [ + "user_id", + "gender", + "city", + "country", + "time_on_site", + "internet_usage", + "area_income", + "Age", +] +continuous_features = ["time_on_site", "internet_usage", "area_income", "Age"] + +all_ads_features = x_train[AD_FEATURES].drop_duplicates().reset_index(drop=True) +all_ad_ids = all_ads_features["ad_id"].tolist() + +retrieval_train_dataset = create_retrieval_dataset( + data_df=x_train, + all_ads_features=all_ads_features, + all_ad_ids=all_ad_ids, + user_features_list=USER_FEATURES, + ad_features_list=AD_FEATURES, + continuous_features_list=continuous_features, +) + +retrieval_test_dataset = create_retrieval_dataset( + data_df=x_test, + all_ads_features=all_ads_features, + all_ad_ids=all_ad_ids, + user_features_list=USER_FEATURES, + ad_features_list=AD_FEATURES, + continuous_features_list=continuous_features, +) + +""" +# **Implement the Retrival Model** +For the Retrieval stage, we will build a Two-Tower Model. + +**The Architecture Components:** + +1. User Tower:User features (User ID, demographics, behavior metrics like time_on_site). +It encodes these mixed features into a fixed-size vector representation called the User +Embedding. +2. Item (Ad) Tower:Ad features (Ad ID, Ad Topic Line).It encodes these features into a +fixed-size vector representation called the Item Embedding. +3. Interaction (Similarity):We calculate the Dot Product between the User Embedding and +the Item Embedding. +""" + +keras.utils.set_random_seed(42) + +vocab_map = { + "user_id": x_train["user_id"].unique(), + "gender": x_train["gender"].astype(str).unique(), + "city": x_train["city"].unique(), + "country": x_train["country"].unique(), + "ad_id": x_train["ad_id"].unique(), + "ad_topic": x_train["ad_topic"].unique(), +} +cont_feats = ["time_on_site", "internet_usage", "area_income", "Age"] + +normalizers = {} +for f in cont_feats: + norm = layers.Normalization(axis=None) + norm.adapt(x_train[f].values.astype("float32")) + normalizers[f] = norm + + +def build_tower(feature_names, continuous_names=None, embed_dim=64, name="tower"): + inputs, embeddings = {}, [] + + for feat in feature_names: + if feat in vocab_map: + inp = keras.Input(shape=(1,), dtype=tf.string, name=feat) + inputs[feat] = inp + vocab = list(vocab_map[feat]) + x = layers.StringLookup(vocabulary=vocab)(inp) + x = layers.Embedding( + len(vocab) + 1, embed_dim, embeddings_regularizer="l2" + )(x) + embeddings.append(layers.Flatten()(x)) + + if continuous_names: + for feat in continuous_names: + inp = keras.Input(shape=(1,), dtype=tf.float32, name=feat) + inputs[feat] = inp + embeddings.append(normalizers[feat](inp)) + + x = layers.Concatenate()(embeddings) + x = layers.Dense(128, activation="relu")(x) + x = layers.Dropout(0.2)(x) + x = layers.Dense(64, activation="relu")(x) + output = layers.Dense(embed_dim)(layers.Dropout(0.2)(x)) + + return keras.Model(inputs=inputs, outputs=output, name=name) + + +user_tower = build_tower( + ["user_id", "gender", "city", "country"], cont_feats, name="user_tower" +) +ad_tower = build_tower(["ad_id", "ad_topic"], name="ad_tower") + + +def bpr_hinge_loss(y_true, y_pred): + margin = 1.0 + return -tf.math.log(tf.nn.sigmoid(y_pred) + 1e-10) + + +class RetrievalModel(keras.Model): + def __init__(self, user_tower_instance, ad_tower_instance, **kwargs): + super().__init__(**kwargs) + self.user_tower = user_tower + self.ad_tower = ad_tower + self.ln_user = layers.LayerNormalization() + self.ln_ad = layers.LayerNormalization() + + def call(self, inputs): + u_emb = self.ln_user(self.user_tower(inputs["user"])) + pos_emb = self.ln_ad(self.ad_tower(inputs["positive_ad"])) + neg_emb = self.ln_ad(self.ad_tower(inputs["negative_ad"])) + pos_score = keras.ops.sum(u_emb * pos_emb, axis=1, keepdims=True) + neg_score = keras.ops.sum(u_emb * neg_emb, axis=1, keepdims=True) + return pos_score - neg_score + + def get_embeddings(self, inputs): + u_emb = self.ln_user(self.user_tower(inputs["user"])) + ad_emb = self.ln_ad(self.ad_tower(inputs["positive_ad"])) + dot_interaction = keras.ops.sum(u_emb * ad_emb, axis=1, keepdims=True) + return u_emb, ad_emb, dot_interaction + + +retrieval_model = RetrievalModel(user_tower, ad_tower) +retrieval_model.compile( + optimizer=keras.optimizers.Adam(learning_rate=1e-3), loss=bpr_hinge_loss +) +history = retrieval_model.fit(retrieval_train_dataset, epochs=30) + +pd.DataFrame(history.history).plot( + subplots=True, layout=(1, 3), figsize=(12, 4), title="Retrival Model Metrics" +) +plt.show() + +""" +# **Predictions of Retrival Model** +Two-Tower model is trained, we need to use it to generate candidates. + +We can implement inference pipeline using three steps: +1. Indexing: We can run the Item Tower once for all available ads to generate their +embeddings. +2. Query Encoding: When a user arrives, we pass their features through the User Tower to +generate a User Embedding. +3. Nearest Neighbor Search: We search the index to find the Ad Embeddings closest to the +User Embedding (highest dot product). + +Keras-RS [BruteForceRetrieval +layer](https://keras.io/keras_rs/api/retrieval_layers/brute_force_retrieval/) calculates +dot product between the user and every single item in the index to find exact top-K +matches +""" + +USER_CATEGORICAL = ["user_id", "gender", "city", "country"] +CONTINUOUS_FEATURES = ["time_on_site", "internet_usage", "area_income", "Age"] +USER_FEATURES = USER_CATEGORICAL + CONTINUOUS_FEATURES + + +class BruteForceRetrievalWrapper: + def __init__(self, model, ads_df, ad_features, user_features, k=10): + self.model, self.k = model, k + self.user_features = user_features + unique_ads = ads_df[ad_features].drop_duplicates("ad_id").reset_index(drop=True) + self.ids = unique_ads["ad_id"].values + self.topic_map = dict(zip(unique_ads["ad_id"], unique_ads["ad_topic"])) + ad_inputs = { + "ad_id": tf.constant(self.ids.astype(str)), + "ad_topic": tf.constant(unique_ads["ad_topic"].astype(str).values), + } + self.candidate_embs = model.ln_ad(model.ad_tower(ad_inputs)) + + def query_batch(self, user_df): + inputs = { + k: tf.constant( + user_df[k].values.astype(float if k in CONTINUOUS_FEATURES else str) + ) + for k in self.user_features + if k in user_df.columns + } + u_emb = self.model.ln_user(self.model.user_tower(inputs)) + scores = tf.linalg.matmul(u_emb, self.candidate_embs, transpose_b=True) + top_scores, top_indices = tf.math.top_k(scores, k=self.k) + return top_scores.numpy(), top_indices.numpy() + + def decode_results(self, scores, indices): + results = [] + for row_scores, row_indices in zip(scores, indices): + retrieved_ids = self.ids[row_indices] + results.append( + [ + {"ad_id": aid, "ad_topic": self.topic_map[aid], "score": float(s)} + for aid, s in zip(retrieved_ids, row_scores) + ] + ) + return results + + +retrieval_engine = BruteForceRetrievalWrapper( + model=retrieval_model, + ads_df=ads_df, + ad_features=["ad_id", "ad_topic"], + user_features=USER_FEATURES, + k=10, +) +sample_user = pd.DataFrame([x_test.iloc[0]]) +scores, indices = retrieval_engine.query_batch(sample_user) +top_ads = retrieval_engine.decode_results(scores, indices)[0] + +""" +# **Implementation of Ranking Model** +Retrieval model only calculates a simple similarity score (Dot Product). It doesn't +account for complex feature interactions. +So we need to build ranking model after words retrival model. + +**Architecture** +1. **Feature Extraction:** We reuse the trained User Tower and Ad Tower from the +Retrieval stage. We freeze these towers (trainable = False) so their weights don't +change. +2. **Interaction:** Instead of just a dot product, we concatenate three inputs- The User +EmbeddingThe Ad EmbeddingThe Dot Product (Similarity) +3. **Scorer(MLP):** These concatenated inputs are fed into a Multi-Layer Perceptron—a +stack of Dense layers. This network learns the non-linear relationships between the user +and the ad. +4. **Output:** The final layer uses a Sigmoid activation to output a single probability +between 0.0 and 1.0 (Likelihood of a Click). +""" + +retrieval_model.trainable = False + + +def create_ranking_ds(df): + inputs = { + "user": dict_to_tensor_features(df[USER_FEATURES], continuous_features), + "positive_ad": dict_to_tensor_features(df[AD_FEATURES], continuous_features), + } + return ( + tf.data.Dataset.from_tensor_slices( + (inputs, df["Clicked on Ad"].values.astype("float32")) + ) + .shuffle(10000) + .batch(256) + .prefetch(tf.data.AUTOTUNE) + ) + + +ranking_train_dataset = create_ranking_ds(x_train) +ranking_test_dataset = create_ranking_ds(x_test) + + +class RankingModel(keras.Model): + def __init__(self, retrieval_model, **kwargs): + super().__init__(**kwargs) + self.retrieval = retrieval_model + self.mlp = keras.Sequential( + [ + layers.Dense(256, activation="relu"), + layers.Dropout(0.2), + layers.Dense(128, activation="relu"), + layers.Dropout(0.2), + layers.Dense(64, activation="relu"), + layers.Dense(1, activation="sigmoid"), + ] + ) + + def call(self, inputs): + u_emb, ad_emb, dot = self.retrieval.get_embeddings(inputs) + return self.mlp(keras.ops.concatenate([u_emb, ad_emb, dot], axis=-1)) + + +ranking_model = RankingModel(retrieval_model) +ranking_model.compile( + optimizer=keras.optimizers.Adam(1e-4), + loss="binary_crossentropy", + metrics=["AUC", "accuracy"], +) +history1 = ranking_model.fit(ranking_train_dataset, epochs=20) + +pd.DataFrame(history1.history).plot( + subplots=True, layout=(1, 3), figsize=(12, 4), title="Ranking Model Metrics" +) +plt.show() + +ranking_model.evaluate(ranking_test_dataset) + +""" +# **Predictions of Ranking Model** +The retrieval model gave us a list of ads that are generally relevant (high dot product +similarity). The ranking model will now calculate the specific probability (0% to 100%) +that the user will click each of those ads. + +The Ranking model expects pairs of (User, Ad). Since we are scoring 10 ads for 1 user, we +cannot just pass the user features once.We effectively take user's features 10 times to +create a batch. +""" + + +def rerank_ads_for_user(user_row, retrieved_ads, ranking_model): + ads_df = pd.DataFrame(retrieved_ads) + num_ads = len(ads_df) + user_inputs = { + k: tf.fill( + (num_ads, 1), + str(user_row[k]) if k not in continuous_features else float(user_row[k]), + ) + for k in USER_FEATURES + } + ad_inputs = { + k: tf.reshape(tf.constant(ads_df[k].astype(str).values), (-1, 1)) + for k in AD_FEATURES + } + scores = ( + ranking_model({"user": user_inputs, "positive_ad": ad_inputs}).numpy().flatten() + ) + ads_df["ranking_score"] = scores + return ads_df.sort_values("ranking_score", ascending=False).to_dict("records") + + +sample_user = x_test.iloc[0] +scores, indices = retrieval_engine.query_batch(pd.DataFrame([sample_user])) +top_ads = retrieval_engine.decode_results(scores, indices)[0] +final_ranked_ads = rerank_ads_for_user(sample_user, top_ads, ranking_model) +print(f"User: {sample_user['user_id']}") +print(f"{'Ad ID':<10} | {'Topic':<30} | {'Retrival Score':<11} | {'Rank Probability'}") +for item in final_ranked_ads: + print( + f"{item['ad_id']:<10} | {item['ad_topic'][:28]:<30} | {item['score']:.4f} |{item['ranking_score']*100:.2f}%" + ) diff --git a/two_stage_rs_with_marketing_interaction.ipynb b/two_stage_rs_with_marketing_interaction.ipynb new file mode 100644 index 0000000000..cb1843b016 --- /dev/null +++ b/two_stage_rs_with_marketing_interaction.ipynb @@ -0,0 +1,1126 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + } + }, + "cells": [ + { + "cell_type": "markdown", + "source": [ + "# **Introduction**\n", + "\n", + "This tutorial demonstrates a critical business scenario: a user lands on a website, and a marketing engine must decide which specific ad to display from an inventory of thousands.\n", + "The goal is to maximize the Click-Through Rate (CTR). Showing irrelevant ads wastes marketing budget and annoys the user. Therefore, we need a system that predicts the probability of a specific user clicking on a specific ad based on their demographics and browsing habits.\n", + "\n", + "**Architecture**\n", + "1. **The Retrieval Stage:** Efficiently select an initial set of roughly 10-100 candidates from millions of possibilities. It weeds out items the user is definitely not interested in.\n", + "User Tower: Embeds user features (ID, demographics, behavior) into a vector.\n", + "Item Tower: Embeds ad features (Ad ID, Topic) into a vector.\n", + "Interaction: The dot product of these two vectors represents similarity.\n", + "2. **The Ranking Stage:** It takes the output of the retrieval model and fine-tune the order to select the single best ad to show.\n", + "A Deep Neural Network (MLP).\n", + "Interaction: It takes the User Embedding, Ad Embedding, and their similarity score to predict a precise probability (0% to 100%) that the user will click.\n", + "\n", + "![marketing_usecase.jpg](data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/4QBoRXhpZgAASUkqAAgAAAACADEBAgAHAAAAJgAAAGmHBAABAAAALgAAAAAAAABQaWNhc2EAAAIAAJAHAAQAAAAwMjIwA5ACABQAAABMAAAAAAAAADIwMjU6MTE6MjQgMTU6MDE6NTYA/+EDH2h0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8APD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczpJcHRjNHhtcEV4dD0iaHR0cDovL2lwdGMub3JnL3N0ZC9JcHRjNHhtcEV4dC8yMDA4LTAyLTI5LyIgZXhpZjpEYXRlVGltZU9yaWdpbmFsPSIyMDI1LTExLTI0VDE1OjAxOjU2KzAwOjAwIiBwaG90b3Nob3A6Q3JlZGl0PSJNYWRlIHdpdGggR29vZ2xlIEFJIiBwaG90b3Nob3A6RGF0ZUNyZWF0ZWQ9IjIwMjUtMTEtMjRUMTU6MDE6NTYrMDA6MDAiIElwdGM0eG1wRXh0OkRpZ2l0YWxTb3VyY2VmaWxlVHlwZT0iaHR0cDovL2N2LmlwdGMub3JnL25ld3Njb2Rlcy9kaWdpdGFsc291cmNldHlwZS90cmFpbmVkQWxnb3JpdGhtaWNNZWRpYSIgSXB0YzR4bXBFeHQ6RGlnaXRhbFNvdXJjZVR5cGU9Imh0dHA6Ly9jdi5pcHRjLm9yZy9uZXdzY29kZXMvZGlnaXRhbHNvdXJjZXR5cGUvdHJhaW5lZEFsZ29yaXRobWljTWVkaWEiLz4gPC9yZGY6UkRGPiA8L3g6eG1w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)" + ], + "metadata": { + "id": "y5jO6Y78Vf-N" + } + }, + { + "cell_type": "markdown", + "source": [ + "# **Dataset**\n", + "We will use the [Ad Click Prediction](https://www.kaggle.com/datasets/mafrojaakter/ad-click-data) Dataset from Kaggle\n", + "\n", + "**Feature Distribution of dataset:**\n", + "User Tower describes who is looking and features contains i.e Gender, City, Country, Age, Daily Internet Usage, Daily Time Spent on Site, and Area Income.\n", + "Item Tower describes what is being shown and features contains Ad Topic Line, Ad ID.\n", + "\n", + "In this tutorial, we are going to build and train a Two-Tower (User Tower and Ad Tower) model using the Ad Click Prediction dataset from Kaggle.\n", + "We're going to:\n", + "1. **Data Pipeline:** Get our data and preprocess it for both Retrieval (implicit feedback) and Ranking (explicit labels).\n", + "2. **Retrieval:** Implement and train a Two-Tower model to generate candidates.\n", + "3. **Ranking:** Implement and train a Neural Ranking model to predict click probabilities.\n", + "4. **Inference:** Run an end-to-end test (Retrieval --> Ranking) to generate recommendations for a specific user." + ], + "metadata": { + "id": "xcJBUXmeaavN" + } + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "id": "AL5vdFd8QOZl", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "8b519c48-1e1a-4e58-9325-6108cfb7b4da" + }, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[?25l \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m0.0/92.5 kB\u001b[0m \u001b[31m?\u001b[0m eta \u001b[36m-:--:--\u001b[0m\r\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m92.5/92.5 kB\u001b[0m \u001b[31m2.8 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n", + "\u001b[?25h" + ] + } + ], + "source": [ + "!pip install -q keras-rs" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "id": "2cdPdsiFQOZm" + }, + "outputs": [], + "source": [ + "import os\n", + "os.environ[\"KERAS_BACKEND\"] = \"tensorflow\"\n", + "import keras\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import tensorflow as tf\n", + "import pandas as pd\n", + "import keras_rs\n", + "import tensorflow_datasets as tfds\n", + "from mpl_toolkits.axes_grid1 import make_axes_locatable\n", + "from keras import layers\n", + "from concurrent.futures import ThreadPoolExecutor\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.preprocessing import MinMaxScaler\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "source": [ + "# **Preparing Dataset**" + ], + "metadata": { + "id": "fdhb5tuL9UBe" + } + }, + { + "cell_type": "code", + "source": [ + "from google.colab import files\n", + "files.upload()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 91 + }, + "id": "RJN16Th-9W8E", + "outputId": "bfa060e0-25fe-41a4-cddd-b46aea023352" + }, + "execution_count": 3, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "" + ], + "text/html": [ + "\n", + " \n", + " \n", + " Upload widget is only available when the cell has been executed in the\n", + " current browser session. Please rerun this cell to enable.\n", + " \n", + " " + ] + }, + "metadata": {} + }, + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Saving kaggle (1).json to kaggle (1).json\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "{'kaggle (1).json': b'{\"username\":\"mansim071\",\"key\":\"7b9249c264ac5cb7d295afcdd44f7ad1\"}'}" + ] + }, + "metadata": {}, + "execution_count": 3 + } + ] + }, + { + "cell_type": "code", + "source": [ + "!mkdir -p ~/.kaggle\n", + "!mv kaggle.json ~/.kaggle/\n", + "!chmod 600 ~/.kaggle/kaggle.json" + ], + "metadata": { + "id": "G4JgdNRp9tI3" + }, + "execution_count": 4, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "!kaggle datasets download -d mafrojaakter/ad-click-data\n", + "!unzip -o ad-click-data.zip -d ./ad_click_data" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "NOhaq3bl-bmp", + "outputId": "bcd54c95-28dc-42b5-8f82-39f8763db18a" + }, + "execution_count": 5, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Dataset URL: https://www.kaggle.com/datasets/mafrojaakter/ad-click-data\n", + "License(s): unknown\n", + "Downloading ad-click-data.zip to /content\n", + " 0% 0.00/37.6k [00:00" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlIAAAGHCAYAAAB7xLxyAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAPERJREFUeJzt3Xl8VPW9//H3ZJtsk4RA9gQIiywii0EQUEShUgQKVhGhLajAdYlaBGvL7UWtyy/1WitVcUGvcKtFEBH1oojIKgVURFRAEJAlQHbITPaEzPn9ETISSYBMZjLJzOv5eJxHMmfOmfOZEx7Ht9/v93yPyTAMQwAAAGg0P08XAAAA0FoRpAAAAJxEkAIAAHASQQoAAMBJBCkAAAAnEaQAAACcRJACAABwEkEKAADASQQpAAAAJxGkAACtXseOHXXbbbe57fM3bNggk8mkDRs2uO0YTWUymfToo482er/Dhw/LZDJp0aJFLq+pOXj6b0OQAgA4ZdGiRTKZTI4lICBASUlJuu2223T8+HGnPnPPnj169NFHdfjwYdcW20zOPiebN28+533DMJSSkiKTyaQxY8Z4oELn1QYWk8mkN998s95thgwZIpPJpF69ejl1jMWLF2vevHlNqLL5BXi6AABA6/bYY48pNTVV5eXl2rZtmxYtWqTNmzdr165dCg4ObtRn7dmzR3/5y180bNgwdezY8aL327dvn/z8Wk7bQHBwsBYvXqyrrrqqzvqNGzfq2LFjMpvNHqqs6Wq/229/+9s66w8fPqwtW7Y0+m9+tsWLF2vXrl2aOXPmRe8zdOhQlZWVKSgoyOnjNkXL+VcHAGiVRo0apd/+9reaPn26XnvtNT344IM6ePCgPvjgA7ce1zAMlZWVSZLMZrMCAwPderzGuOGGG7Rs2TKdPn26zvrFixcrLS1N8fHxHqqs6W644QatWbNG+fn5ddYvXrxYcXFx6t+/f7PUUV5eLrvdLj8/PwUHB3ssSBOkAAAudfXVV0uSDh48WGf93r17dfPNNys6OlrBwcHq379/nbC1aNEiTZgwQZJ07bXXOrqRase+dOzYUWPGjNHq1avVv39/hYSE6JVXXnG8VztGavv27TKZTPrf//3fc2pbvXq1TCaTVq5cKUk6cuSI7rnnHnXr1k0hISFq27atJkyY0OSuxUmTJqmgoEBr1qxxrKusrNQ777yjyZMn17tPSUmJZs+erZSUFJnNZnXr1k1/+9vfZBhGne0qKir0wAMPKCYmRhaLRb/61a907Nixej/z+PHjuuOOOxQXFyez2axLL71Ur7/+epO+27hx42Q2m7Vs2bI66xcvXqxbbrlF/v7+9e735ptvKi0tTSEhIYqOjtatt96qzMxMx/vDhg3Thx9+qCNHjjj+9rWtkrXdikuWLNF//dd/KSkpSaGhobLZbA2Okfr88891ww03qE2bNgoLC1Pv3r31j3/8w/F+dna2br/9diUnJ8tsNishIUHjxo1r9N+erj0AgEvV/oeoTZs2jnW7d+/WkCFDlJSUpD/96U8KCwvT22+/rfHjx2v58uW68cYbNXToUN1///167rnn9J//+Z/q0aOHJDl+SjVdeJMmTdKdd96pGTNmqFu3buccv3///urUqZPefvttTZ06tc57S5cuVZs2bTRy5EhJ0pdffqktW7bo1ltvVXJysg4fPqyXXnpJw4YN0549exQaGurUOejYsaMGDRqkt956S6NGjZIkrVq1SlarVbfeequee+65OtsbhqFf/epXWr9+vaZNm6a+fftq9erV+sMf/qDjx4/r2WefdWw7ffp0vfnmm5o8ebIGDx6sdevWafTo0efUkJOToyuvvFImk0n33nuvYmJitGrVKk2bNk02m61R3WdnCw0N1bhx4/TWW2/p7rvvliR988032r17t1577TV9++235+zz5JNPau7cubrllls0ffp05eXl6fnnn9fQoUP19ddfKyoqSn/+859ltVp17Ngxx/cNDw+v8zmPP/64goKC9OCDD6qioqLB7rw1a9ZozJgxSkhI0O9//3vFx8fr+++/18qVK/X73/9eknTTTTdp9+7duu+++9SxY0fl5uZqzZo1Onr0aKO6lWUAAOCEhQsXGpKMTz/91MjLyzMyMzONd955x4iJiTHMZrORmZnp2Hb48OHGZZddZpSXlzvW2e12Y/DgwUbXrl0d65YtW2ZIMtavX3/O8Tp06GBIMj7++ON635s6darj9Zw5c4zAwEDj5MmTjnUVFRVGVFSUcccddzjWlZaWnvNZW7duNSQZ//znPx3r1q9f32Bd9Z2TL7/80njhhRcMi8XiOMaECROMa6+91lHv6NGjHfu99957hiTjiSeeqPN5N998s2EymYwDBw4YhmEYO3fuNCQZ99xzT53tJk+ebEgyHnnkEce6adOmGQkJCUZ+fn6dbW+99VYjMjLSUdehQ4cMScbChQvP+91qz8GyZcuMlStXGiaTyTh69KhhGIbxhz/8wejUqZNhGIZxzTXXGJdeeqljv8OHDxv+/v7Gk08+WefzvvvuOyMgIKDO+tGjRxsdOnRo8NidOnU652/287/N6dOnjdTUVKNDhw7GqVOn6mxrt9sNwzCMU6dOGZKMp59++rzf+WLQtQcAaJIRI0YoJiZGKSkpuvnmmxUWFqYPPvhAycnJkqSTJ09q3bp1uuWWW1RUVKT8/Hzl5+eroKBAI0eO1P79+y/6Lr/U1FRHa9L5TJw4UVVVVXr33Xcd6z755BMVFhZq4sSJjnUhISGO36uqqlRQUKAuXbooKipKO3bsuNhTUK9bbrlFZWVlWrlypYqKirRy5coGu/U++ugj+fv76/7776+zfvbs2TIMQ6tWrXJsJ+mc7X7eumQYhpYvX66xY8fKMAzHOc/Pz9fIkSNltVqb9P2uv/56RUdHa8mSJTIMQ0uWLNGkSZPq3fbdd9+V3W7XLbfcUqeO+Ph4de3aVevXr7/o406dOrXO36w+X3/9tQ4dOqSZM2cqKiqqznsmk0lSzd89KChIGzZs0KlTpy76+PWhaw8A0CTz58/XJZdcIqvVqtdff12bNm2qc1fagQMHZBiG5s6dq7lz59b7Gbm5uUpKSrrgsVJTUy+qpj59+qh79+5aunSppk2bJqmmW69du3a67rrrHNuVlZUpIyNDCxcu1PHjx+uMR7JarRd1rIbExMRoxIgRWrx4sUpLS1VdXa2bb7653m2PHDmixMREWSyWOutruzWPHDni+Onn56fOnTvX2e7nXZx5eXkqLCzUggULtGDBgnqPmZub69T3kqTAwEBNmDBBixcv1oABA5SZmdlgSNy/f78Mw1DXrl0b/KyLdTF//9qxeeebgsFsNuupp57S7NmzFRcXpyuvvFJjxozRlClTGn0jAEEKANAkAwYMcNypNX78eF111VWaPHmy9u3bp/DwcNntdknSgw8+2GBrUpcuXS7qWBdqjTjbxIkT9eSTTyo/P18Wi0UffPCBJk2apICAn/7Td99992nhwoWaOXOmBg0apMjISJlMJt16662Oupti8uTJmjFjhrKzszVq1KhzWkjcpbb23/72t+eME6vVu3fvJh1j8uTJevnll/Xoo4+qT58+6tmzZ4O1mEwmrVq1qt6B6D8fB3U+jfn7X8jMmTM1duxYvffee1q9erXmzp2rjIwMrVu3Tv369bvozyFIAQBcxt/fXxkZGbr22mv1wgsv6E9/+pM6deokqablYcSIEefdv7brxRUmTpyov/zlL1q+fLni4uJks9l066231tnmnXfe0dSpU/XMM8841pWXl6uwsNAlNdx444268847tW3bNi1durTB7Tp06KBPP/1URUVFdVql9u7d63i/9qfdbtfBgwfrtELt27evzufV3tFXXV19wXPurKuuukrt27fXhg0b9NRTTzW4XefOnWUYhlJTU3XJJZec9zNd8fevba3btWvXBb97586dNXv2bM2ePVv79+9X37599cwzzzQ44Wh9GCMFAHCpYcOGacCAAZo3b57Ky8sVGxurYcOG6ZVXXlFWVtY52+fl5Tl+DwsLkySXBJkePXrosssu09KlS7V06VIlJCRo6NChdbbx9/c/Z3qB559/XtXV1U0+vlTT2vLSSy/p0Ucf1dixYxvc7oYbblB1dbVeeOGFOuufffZZmUwmx51/tT9/ftffz2cD9/f310033aTly5dr165d5xzv7HPuLJPJpOeee06PPPKIfve73zW43a9//Wv5+/vrL3/5yznn2jAMFRQUOF6HhYU1uUv18ssvV2pqqubNm3fOv6Pa45eWlqq8vLzOe507d5bFYlFFRUWjjkeLFADA5f7whz9owoQJWrRoke666y7Nnz9fV111lS677DLNmDFDnTp1Uk5OjrZu3apjx47pm2++kST17dtX/v7+euqpp2S1WmU2m3XdddcpNjbWqTomTpyohx9+WMHBwZo2bdo5kzaOGTNGb7zxhiIjI9WzZ09t3bpVn376qdq2bdvkc1Croa61s40dO1bXXnut/vznP+vw4cPq06ePPvnkE73//vuaOXOmo5Wlb9++mjRpkl588UVZrVYNHjxYa9eu1YEDB875zL/+9a9av369Bg4cqBkzZqhnz546efKkduzYoU8//VQnT55s8ncbN26cxo0bd95tOnfurCeeeEJz5szR4cOHNX78eFksFh06dEgrVqzQf/zHf+jBBx+UJKWlpWnp0qWaNWuWrrjiCoWHh583gNbHz89PL730ksaOHau+ffvq9ttvV0JCgvbu3avdu3dr9erV+uGHHzR8+HDdcsst6tmzpwIC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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# **Predictions of Retrival Model**\n", + "Two-Tower model is trained, we need to use it to generate candidates.\n", + "\n", + "We can implement inference pipeline using three steps:\n", + "1. Indexing: We can run the Item Tower once for all available ads to generate their embeddings.\n", + "2. Query Encoding: When a user arrives, we pass their features through the User Tower to generate a User Embedding.\n", + "3. Nearest Neighbor Search: We search the index to find the Ad Embeddings closest to the User Embedding (highest dot product).\n", + "\n", + "Keras-RS [BruteForceRetrieval layer](https://keras.io/keras_rs/api/retrieval_layers/brute_force_retrieval/) calculates dot product between the user and every single item in the index to find exact top-K matches" + ], + "metadata": { + "id": "_o0ILppGcknp" + } + }, + { + "cell_type": "code", + "source": [ + "USER_CATEGORICAL = [\"user_id\", \"gender\", \"city\", \"country\"]\n", + "CONTINUOUS_FEATURES = [\"time_on_site\", \"internet_usage\", \"area_income\", \"Age\"]\n", + "USER_FEATURES = USER_CATEGORICAL + CONTINUOUS_FEATURES\n", + "\n", + "class BruteForceRetrievalWrapper:\n", + " def __init__(self, model, ads_df, ad_features, user_features, k=10):\n", + " self.model, self.k = model, k\n", + " self.user_features = user_features\n", + " unique_ads = ads_df[ad_features].drop_duplicates(\"ad_id\").reset_index(drop=True)\n", + " self.ids = unique_ads[\"ad_id\"].values\n", + " self.topic_map = dict(zip(unique_ads[\"ad_id\"], unique_ads[\"ad_topic\"]))\n", + " ad_inputs = {\"ad_id\": tf.constant(self.ids.astype(str)),\n", + " \"ad_topic\": tf.constant(unique_ads[\"ad_topic\"].astype(str).values)\n", + " }\n", + " self.candidate_embs = model.ln_ad(model.ad_tower(ad_inputs))\n", + "\n", + " def query_batch(self, user_df):\n", + " inputs = {k: tf.constant(user_df[k].values.astype(float if k in CONTINUOUS_FEATURES else str))\n", + " for k in self.user_features if k in user_df.columns\n", + " }\n", + " u_emb = self.model.ln_user(self.model.user_tower(inputs))\n", + " scores = tf.linalg.matmul(u_emb, self.candidate_embs, transpose_b=True)\n", + " top_scores, top_indices = tf.math.top_k(scores, k=self.k)\n", + " return top_scores.numpy(), top_indices.numpy()\n", + "\n", + " def decode_results(self, scores, indices):\n", + " results = []\n", + " for row_scores, row_indices in zip(scores, indices):\n", + " retrieved_ids = self.ids[row_indices]\n", + " results.append([\n", + " {\"ad_id\": aid, \"ad_topic\": self.topic_map[aid], \"score\": float(s)}\n", + " for aid, s in zip(retrieved_ids, row_scores)\n", + " ])\n", + " return results\n", + "\n", + "retrieval_engine = BruteForceRetrievalWrapper(model=retrieval_model,ads_df=ads_df,ad_features=[\"ad_id\", \"ad_topic\"],\n", + " user_features=USER_FEATURES, k=10)\n", + "sample_user = pd.DataFrame([x_test.iloc[0]])\n", + "scores, indices = retrieval_engine.query_batch(sample_user)\n", + "top_ads = retrieval_engine.decode_results(scores, indices)[0]" + ], + "metadata": { + "id": "QrHPBLIml8Si" + }, + "execution_count": 51, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "# **Implementation of Ranking Model**\n", + "Retrieval model only calculates a simple similarity score (Dot Product). It doesn't account for complex feature interactions.\n", + "So we need to build ranking model after words retrival model.\n", + "\n", + "**Architecture**\n", + "1. **Feature Extraction:** We reuse the trained User Tower and Ad Tower from the Retrieval stage. We freeze these towers (trainable = False) so their weights don't change.\n", + "2. **Interaction:** Instead of just a dot product, we concatenate three inputs- The User EmbeddingThe Ad EmbeddingThe Dot Product (Similarity)\n", + "3. **Scorer(MLP):** These concatenated inputs are fed into a Multi-Layer Perceptron—a stack of Dense layers. This network learns the non-linear relationships between the user and the ad.\n", + "4. **Output:** The final layer uses a Sigmoid activation to output a single probability between 0.0 and 1.0 (Likelihood of a Click)." + ], + "metadata": { + "id": "xQtLgCfyeqYS" + } + }, + { + "cell_type": "code", + "source": [ + "retrieval_model.trainable = False\n", + "def create_ranking_ds(df):\n", + " inputs = {\"user\": dict_to_tensor_features(df[USER_FEATURES], continuous_features),\n", + " \"positive_ad\": dict_to_tensor_features(df[AD_FEATURES], continuous_features)\n", + " }\n", + " return tf.data.Dataset.from_tensor_slices((inputs, df[\"Clicked on Ad\"].values.\n", + " astype('float32'))).shuffle(10000).batch(256).prefetch(tf.data.AUTOTUNE)" + ], + "metadata": { + "id": "_j2PAllRvDOb" + }, + "execution_count": 39, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "ranking_train_dataset= create_ranking_ds(x_train)\n", + "ranking_test_dataset = create_ranking_ds(x_test)" + ], + "metadata": { + "id": "uhKCsNa8v0Uo" + }, + "execution_count": 40, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "class RankingModel(keras.Model):\n", + " def __init__(self, retrieval_model, **kwargs):\n", + " super().__init__(**kwargs)\n", + " self.retrieval = retrieval_model\n", + " self.mlp = keras.Sequential([\n", + " layers.Dense(256, activation=\"relu\"), layers.Dropout(0.2),\n", + " layers.Dense(128, activation=\"relu\"), layers.Dropout(0.2),\n", + " layers.Dense(64, activation=\"relu\"),\n", + " layers.Dense(1, activation=\"sigmoid\")\n", + " ])\n", + "\n", + " def call(self, inputs):\n", + " u_emb, ad_emb, dot = self.retrieval.get_embeddings(inputs)\n", + " return self.mlp(keras.ops.concatenate([u_emb, ad_emb, dot], axis=-1))" + ], + "metadata": { + "id": "mQCXdFFqvDRC" + }, + "execution_count": 41, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "ranking_model = RankingModel(retrieval_model)\n", + "ranking_model.compile(optimizer=keras.optimizers.Adam(1e-4), loss=\"binary_crossentropy\", metrics=[\"AUC\", \"accuracy\"])\n", + "history1 = ranking_model.fit(ranking_train_dataset, epochs=20)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "w5JPRvJ_vDUS", + "outputId": "cdc8c321-8722-48a9-f6e3-8516c9f5caa1" + }, + "execution_count": 42, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch 1/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m6s\u001b[0m 75ms/step - AUC: 0.7137 - accuracy: 0.4999 - loss: 0.6688\n", + "Epoch 2/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 43ms/step - AUC: 0.8871 - accuracy: 0.6535 - loss: 0.6237\n", + "Epoch 3/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 51ms/step - AUC: 0.9528 - accuracy: 0.8104 - loss: 0.5837\n", + "Epoch 4/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 27ms/step - AUC: 0.9704 - accuracy: 0.8531 - loss: 0.5561 \n", + "Epoch 5/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 23ms/step - AUC: 0.9826 - accuracy: 0.9023 - loss: 0.5173\n", + "Epoch 6/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 47ms/step - AUC: 0.9875 - accuracy: 0.9188 - loss: 0.4851\n", + "Epoch 7/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 58ms/step - AUC: 0.9866 - accuracy: 0.9337 - loss: 0.4533\n", + "Epoch 8/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 29ms/step - AUC: 0.9914 - accuracy: 0.9448 - loss: 0.4224 \n", + "Epoch 9/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 23ms/step - AUC: 0.9903 - accuracy: 0.9441 - loss: 0.3910\n", + "Epoch 10/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 40ms/step - AUC: 0.9910 - accuracy: 0.9502 - loss: 0.3671\n", + "Epoch 11/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 20ms/step - AUC: 0.9938 - accuracy: 0.9616 - loss: 0.3386\n", + "Epoch 12/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 22ms/step - AUC: 0.9922 - accuracy: 0.9628 - loss: 0.3158\n", + "Epoch 13/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 22ms/step - AUC: 0.9940 - accuracy: 0.9676 - loss: 0.2864\n", + "Epoch 14/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 24ms/step - AUC: 0.9948 - accuracy: 0.9657 - loss: 0.2607\n", + "Epoch 15/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 14ms/step - AUC: 0.9951 - accuracy: 0.9685 - loss: 0.2452\n", + "Epoch 16/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - AUC: 0.9943 - accuracy: 0.9689 - loss: 0.2243\n", + "Epoch 17/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - AUC: 0.9945 - accuracy: 0.9701 - loss: 0.2068\n", + "Epoch 18/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 13ms/step - AUC: 0.9942 - accuracy: 0.9682 - loss: 0.1947\n", + "Epoch 19/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 12ms/step - AUC: 0.9955 - accuracy: 0.9719 - loss: 0.1764\n", + "Epoch 20/20\n", + "\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m0s\u001b[0m 15ms/step - AUC: 0.9943 - accuracy: 0.9725 - loss: 0.1623\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [ + "pd.DataFrame(history1.history).plot(subplots=True, layout=(1, 3), figsize=(12, 4), title=\"Ranking Model Metrics\")\n", + "plt.show()" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/", + "height": 408 + }, + "id": "WoodoIYnFgsx", + "outputId": "ee8c8243-6c85-4831-f44a-167d1ecf7b06" + }, + "execution_count": 43, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA94AAAGHCAYAAABGc4o9AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAh+xJREFUeJzs3Xt8zvX/x/HHdV3btZMdzGZzGHM+syJLiGq1kEonhwr74vtLKVm+scKkpBPpoFYiOn3TwbcTkRaViCIkEjkfNmOzsdnpuq7fH7OLZdj5s8Pzfrt9bte1z/U5PK8LH3td7/fn/TY5HA4HIiIiIiIiIlIuzEYHEBEREREREanOVHiLiIiIiIiIlCMV3iIiIiIiIiLlSIW3iIiIiIiISDlS4S0iIiIiIiJSjlR4i4iIiIiIiJQjFd4iIiIiIiIi5UiFt4iIiIiIiEg5UuEtIiIiIiIiUo5UeIuISLUzfPhwatWqdcntevfuTe/evcs/UCUydepUTCZTifYdPnw4oaGhZRuoAtXEP28REakcVHiLiEiZW7BgASaTybm4uLjQoEEDhg8fzqFDh4yOVymEhoZiMpmIiIgo9PW5c+c6P79ff/21gtOVTu/evTGZTLRo0aLQ11esWOF8b5988kmxj3/48GGmTp3Kpk2bSplURESkYrgYHUBERKqvadOm0aRJEzIzM/n5559ZsGABq1evZuvWrbi7uxsdj2+++cbQ87u7u7Ny5UoSEhIIDg4u8Nr777+Pu7s7mZmZBqUrHXd3d3bt2sX69evp2rVrgddK+94OHz7ME088QWhoKGFhYUXez+g/bxERqbnU4i0iIuWmT58+3HPPPYwcOZK33nqL8ePH8/fff/PFF18YHQ0Aq9WK1Wo17Pzdu3enVq1aLFq0qMD6gwcP8uOPP9KvXz+DkpVes2bNaNWqFf/9738LrM/MzOR///tfhb63jIwMwPg/bxERqblUeIuISIXp2bMnAH///bdzXXZ2NlOmTKFz5874+vri5eVFz549WblyZYF99+7di8lk4oUXXuDNN9+kWbNmuLm5ccUVV/DLL79c8tybNm0iMDCQ3r17c+rUKeD8e35XrVqFyWTio48+Yvr06TRs2BB3d3euu+46du3add4x58yZQ9OmTfHw8KBr1678+OOPxbqP2N3dndtuu40PPvigwPr//ve/1K5dm8jIyEL3++677+jZsydeXl74+flxyy23sH379vO2W716NVdccQXu7u40a9aMN95444JZ3nvvPTp37oyHhwf+/v4MGjSIAwcOFOl9XMjgwYNZtGgRdrvdue7LL78kIyODu+66q9B9Dh06xL/+9S+CgoJwc3OjXbt2zJ8/3/n6qlWruOKKKwCIiopydllfsGABkPdn2r59ezZs2MDVV1+Np6cnjz32mPO1f/7ZZGZmMnXqVFq2bIm7uzv16tXjtttuK/B39MMPP6Rz5854e3vj4+NDhw4deOmll0r12YiISM2iruYiIlJh9u7dC0Dt2rWd69LS0njrrbcYPHgwo0aN4uTJk8ybN4/IyEjWr19/XlfiDz74gJMnT/J///d/mEwmnnvuOW677TZ2796Nq6troef95ZdfiIyMpEuXLnz++ed4eHhcNOczzzyD2Wxm/PjxpKam8txzz3H33Xezbt065zavv/46Y8aMoWfPnowbN469e/dy6623Urt2bRo2bFjkz2TIkCHccMMN/P333zRr1sz5Hu+4445C38+3335Lnz59aNq0KVOnTuX06dO88sordO/enY0bNzoHP/v999+54YYbCAwMZOrUqeTm5hIbG0tQUNB5x5w+fTqTJ0/mrrvuYuTIkSQlJfHKK69w9dVX89tvv+Hn51fk9/PP9zZ16lRWrVrFtdde63xv1113HXXr1j1v+8TERK688kpMJhNjxowhMDCQr7/+mhEjRpCWlsbDDz9MmzZtmDZtGlOmTOHf//6388ucq666ynmc48eP06dPHwYNGsQ999xT6HsGsNls3HTTTcTHxzNo0CDGjh3LyZMnWbFiBVu3bqVZs2asWLGCwYMHc9111/Hss88CsH37dn766SfGjh1bos9FRERqIIeIiEgZe/vttx2A49tvv3UkJSU5Dhw44Pjkk08cgYGBDjc3N8eBAwec2+bm5jqysrIK7J+SkuIICgpy/Otf/3Ku27NnjwNw1KlTx5GcnOxc//nnnzsAx5dffulcN2zYMIeXl5fD4XA4Vq9e7fDx8XH069fPkZmZWeA8vXr1cvTq1cv588qVKx2Ao02bNgUyvfTSSw7A8fvvvzscDocjKyvLUadOHccVV1zhyMnJcW63YMECB1DgmBfSuHFjR79+/Ry5ubmO4OBgx5NPPulwOByObdu2OQDH999/7/wcf/nlF+d+YWFhjrp16zqOHz/uXLd582aH2Wx2DB061Lnu1ltvdbi7uzv27dvnXLdt2zaHxWJxnPvf/969ex0Wi8Uxffr0Avl+//13h4uLS4H1w4YNczRu3PiS761Xr16Odu3aORwOh6NLly6OESNGOByOvD9Xq9XqWLhwofOz/vjjj537jRgxwlGvXj3HsWPHChxv0KBBDl9fX0dGRobD4XA4fvnlFwfgePvttws9N+CIi4sr9LVz/2zmz5/vAByzZs06b1u73e5wOByOsWPHOnx8fBy5ubmXfN8iIiIXoq7mIiJSbiIiIggMDCQkJIQ77rgDLy8vvvjiiwItwhaLxXnfrd1uJzk5mdzcXLp06cLGjRvPO+bAgQMLtJjnt3ju3r37vG1XrlxJZGQk1113HYsXL8bNza1IuaOiogrcC/zPc/z6668cP36cUaNG4eJytvPY3XffXSBbUVgsFu666y7nvdDvv/8+ISEhznOe68iRI2zatInhw4fj7+/vXN+xY0euv/56li5dCuS15C5fvpxbb72VRo0aObdr06bNed3XFy9ejN1u56677uLYsWPOJTg4mBYtWpzX5b+4hgwZwuLFi8nOzuaTTz7BYrEwYMCA87ZzOBx8+umn9O/fH4fDUSBLZGQkqamphf59KIybmxtRUVGX3O7TTz8lICCABx988LzX8qdc8/PzIz09nRUrVhTp3CIiIoVR4S0iIuVmzpw5rFixgk8++YS+ffty7NixQovfhQsX0rFjR9zd3alTpw6BgYEsWbKE1NTU87Y9t5CEs93WU1JSCqzPzMykX79+XHbZZXz00UfFGlTrUufYt28fAM2bNy+wnYuLS4nmuR4yZAjbtm1j8+bNfPDBBwwaNKjQubbzz9uqVavzXmvTpg3Hjh0jPT2dpKQkTp8+Xeh0Xv/cd+fOnTgcDlq0aEFgYGCBZfv27Rw9erTY7+dcgwYNIjU1la+//pr333+fm266CW9v7/O2S0pK4sSJE7z55pvn5cgvoouapUGDBkX68/77779p1apVgS9P/un++++nZcuW9OnTh4YNG/Kvf/2LZcuWFSmHiIhIPt3jLSIi5aZr16506dIFgFtvvZUePXowZMgQduzYQa1atYC8Qb2GDx/Orbfeyn/+8x/q1q2LxWJhxowZBQa4ymexWAo9l8PhKPCzm5sbffv25fPPP2fZsmXcdNNNRc5d1HOUlfDwcJo1a8bDDz/Mnj17GDJkSLmcpzB2ux2TycTXX39d6PvO/3MqqXr16tG7d29mzpzJTz/9xKeffnrBHAD33HMPw4YNK3Sbjh07Fumcl7qHvzjq1q3Lpk2bWL58OV9//TVff/01b7/9NkOHDmXhwoVldh4REaneVHiLiEiFyC+mr7nmGl599VUmTpwIwCeffELTpk1ZvHhxgVbe2NjYUp3PZDLx/vvvc8stt3DnnXfy9ddfF3m08Utp3LgxALt27eKaa65xrs/NzWXv3r1FLhDPNXjwYJ566inatGlzwbmp88+7Y8eO8177888/CQgIwMvLC3d3dzw8PNi5c+d52/1z32bNmuFwOGjSpAktW7Ysdu6iGDJkCCNHjsTPz4++ffsWuk1gYCDe3t7YbDYiIiIuerzCegOURLNmzVi3bh05OTkXHJgP8qYh69+/P/3798dut3P//ffzxhtvMHny5PN6PYiIiBRGXc1FRKTC9O7dm65duzJ79mwyMzOBs63L57Ymr1u3jrVr15b6fFarlcWLF3PFFVfQv39/1q9fX+pjAnTp0oU6deowd+5ccnNznevff//987q8F9XIkSOJjY1l5syZF9ymXr16hIWFsXDhQk6cOOFcv3XrVr755htnUWuxWIiMjOSzzz5j//79zu22b9/O8uXLCxzztttuw2Kx8MQTT5zXou9wODh+/HiJ3s+57rjjDmJjY3nttdcu2AXcYrFw++238+mnn7J169bzXk9KSnI+9/LyAijwGZTE7bffzrFjx3j11VfPey3/s/jn+zebzc4vVrKyskp1fhERqTnU4i0iIhXqP//5D3feeScLFizgvvvu46abbmLx4sUMGDCAfv36sWfPHuLi4mjbtq1zvu3S8PDw4KuvvuLaa6+lT58+fP/997Rv375Ux7RarUydOpUHH3yQa6+9lrvuuou9e/eyYMECmjVrVqIW2caNGzN16tRLbvf888/Tp08funXrxogRI5zTifn6+hbY/4knnmDZsmX07NmT+++/n9zcXF555RXatWvHli1bnNs1a9aMp556ipiYGOeUaN7e3uzZs4f//e9//Pvf/2b8+PHFfj/n+me2C3nmmWdYuXIl4eHhjBo1irZt25KcnMzGjRv59ttvSU5Odmb28/MjLi4Ob29vvLy8CA8Pp0mTJsXKNXToUN555x2io6NZv349PXv2JD09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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "code", + "source": [ + "ranking_model.evaluate(ranking_test_dataset)" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "RD4UirtNvDXT", + "outputId": "9964607f-eea1-4c1a-d117-2a847416cfec" + }, + "execution_count": 44, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "\u001b[1m1/1\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 630ms/step - AUC: 0.9867 - accuracy: 0.9372 - loss: 0.2243\n" + ] + }, + { + "output_type": "execute_result", + "data": { + "text/plain": [ + "[0.2243196964263916, 0.9866776466369629, 0.9371727705001831]" + ] + }, + "metadata": {}, + "execution_count": 44 + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "# **Predictions of Ranking Model**\n", + "The retrieval model gave us a list of ads that are generally relevant (high dot product similarity). The ranking model will now calculate the specific probability (0% to 100%) that the user will click each of those ads.\n", + "\n", + "The Ranking model expects pairs of (User, Ad). Since we are scoring 10 ads for 1 user, we cannot just pass the user features once.We effectively take user's features 10 times to create a batch." + ], + "metadata": { + "id": "XaLAPapNjdYm" + } + }, + { + "cell_type": "code", + "source": [ + "def rerank_ads_for_user(user_row, retrieved_ads, ranking_model):\n", + " ads_df = pd.DataFrame(retrieved_ads)\n", + " num_ads = len(ads_df)\n", + " user_inputs = { k: tf.fill((num_ads, 1), str(user_row[k]) if k not in continuous_features else float(user_row[k]))\n", + " for k in USER_FEATURES}\n", + " ad_inputs = {k: tf.reshape(tf.constant(ads_df[k].astype(str).values), (-1, 1)) for k in AD_FEATURES}\n", + " scores = ranking_model({\"user\": user_inputs, \"positive_ad\": ad_inputs}).numpy().flatten()\n", + " ads_df[\"ranking_score\"] = scores\n", + " return ads_df.sort_values(\"ranking_score\", ascending=False).to_dict(\"records\")\n", + "\n", + "sample_user = x_test.iloc[0]\n", + "scores, indices = retrieval_engine.query_batch(pd.DataFrame([sample_user]))\n", + "top_ads = retrieval_engine.decode_results(scores, indices)[0]\n", + "final_ranked_ads = rerank_ads_for_user(sample_user, top_ads, ranking_model)\n", + "print(f\"User: {sample_user['user_id']}\")\n", + "print(f\"{'Ad ID':<10} | {'Topic':<30} | {'Retrival Score':<11} | {'Rank Probability'}\")\n", + "for item in final_ranked_ads:\n", + " print(f\"{item['ad_id']:<10} | {item['ad_topic'][:28]:<30} | {item['score']:.4f} | {item['ranking_score']*100:.2f}%\")" + ], + "metadata": { + "id": "MvPsCaw_vDaT", + "colab": { + "base_uri": "https://localhost:8080/" + }, + "outputId": "7b16a6ac-679e-41b6-cce8-67b4f193b91a" + }, + "execution_count": 49, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "User: user_216\n", + "Ad ID | Topic | Retrival Score | Rank Probability\n", + "ad_660 | Profound optimizing utilizat | 8.1021 | 99.19%\n", + "ad_318 | Front-line upward-trending g | 6.6563 | 99.07%\n", + "ad_311 | Front-line methodical utiliz | 6.6728 | 98.77%\n", + "ad_31 | Ameliorated well-modulated c | 6.4871 | 98.65%\n", + "ad_861 | Synergized clear-thinking pr | 6.2368 | 98.57%\n", + "ad_387 | Implemented didactic support | 5.9674 | 98.47%\n", + "ad_799 | Self-enabling optimal initia | 5.8983 | 98.43%\n", + "ad_984 | Vision-oriented contextually | 5.9103 | 98.29%\n", + "ad_706 | Re-engineered demand-driven | 6.5815 | 98.22%\n", + "ad_916 | Universal multi-state system | 5.6566 | 98.17%\n" + ] + } + ] + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "ECqj1I91JUgg" + }, + "execution_count": 45, + "outputs": [] + } + ] +} \ No newline at end of file