-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement Social Network Simulation with Crisis and Bridge Builder Dynamics #45
Conversation
…d emotional states
- Added missing methods `measure_polarization`, `analyze_bridge_effectiveness`, and `test_network_resilience` to the `SocialNetwork` class. - Updated `analyze_results` method in `SimulationAnalyzer` to use the correct key `overall_variance` from `measure_polarization` output. - Ensured comprehensive simulation runs without errors and provides detailed analysis of network dynamics.
Reviewer's Guide by SourceryThis PR introduces a comprehensive social network simulation framework for studying bias dynamics, implementing a multi-agent system with echo chambers, bridge builders, and crisis response mechanisms. The implementation uses PyTorch for the neural network components and includes extensive analysis and visualization capabilities. Class diagram for SocialAgent and SocialNetworkclassDiagram
class SocialAgent {
+Parameter bias
+float susceptibility
+float stubbornness
+bool is_influencer
+float confirmation_bias_strength
+list interaction_history
+int memory_length
+Parameter emotional_state
+Sequential belief_network
+list trauma_memories
+float trauma_decay_rate
+float emotional_contagion_rate
+bool is_bridge_builder
+list group_memberships
+list bias_influence_history
+list received_influences
+float influence_strength
+Linear projection
+MultiheadAttention attention
+Parameter uncertainty
+calculate_confirmation_bias(social_influence)
+update_emotional_state(social_influence, neighboring_emotions, crisis_intensity)
+forward(social_influence, new_information, external_influence)
+calculate_bias_impact(other_bias)
+record_influence(influence_value, source_bias)
+analyze_individual_bias()
}
class SocialNetwork {
+int num_echo_chambers
+int num_bridge_builders
+int num_base_agents
+int total_agents
+list agents
+Tensor external_influences
+Tensor group_identities
+Tensor connections
+list crisis_history
+list bias_spread_history
+list chamber_polarization
+DiGraph influence_network
+dict metrics
+list bias_history
+int crisis_start
+int crisis_end
+add_bridge_builder_connections(builder_idx, chambers)
+create_echo_chamber_connections(num_agents, agents_per_chamber, num_influencers)
+trigger_crisis(intensity, duration, target_chamber)
+simulate_step(time_step)
+run_simulation(steps)
+visualize_network()
+plot_simulation(bias_history)
+add_bridge_builders(num_bridge_builders)
+analyze_individual_bias()
+analyze_bias_evolution(bias_history)
+track_opinion_shifts(bias_history)
+identify_critical_points(bias_history)
+analyze_crisis_response()
+calculate_recovery_time()
+analyze_network_stability()
+visualize_bias_spread()
+analyze_group_dynamics()
+calculate_chamber_isolation(start_idx, end_idx)
+measure_external_resistance(chamber_agents)
+measure_polarization()
+analyze_bridge_effectiveness()
+test_network_resilience()
}
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @leonvanbokhorst - I've reviewed your changes and they look great!
Here's what I looked at during the review
- 🟡 General issues: 3 issues found
- 🟢 Security: all looks good
- 🟢 Testing: all looks good
- 🟡 Complexity: 2 issues found
- 🟢 Documentation: all looks good
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
# Apply attention mechanism | ||
attention_output = self.attention( | ||
query=current_state, key=current_state, value=current_state | ||
)[0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (performance): The self-attention mechanism is being applied to a single state, which is inefficient and provides no benefit.
Consider either removing the attention mechanism or batching multiple states together if attention comparison is needed. For a single state, a simple linear transformation would be more efficient.
# Replace attention with direct linear transformation
attention_output = self.linear(current_state)
def calculate_confirmation_bias(self, social_influence): | ||
"""Calculate how much the agent accepts/rejects information based on current bias""" | ||
bias_difference = abs(self.bias.item() - social_influence) | ||
acceptance_rate = 1.0 - (bias_difference * self.confirmation_bias_strength) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue: Potential edge case where acceptance_rate could be negative before clamping.
Consider handling the edge case by clamping bias_difference * confirmation_bias_strength to 1.0 before subtracting from 1.0.
self.bias_history = [] # Store for crisis analysis | ||
|
||
for step in range(steps): | ||
if self.current_crisis and step == self.current_crisis['remaining']: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (performance): Inefficient crisis event checking in run_simulation method.
Consider tracking crisis start/end steps when crisis is triggered and only checking during those relevant steps.
if self.current_crisis and step == self.current_crisis['remaining']: | |
crisis_start = self.current_crisis.get('remaining') if self.current_crisis else None | |
crisis_end = (self.current_crisis.get('remaining') + self.current_crisis.get('duration')) if self.current_crisis else None | |
if step == crisis_start: |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') | ||
|
||
|
||
class SocialAgent(nn.Module): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider splitting SocialAgent class into focused components for emotional processing, belief processing, and core agent logic
The SocialAgent class would benefit from being split into focused components while maintaining functionality. Here's how to reduce complexity:
- Extract emotional processing into an EmotionalProcessor:
class EmotionalProcessor:
def __init__(self, emotional_state, contagion_rate):
self.emotional_state = emotional_state
self.contagion_rate = contagion_rate
self.trauma_memories = []
def update(self, social_influence, neighboring_emotions, crisis_intensity):
# Existing emotional update logic moved here
pass
- Extract belief processing into a BeliefProcessor:
class BeliefProcessor:
def __init__(self, input_size):
self.network = nn.Sequential(
nn.Linear(input_size, 12),
nn.ReLU(),
nn.Linear(12, 1),
nn.Tanh()
)
def process(self, inputs):
return self.network(inputs)
- Simplify forward() by removing redundant attention mechanism and using existing weighted averaging:
def forward(self, social_influence, new_information, external_influence):
# Update emotional state
self.emotional_processor.update(social_influence, neighboring_emotions, crisis_intensity)
# Calculate weighted history (existing logic)
weighted_history = self.calculate_weighted_history()
# Process beliefs
inputs = torch.tensor([
self.bias.item(),
social_influence * self.calculate_confirmation_bias(social_influence),
new_information,
external_influence,
weighted_history
])
return self.belief_processor.process(inputs)
This restructuring:
- Improves maintainability by separating concerns
- Removes redundant attention mechanism while keeping weighted influence
- Maintains all functionality including emotional contagion and trauma memory
- Reduces cognitive load by having clear component responsibilities
return results | ||
|
||
|
||
class SimulationAnalyzer: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (complexity): Consider simplifying the analysis layer by removing LLM-based narrative generation in favor of structured data output
The SimulationAnalyzer
class adds unnecessary complexity by using LLM-generated narratives. Instead, return the metrics directly in a structured format that's easier to consume programmatically:
class SimulationAnalyzer:
def analyze_results(self, simulation_data: Dict[str, Any]) -> Dict[str, Any]:
"""Analyze simulation results and return structured insights"""
return {
'bias_evolution': {
'convergence_rate': simulation_data['temporal_metrics']['convergence_rate'],
'final_polarization': simulation_data['network_metrics']['overall_variance'],
'critical_changes': simulation_data['temporal_metrics']['critical_points']
},
'network_health': {
'echo_chamber_strength': simulation_data['group_metrics'],
'bridge_effectiveness': simulation_data['bridge_builder_metrics'],
'crisis_resilience': simulation_data['resilience_metrics']
}
}
This approach:
- Removes the LLM dependency and complex prompt engineering
- Returns metrics directly for programmatic use
- Maintains all valuable insights in a structured format
- Improves reliability and testability
|
||
def add_bridge_builders(self, num_bridge_builders): | ||
"""Add agents with connections to multiple chambers""" | ||
for i in range(num_bridge_builders): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (code-quality): Replace unused for index with underscore (for-index-underscore
)
for i in range(num_bridge_builders): | |
for _ in range(num_bridge_builders): |
src/bias_mas_dynamics.py
Outdated
return shifts | ||
|
||
def identify_critical_points(self, bias_history): | ||
"""Identify points where significant changes occurred""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): We've found these issues:
- Move assignment closer to its usage within a block (
move-assign-in-block
) - Convert for loop into list comprehension (
list-comprehension
) - Inline variable that is immediately returned (
inline-immediately-returned-variable
)
for t, biases in enumerate(post_crisis): | ||
if torch.var(torch.tensor(biases)) <= baseline_variance * 1.1: # Within 10% of baseline | ||
return t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): Use the built-in function next
instead of a for-loop (use-next
)
for j in range(i + 1, len(chamber_means)): | ||
chamber_distances.append(abs(chamber_means[i] - chamber_means[j])) | ||
|
||
return { | ||
'overall_variance': variance, | ||
'chamber_polarization': chamber_polarization, | ||
'max_chamber_distance': max(chamber_distances) if chamber_distances else 0, | ||
'avg_chamber_distance': sum(chamber_distances) / len(chamber_distances) if chamber_distances else 0, | ||
'extremity_index': float(torch.max(torch.abs(biases))) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): We've found these issues:
- Replace a for append loop with list extend (
for-append-to-extend
) - Use max/min default argument instead of if statement (
max-min-default
)
return results | ||
|
||
|
||
def analyze_bridge_impact(bridge_counts=[0, 2, 4, 6], num_trials=3): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue (code-quality): We've found these issues:
- Replace unused for index with underscore (
for-index-underscore
) - Replace mutable default arguments with None (
default-mutable-arg
)
Summary by Sourcery
Add a comprehensive simulation framework for modeling and analyzing social network dynamics, including agent interactions, crisis impacts, and visualization tools.
New Features: