Source code for components.socialgraph

""" A binary social graph represents relationships between users which
    can be used in different types of recommender systems.
"""
import numpy as np
from trecs.logging import VerboseMode
from .users import PredictedUserProfiles


[docs]class BinarySocialGraph(VerboseMode): """ A mixin for classes with a :attr:`~trecs.models.recommender.BaseRecommender.users_hat` attribute to gain the basic functionality of a binary social graph. It assumes a network adjacency matrix of size :math:`|U|\\times |U|`. """ # expect these to be initialized users_hat = PredictedUserProfiles(np.array([])) num_users = 0
[docs] def follow(self, user_index, following_index): """ Method to follow another user -- that is, to create a unidirectional link from one user to the other. Parameters ---------- user_index: int Index of the user initiating the follow. following_index: int Index of the user to be followed. Raises ------ ValueError If either of the user indices does not exist. """ if user_index >= self.num_users or following_index >= self.num_users: raise ValueError( f"Number of users is {self.num_users}, but indices " f"{user_index} and {following_index} were requested." ) if self.users_hat.value[following_index, user_index] == 0: self.users_hat.value[following_index, user_index] = 1 elif self.is_verbose(): self.log(f"User {following_index} was already following user {user_index}")
[docs] def unfollow(self, user_index, following_index): """ Method to unfollow another user -- that is, to delete the unidirectional link that goes from one user to the other. Parameters ---------- user_index: int Index of the user initiating the unfollow. following_index: int Index of the user to be unfollowed. Raises ------ ValueError If either of the user indices does not exist. """ if user_index >= self.num_users or following_index >= self.num_users: raise ValueError( f"Number of users is {self.num_users}, but indices " f"{user_index} and {following_index} were requested." ) if self.users_hat.value[following_index, user_index] == 1: self.users_hat.value[following_index, user_index] = 0 elif self.is_verbose(): self.log(f"User {following_index} was not following user {user_index}")
[docs] def add_friends(self, user1_index, user2_index): """ Method to add a user as *friends* -- that is, to create a bidirectional link that connects the two users. Parameters ---------- user1_index: int Index of one user to establish the connection. user2_index: int Index of the other user to establish the connection. Raises ------ ValueError If either of the user indices does not exist. """ if user1_index >= self.num_users or user2_index >= self.num_users: raise ValueError( f"Number of users is {self.num_users}, but indices " f"{user1_index} and {user2_index} were requested." ) if self.users_hat.value[user1_index, user2_index] == 0: self.users_hat.value[user1_index, user2_index] = 1 elif self.is_verbose(): self.log(f"User {user2_index} was already following user {user1_index}") if self.users_hat.value[user2_index, user1_index] == 0: self.users_hat.value[user2_index, user1_index] = 1 elif self.is_verbose(): self.log(f"User {user1_index} was already following user {user2_index}")
[docs] def remove_friends(self, user1_index, user2_index): """ Method to remove a user from *friends* -- that is, to remove a bidirectional link that connects the two users. Parameters ---------- user1_index: int Index of one user for which to remove the connection. user2_index: int Index of the other user for which to remove the connection. Raises ------ ValueError If either of the user indices does not exist. """ if user1_index >= self.num_users or user2_index >= self.num_users: raise ValueError( f"Number of users is {self.num_users}, but indices " f"{user1_index} and {user2_index} were requested." ) if self.users_hat.value[user1_index, user2_index] == 1: self.users_hat.value[user1_index, user2_index] = 0 elif self.is_verbose(): self.log(f"User {user2_index} was not following user {user1_index}") if self.users_hat.value[user2_index, user1_index] == 1: self.users_hat.value[user2_index, user1_index] = 0 elif self.is_verbose(): self.log(f"User {user1_index} was not following user {user2_index}")