tensorrec
tensorrec copied to clipboard
Unexpected outcomes from custom prediction graph
Very glad to find this module for building recommender systems. I was trying to apply this to a slightly different scenario where the interaction outcome is binary, either 0 or 1. So I designed a prediction graph using sigmoid and defined a loss function as log-loss (or cross-entropy).
Below are the codes for custom graphs.
# Import modules
import numpy as np
import scipy as sp
import tensorflow as tf
import tensorrec
# Define a custom loss graph
class SigmoidLossGraph(tensorrec.loss_graphs.AbstractLossGraph):
def connect_loss_graph(self, tf_prediction_serial, tf_interactions_serial, **kwargs):
return -tf.reduce_mean(tf_interactions_serial * tf.log(tf_prediction_serial) +
(1-tf_interactions_serial) * tf.log(1-tf_prediction_serial))
# Define a custom prediction graph
class SigmoidPredictionGraph(tensorrec.prediction_graphs.AbstractPredictionGraph):
def connect_dense_prediction_graph(self, tf_user_representation, tf_item_representation):
return tf.nn.sigmoid(tf.matmul(tf_user_representation, tf_item_representation, transpose_b=True))
def connect_serial_prediction_graph(self, tf_user_representation, tf_item_representation, tf_x_user, tf_x_item):
gathered_user_reprs = tf.gather(tf_user_representation, tf_x_user)
gathered_item_reprs = tf.gather(tf_item_representation, tf_x_item)
return tf.nn.sigmoid(tf.reduce_sum(tf.multiply(gathered_user_reprs, gathered_item_reprs), axis=1))
Then I used the custom graphs to create a system and generate some random datasets to test it.
# Build a hybrid model with customized functions
hybrid_model = tensorrec.TensorRec(n_components = 10,
loss_graph=SigmoidLossGraph(),
prediction_graph = SigmoidPredictionGraph(),
)
# Generate some dummy data
n_users=1000
n_items=150
interactions, user_features, item_features = tensorrec.util.generate_dummy_data(num_users=n_users,
num_items=n_items,
n_features_per_user = 5,
n_features_per_item = 5,
interaction_density=.3)
# Transform interaction outcome into binary
interactions2 = (interactions > 0) * 1
# Fit the hybrid model
print("Training hybrid model")
hybrid_model.fit(interactions=interactions2,
user_features=user_features,
item_features=item_features,
epochs=10,
verbose = True,
alpha = 0
)
# Predict scores for all users and all items
predictions = hybrid_model.predict(user_features=user_features,
item_features=item_features,
)
predictions
As far as I understand, the system was going to produce prediction values between 0 and 1. But it turned out not the case. There were many prediction values higher than one.
Is there something wrong with the above codes? Thanks!