Search code examples
pythontensorflowkerastf.kerasrecommendation-engine

Add longitude and latitude as features in tensorflow-recommender model


I am making a recommender system. For similar queries I want to give similar recommendations.

I was following the example from here: https://www.tensorflow.org/recommenders/examples/featurization?hl=en

User creates a query. He can choose the desired location on the map that's why query has longitude and latitude in its features. I want to add longitude and latitude in the Query model for the recommender algorithm.

Here is the Query model. It already takes the tokenized text features:

class QueryModel(tf.keras.Model):
  
  def __init__(self):
    super().__init__()

    max_tokens = 10_000

    self.query_features_vectorizer = tf.keras.layers.TextVectorization(
        max_tokens=max_tokens)

    self.query_features_embedding = tf.keras.Sequential([
      self.query_features_vectorizer,
      tf.keras.layers.Embedding(max_tokens, 64, mask_zero=True),
      tf.keras.layers.GlobalAveragePooling1D(),
    ])

    self.query_features_vectorizer.adapt(query_features)

  def call(self, inputs):
    # Take the input dictionary, pass it through each input layer,
    # and concatenate the result.
    return tf.concat([
        self.query_features_embedding(inputs["query_features"]),
    ], axis=1)

I pass query model into this ranking model that has a task to give ratings to each query-candidate pair:

class RatingsModel(tfrs.models.Model):

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

    # query and warehouse models
    self.query_model = tf.keras.Sequential([
      QueryModel(),
      tf.keras.layers.Dense(16)
    ])
    self.candidate_model = tf.keras.Sequential([
      WarehouseModel(),
      tf.keras.layers.Dense(16)
    ])

    # A small model to take in query and warehouse embeddings and predict ratings.
    # We can make this as complicated as we want as long as we output a scalar
    # as our prediction.
    self.rating_model = tf.keras.Sequential([
        tf.keras.layers.Dense(16, activation="linear"),
        tf.keras.layers.Dense(8, activation="tanh"),
        tf.keras.layers.Dense(1, activation="linear"),
    ])

    self.task = tfrs.tasks.Ranking(
      loss=tf.keras.losses.MeanSquaredError(),
      metrics=[tf.keras.metrics.RootMeanSquaredError("RMSE")]
    )

  def call(self, features):
    query_embeddings = self.query_model({
        "query_features": features["query_features"],
    })

    warehouse_embeddings = self.candidate_model({
        "warehouse_id": features["warehouse_id"],
    })

    return (
        self.rating_model(
            tf.concat([query_embeddings, warehouse_embeddings], axis=1)
        ),
    )

  def compute_loss(self, features, training=False):
    labels = features.pop("similarity")
    
    rating_predictions = self(features)

    # We compute the loss for each task.
    rating_loss = self.task(
        labels=labels,
        predictions=rating_predictions,
    )
    return rating_loss

The algorithm predicts the rating for the most relevant candidates for the query.

My question is: how can I take the longitude and latitude into account, what is the general approach?


Solution

  • In this Google blog an explaination is given on how to model geographic coordinates. You can make use of feature crosses to combine the longitude and latitude features.