catfish_sim package

Submodules

catfish_sim.agents module

class catfish_sim.agents.Agent(id, reported_attributes, hidden_attributes, like_allowance, strategy, compatibility_calculator, attractiveness=None, estimated_attractiveness=None)[source]

Bases: object

The base agent class that can take different attributes.

assess_candidates(candidates_details)[source]

Classifies the provided candidates into liked and passed candidate groups.

Parameters:

candidates_details (list) – A list of dictionaries for public candidates’ details.

Returns:

A dictionary of “liked” and “passed” candidates.

Return type:

dict

calculate_happiness(matched_agent)[source]

Returns the match happiness (utility) for a given matched agent using the utility formula. The utility suffers from diminishing returns.

Parameters:

matched_agent (Agent) – The matched agent’s object.

Returns:

Match happiness.

Return type:

float

estimate_self_attractiveness()[source]

Estimates its own attractiveness with an error margin. Agents cannot use their actual attractiveness levels for anything. Instead, they use their estimations (unless they use a strategy that updates this estimation).

Returns:

Estimated self-attractiveness.

Return type:

float

get_assessed_candidates()[source]

Returns the previously encountered (liked or passed) candidates’ IDs.

Returns:

A set of agent IDs.

Return type:

set

get_logs(log_id=None, variables=None)[source]

Retrieves the agent logs.

Parameters:
  • log_id (int, optional) – The round state that will be returned. If None, all round logs are returned. Defaults to None.

  • variables (list, optional) – The set of variables that will be returned. If None, all available variables are returned. Defaults to None.

Returns:

A dictionary of variables that have the round values.

Return type:

dict

get_matched(matched_agent)[source]

Informs the agent about the match with the provided agent.

Parameters:

matched_agent (Agent) – The matched agent’s object.

Returns:

Success and acknowledgment indicator.

Return type:

bool

get_public_details()[source]

Returns the agent’s ID, attractivenes, and reported attributes which are passed to the candidates that evaluate the agent.

Returns:

A dictionary that includes the ID, attractiveness, and reported attributes.

Return type:

dict

get_random_attractiveness()[source]

Randomly samples the attractiveness level from gender-specific beta distributions.

Returns:

Attractiveness.

Return type:

float

log_state(log_id, logged_variables)[source]

Logs the agent’s current state with the given log (day/round) ID and the requested log variables.

Parameters:
  • log_id (int) – Round ID that will also uniquely identify the log.

  • logged_variables (list) – A list of variable names from the agent object.

Returns:

Success and acknowledgment indicator.

Return type:

bool

catfish_sim.compatibility module

class catfish_sim.compatibility.Attribute(name, value, preference)[source]

Bases: object

class catfish_sim.compatibility.CategoricalPreference(preferred_values, allowed_values, preferred_score, nonpreferred_score, compatibility_weight=1, ignore_unrecognized=True)[source]

Bases: Preference

evaluate_attribute(value)[source]

Evaluates a candidate’s attribute, comparing it with the preferred values and returning an attribute-specific compatibility score.

Parameters:

value (str|float|int) – Candidate’s attribute value.

Returns:

Attribute-specific compatibility score.

Return type:

float

class catfish_sim.compatibility.CompatibilityCalculator[source]

Bases: object

get_compatibility(judger_attributes, judged_attributes)[source]

Calculates the compatibility between two agents using two dictionaries of attributes. Since the compatibility is calculated from the judging agent’s perspective, it is not necessarily symmetrical. Also, when used by agents themselves, judger_attributes consists of both reported and hidden attributes, and hidden attributes have the precedence over the reported ones to consider the agent’s hidden attributes and preferences. judged_attributes are always the reported ones. When used by a matcher, both attributes are reported attributes.

Parameters:
  • judger_attributes (dict) – Dictionary of the judging agent’s attributes. Consists of both reported and hidden attributes where the hidden ones have the precedence when the compatibility is calculated by the agent. Otherwise, judger_attributes is a dictionary of reported attributes.

  • judged_attributes (dict) – Dictionary of the judged agent’s reported attributes.

Returns:

Compatibility score.

Return type:

float

class catfish_sim.compatibility.DictBasedPreference(compatibility_dict, default_value=None, compatibility_weight=1)[source]

Bases: Preference

evaluate_attribute(value)[source]

Evaluates a candidate’s attribute, comparing it with the preferred value range and returning an attribute-specific compatibility score.

Parameters:

value (float) – Candidate’s attribute value.

Returns:

Attribute-specific compatibility score.

Return type:

float

class catfish_sim.compatibility.NumericalPreference(preferred_range, allowed_range, preferred_score, nonpreferred_score, distance_sensitive=None, compatibility_weight=1, compatibility_fn=None)[source]

Bases: Preference

evaluate_attribute(value)[source]

Evaluates a candidate’s attribute, comparing it with the preferred value range and returning an attribute-specific compatibility score.

Parameters:

value (float) – Candidate’s attribute value.

Returns:

Attribute-specific compatibility score.

Return type:

float

class catfish_sim.compatibility.Preference(preferred_values=None, preferred_range=None, allowed_values=None, allowed_range=None, preferred_score=1, nonpreferred_score=0, distance_sensitive=False, compatibility_weight=1, compatibility_fn=None)[source]

Bases: object

evaluate_attribute(value)[source]

catfish_sim.matchers module

class catfish_sim.matchers.AgentMatcher[source]

Bases: object

This is the base AgentMatcher class that is extended by specific matchers.

eliminate_bottom(bottom_threshold)[source]

Eliminates the provided bottom percentile (inclusive) of agents from the simulation. Eliminated agents cannot interact with the system and they are not shown to other agents anymore.

get_agent_by_id(id)[source]

Returns the agent that corresponds to the provided ID.

Parameters:

id (int) – Agent ID.

Returns:

An Agent object.

Return type:

Agent

get_agents_by_ids(ids)[source]

Returns a list of Agent objects that correspond to the provided list of IDs.

Parameters:

ids (list) – A list of agent IDs.

Returns:

A list of Agent objects.

Return type:

list

get_available_candidates(agent)[source]

Retrieves available candidate agents that will be recommended to the agent.

get_info()[source]

Returns details of the matcher.

process_likes(likes)[source]

Processes likes by updating the matching matrix.

process_matches()[source]

Processes matches by informing the agents about their match details.

process_passes(passes)[source]

Processes passes by updating the matching matrix.

run_new_round()[source]

Runs the simulation for a new round. Each agent is notified of the new round, their allowance is replenished, new agents are recommended, and agent responses are saved. After this is done for all agents, likes, passes, and matches are processed, and the agents are logged.

class catfish_sim.matchers.PreferentialAgentMatcher(agents, recommendation_limit, compatibility_calculator, judger_weight=0.5, logging=True, log_eliminated=False, recalculate=False)[source]

Bases: AgentMatcher

This matcher recommends unseen agents to each agent based on their compatibility using the stated attributes and preferences. judger_weight indicates the weight of the judging agent’s point of view (1 means the recommendations solely depend on the judging agent’s preferences while 0.5 uses both parties preferences equally). Agents’ IDs must start from 0 and be sequential due to being used as indices.

eliminate_bottom(bottom_threshold, verbose=False)[source]

Eliminates the bottom percentile based on happiness. Eliminated agents cannot interact with the system and they are not shown to other agents anymore.

Parameters:
  • bottom_threshold (float) – Inclusive percentile threshold that will be used to eliminate agents.

  • verbose (bool, optional) – Indicates whether the elimination details (round and number of remaining agents) will be printed. Defaults to False.

Returns:

Returning True indicates the elimination is complete.

Return type:

bool

generate_platonic_recommendation_priorities_for_agent(agent_id, judger_weight=None)[source]

Generates a recommendation priority for a single person without updating the other recommendation queues. It is possible to use a judger_weight value that is different than the existing one for this generation.

Parameters:
  • agent_id (int) – Agent ID.

  • judger_weight (float, optional) – Judger weight used solely for this generation. If not provided, the existing value is used. Defaults to None.

generate_recommendation_priorities()[source]

Generates recommendation priority queues for all agents using the compatibility scores and the judger weight.

get_available_candidates(agent)[source]

Returns all candidates who were not seen by the agent.

Parameters:

agent (list) – A list of Agent objects.

Returns:

A set of available agent IDs.

Return type:

set

get_info()[source]

Returns details of the matcher.

Returns:

Name, agents, rounds, and the recommendation limit of the matcher.

Return type:

dict

log_agents(log_eliminated=False)[source]
name = 'Preferential Agent Matcher'
process_likes(likes)[source]

Processes likes by updating the matching matrix.

Returns:

Returning True indicates the process is complete.

Return type:

bool

process_matches()[source]

Processes matches by informing the agents about their match details.

Returns:

Returning True indicates the process is complete.

Return type:

bool

process_passes(passes)[source]

Processes passes by updating the matching matrix.

Returns:

Returning True indicates the process is complete.

Return type:

bool

run_new_round()[source]

Runs the simulation for a new round. Each agent is notified of the new round, their allowance is replenished, new agents are recommended, and agent responses are saved. After this is done for all agents, likes, passes, and matches are processed, and the agents are logged.

Returns:

Returning True indicates the round is complete.

Return type:

bool

class catfish_sim.matchers.RandomAgentMatcher(agents, recommendation_limit, compatibility_calculator, logging=True, log_eliminated=False)[source]

Bases: AgentMatcher

This matcher randomly recommends unseen agents to each agent based on their remaining like allowance. Agents’ IDs must start from 0 and be sequential due to being used as indices.

eliminate_bottom(bottom_threshold, verbose=False)[source]

Eliminates the bottom percentile based on happiness. Eliminated agents cannot interact with the system and they are not shown to other agents anymore.

Parameters:
  • bottom_threshold (float) – Inclusive percentile threshold that will be used to eliminate agents.

  • verbose (bool, optional) – Indicates whether the elimination details (round and number of remaining agents) will be printed. Defaults to False.

Returns:

Returning True indicates the elimination is complete.

Return type:

bool

get_available_candidates(agent)[source]

Returns all candidates who were not seen by the agent.

Parameters:

agent (list) – A list of Agent objects.

Returns:

A set of available agent IDs.

Return type:

set

get_info()[source]

Returns details of the matcher.

Returns:

Name, agents, rounds, and the recommendation limit of the matcher.

Return type:

dict

log_agents(log_eliminated=False)[source]
name = 'Random Agent Matcher'
process_likes(likes)[source]

Processes likes by updating the matching matrix.

Returns:

Returning True indicates the process is complete.

Return type:

bool

process_matches()[source]

Processes matches by informing the agents about their match details.

Returns:

Returning True indicates the process is complete.

Return type:

bool

process_passes(passes)[source]

Processes passes by updating the matching matrix.

Returns:

Returning True indicates the process is complete.

Return type:

bool

run_new_round()[source]

Runs the simulation for a new round. Each agent is notified of the new round, their allowance is replenished, new agents are recommended, and agent responses are saved. After this is done for all agents, likes, passes, and matches are processed, and the agents are logged.

Returns:

Returning True indicates the round is complete.

Return type:

bool

class catfish_sim.matchers.RankedAgentMatcher(agents, recommendation_limit, compatibility_calculator, consider_dealbreakers=True, dealbreaker_judger_weight=0.5, strict_recommendations=True, likes_as_draws=False, rank_passes=True, rank_pass_from_lower=True, rank_pass_from_higher=True, logging=True, log_eliminated=False, recalculate=False)[source]

Bases: AgentMatcher

A matcher that ranks agents based on their interactions with other agents using TrueSkill, a Bayesian rating system. It can eliminate agents based on their happiness levels or ratings. Since TrueSkill works with wins, losses, and draws, likes and passes are interpreted as 1v1 matches. By default, liking an agent means losing a match to them, while passing an agent means winning the match. However, the matcher is flexible and it is possible to change how these interactions are interpreted by the matcher. Agents’ IDs must start from 0 and be sequential due to being used as indices.

calculate_compatibilities()[source]

Calculates compatibilities using the compatibility scores and the judger weight to later check for deal-breakers.

eliminate_bottom(bottom_threshold, using_ratings=False, verbose=False)[source]

Eliminates the bottom percentile based on happiness or rating. Eliminated agents cannot interact with the system and they are not shown to other agents anymore.

Parameters:
  • bottom_threshold (float) – Inclusive percentile threshold that will be used to eliminate agents.

  • using_ratings (bool, optional) – Indicates whether the elimination is handled based on ratings. Defaults to False.

  • verbose (bool, optional) – Indicates whether the elimination details (round and number of remaining agents) will be printed. Defaults to False.

Returns:

Returning True indicates the elimination is complete.

Return type:

bool

get_available_candidates(agent)[source]

Retrieves previously unseen candidates with close ratings for a specific agent.

Parameters:

agent (Agent) – An Agent object.

Returns:

Agent IDs that will be recommended.

Return type:

list

get_info()[source]

Returns details of the matcher.

Returns:

Name, agents, rounds, and the recommendation limit of the matcher.

Return type:

dict

log_agents(log_eliminated=False)[source]

Logs agents’ current state.

Returns:

Returns True when the process is complete.

Return type:

bool

name = 'Ranked Agent Matcher'
process_likes(likes)[source]

Processes likes by updating the matching matrix.

Returns:

Returning True indicates the process is complete.

Return type:

bool

process_matches()[source]

Processes matches by informing the agents about their match details.

Returns:

Returning True indicates the process is complete.

Return type:

bool

process_passes(passes)[source]

Processes passes by updating the matching matrix.

Returns:

Returning True indicates the process is complete.

Return type:

bool

run_new_round()[source]

Runs the simulation for a new round. Each agent is notified of the new round, their allowance is replenished, new agents are recommended, and agent responses are saved. After this is done for all agents, likes, passes, and matches are processed, and the agents are logged.

Returns:

Returning True indicates the round is complete.

Return type:

bool

catfish_sim.strategies module

class catfish_sim.strategies.Adventurous[source]

Bases: Strategy

A strategy that randomly likes the candidate.

is_interested(agent, candidate_details)[source]

_summary_

Parameters:
  • agent – Not used.

  • candidate_details – Not used.

Returns:

A boolean value indicating agent’s liking (True) or passing (False)

behavior.

Return type:

bool

name = 'Adventurous'
class catfish_sim.strategies.PhysicalHomophiliac(homophily_threshold=[-1.5, 2])[source]

Bases: Strategy

A strategy that favors candidates who are in a specified attractiveness threshold with the agent’s own estimated attractiveness.

is_interested(agent, candidate_details)[source]

Decides whether the given agent is interested in the given candidate.

Parameters:
  • agent (Agent) – An agent object that will like or pass the candidate.

  • candidate_details (dict) – Public details of the candidate.

Returns:

A boolean value indicating agent’s liking (True) or passing (False)

behavior.

Return type:

bool

name = 'Physical Homophiliac'
class catfish_sim.strategies.SocialClimber[source]

Bases: Strategy

A strategy that strictly likes candidates who are more attractive than the agent’s own estimated attractiveness.

is_interested(agent, candidate_details)[source]

Decides whether the given agent is interested in the given candidate.

Parameters:
  • agent (Agent) – An agent object that will like or pass the candidate.

  • candidate_details (dict) – Public details of the candidate.

Returns:

A boolean value indicating agent’s liking (True) or passing (False)

behavior.

Return type:

bool

name = 'Social Climber'
class catfish_sim.strategies.Strategy[source]

Bases: object

Strategy parent class.

is_interested(agent, candidate_details)[source]
match_hook(agent, matched_agent)[source]
new_round_hook(agent)[source]
class catfish_sim.strategies.WeightedMinimal[source]

Bases: Strategy

A threshold-based strategy. Depending on the settings, if the candidate compatibility is 1 or higher, or the multiplication of candidate attractiveness and compatibility is equal or higher than the agent’s estimated self-attractiveness, the agent likes the candidate. Currently, always considers attractiveness as well.

is_interested(agent, candidate_details, consider_attractiveness=True)[source]

Decides whether the given agent is interested in the given candidate. The agent also uses their hidden attributes for this, which supersedes the reported ones.

Parameters:
  • agent (Agent) – An agent object that will like or pass the candidate.

  • candidate_details (dict) – Public details of the candidate.

  • consider_attractiveness (bool, optional) – Indicates whether attractiveness will be considered as well. Defaults to True.

Returns:

A boolean value indicating agent’s liking (True) or passing (False) behavior.

Return type:

bool

name = 'Weighted Minimal'

catfish_sim.utils module

catfish_sim.utils.get_agent_stats(agents)[source]

Retrieves the provided agents’ current status.

Parameters:

agents (list) – A list of agent objects.

Returns:

A pandas DataFrame with agents’ status.

Return type:

DataFrame

catfish_sim.utils.get_bmi_preference(gender, bmi)[source]

Deterministically obtains a weight preference.

Parameters:
  • gender (str) – Agent gender.

  • bmi (int) – Agent BMI group ID.

Returns:

BMI preference range, as [min, max].

Return type:

list

catfish_sim.utils.get_height_preference(gender, height)[source]

Deterministically obtains a height preference range for a given gender and height. Uses the height range from LLCP2022 data.

Parameters:
  • gender (str) – Agent gender.

  • height (int) – Agent height.

Returns:

Height preference range, as [min, max].

Return type:

list

catfish_sim.utils.get_random_gender(male_weight=0.72)[source]

Samples gender.

Parameters:

male_weight (float, optional) – Male gender probability. Defaults to 0.72 (based on online dating populations).

Returns:

_description_

Return type:

_type_

catfish_sim.utils.get_random_strategy(strategies, strategy_weights=None)[source]

Chooses, instantiates, and returns a random strategy from the provided strategies.

Parameters:
  • strategies (list) – A list of strategy classes.

  • strategy_weights (list, optional) – A list of strategy weights for sampling. Defaults to None.

Returns:

An instantiated strategy object.

catfish_sim.utils.sample_age_from_sex(sex, consider_dating_population=True)[source]

Samples age from sex (based on LLCP2022: https://www.cdc.gov/brfss/annual_data/annual_2022.html) and optionally calibrates the probabilities according to online dating age penetration distribution (based on https://www.pewresearch.org/short-reads/2023/02/02/key-findings-about-online-dating-in-the-u-s/).

Parameters:
  • sex (str) – “Male” or “Female.”

  • consider_dating_population (bool, optional) – Indicates whether the age probabilities are calibrated using the online dating distributions. Defaults to True.

Returns:

Age group ID (1: 18-24, 2: 25-29, 3: 30-34, 4: 35-39, 5: 40-44, 6: 45-49, 7: 50-54, 8: 55-59, 9: 60-64,

10: 65-69, 11: 70-74, 12: 75-79, 13: 80+).

Return type:

int

catfish_sim.utils.sample_age_preference(sex, age_group, allowed_diff=3)[source]

Samples age preference for a given sex and age group (based on the 2017 US Current Population Survey: https://www2.census.gov/programs-surveys/demo/tables/families/2017/cps-2017/tabfg3-all.xls), along with the user-provided allowed maximum difference using age group IDs.

Parameters:
  • sex (str) – “Male” or “Female.”

  • age_group (str|int) – Age group ID (1: 18-24, 2: 25-29, 3: 30-34, 4: 35-39, 5: 40-44, 6: 45-49, 7: 50-54, 8: 55-59, 9: 60-64, 10: 65-69, 11: 70-74, 12: 75-79, 13: 80+).

  • allowed_diff (int, optional) – Allowed maximum difference using age group IDs. Defaults to 3.

Returns:

Age preference range (minimum, maximum).

Return type:

list

catfish_sim.utils.sample_bmi_from_sex_age(sex, age_group)[source]

Samples a weight group based on the provided sex and age group based on the data. Based on LLCP2022: https://www.cdc.gov/brfss/annual_data/annual_2022.html

Parameters:
  • sex (str) – “Male” or “Female.”

  • age_group (str|int) – Age group ID (1: 18-24, 2: 25-29, 3: 30-34, 4: 35-39, 5: 40-44, 6: 45-49, 7: 50-54, 8: 55-59, 9: 60-64, 10: 65-69, 11: 70-74, 12: 75-79, 13: 80+).

Returns:

BMI group ID (1: Underweight, 2: Normal weight, 3: Overweight, 4: Obesity)

Return type:

int

catfish_sim.utils.sample_height_from_sex_age(sex, age_group)[source]

Samples height from the provided sex and age group (based on LLCP2022: https://www.cdc.gov/brfss/annual_data/annual_2022.html).

Parameters:
  • sex (str) – “Male” or “Female.”

  • age_group (str|int) – Age group ID (1: 18-24, 2: 25-29, 3: 30-34, 4: 35-39, 5: 40-44, 6: 45-49, 7: 50-54, 8: 55-59, 9: 60-64, 10: 65-69, 11: 70-74, 12: 75-79, 13: 80+).

Returns:

Rounded sampled height.

Return type:

int