Network Analysis with ySights

This tutorial demonstrates how to extract and analyze social networks from YSocial simulation data.

What You’ll Learn

  • Extracting different types of social networks

  • Computing network metrics

  • Analyzing ego networks

  • Working with opaque identifiers

  • Thread-level summaries and community diagnostics


[ ]:
from pathlib import Path

from ysights import YDataHandler
import networkx as nx
import matplotlib.pyplot as plt
import numpy as np

plt.style.use('seaborn-v0_8-whitegrid')
%matplotlib inline
[ ]:
# Initialize data handler
from pathlib import Path


def resolve_example_db():
    candidates = [
        Path("ysocial_db.db"),
        Path("../notebooks/ysocial_db.db"),
        Path("../../notebooks/ysocial_db.db"),
        Path("docs/notebooks/ysocial_db.db"),
    ]
    for candidate in candidates:
        if candidate.exists():
            return str(candidate.resolve())
    return "ysocial_db.db"

db_path = resolve_example_db()
ydh = YDataHandler(db_path)

1. Extracting the Social Network

The social network represents connections between agents (follows, friends, etc.).

[ ]:
social_network = ydh.social_network()

print("Social Network Statistics:")
print(f"  Nodes (Agents): {social_network.number_of_nodes()}")
print(f"  Edges (Connections): {social_network.number_of_edges()}")
print(f"  Directed: {social_network.is_directed()}")

Network Density

Density measures how connected the network is (0 = no connections, 1 = fully connected).

[ ]:
density = nx.density(social_network)
print(f"Network Density: {density:.4f}")
print(f"  Interpretation: {density*100:.2f}% of all possible connections exist")

2. Degree Distribution Analysis

The degree of a node is the number of connections it has.

[ ]:
degrees = dict(social_network.degree())
degree_values = list(degrees.values())

print("Degree Statistics:")
print(f"  Mean Degree: {np.mean(degree_values):.2f}")
print(f"  Median Degree: {np.median(degree_values):.2f}")
print(f"  Max Degree: {max(degree_values)}")
print(f"  Min Degree: {min(degree_values)}")
[ ]:
plt.figure(figsize=(12, 5))

plt.subplot(1, 2, 1)
plt.hist(degree_values, bins=30, edgecolor='black', alpha=0.7, color='steelblue')
plt.xlabel('Degree', fontsize=11)
plt.ylabel('Number of Nodes', fontsize=11)
plt.title('Degree Distribution', fontsize=13, fontweight='bold')
plt.grid(True, alpha=0.3)

plt.subplot(1, 2, 2)
degree_counts = nx.degree_histogram(social_network)
degrees_range = range(len(degree_counts))
plt.loglog(degrees_range, degree_counts, 'o', markersize=5, alpha=0.6, color='darkred')
plt.xlabel('Degree (log scale)', fontsize=11)
plt.ylabel('Frequency (log scale)', fontsize=11)
plt.title('Degree Distribution (Log-Log)', fontsize=13, fontweight='bold')
plt.grid(True, alpha=0.3)

plt.tight_layout()
plt.show()

3. Centrality Measures

Centrality measures identify the most important nodes in the network.

Degree Centrality

Identifies nodes with the most direct connections.

[ ]:
degree_centrality = nx.degree_centrality(social_network)

top_5_degree = sorted(degree_centrality.items(), key=lambda x: x[1], reverse=True)[:5]

print("Top 5 Nodes by Degree Centrality:")
for i, (node, centrality) in enumerate(top_5_degree, 1):
    print(f"  {i}. Node {node}: {centrality:.4f}")

Betweenness Centrality

Identifies nodes that act as bridges between different parts of the network.

[ ]:
if social_network.number_of_nodes() > 1000:
    print("Large network detected. Computing approximate betweenness...")
    betweenness = nx.betweenness_centrality(social_network, k=100)
else:
    betweenness = nx.betweenness_centrality(social_network)

top_5_betweenness = sorted(betweenness.items(), key=lambda x: x[1], reverse=True)[:5]

print("Top 5 Nodes by Betweenness Centrality:")
for i, (node, centrality) in enumerate(top_5_betweenness, 1):
    print(f"  {i}. Node {node}: {centrality:.4f}")

4. Mention Network

The mention network shows who mentions whom in their posts.

[ ]:
mention_network = ydh.mention_network()

print("Mention Network Statistics:")
print(f"  Nodes: {mention_network.number_of_nodes()}")
print(f"  Edges (Mentions): {mention_network.number_of_edges()}")
print(f"  Density: {nx.density(mention_network):.4f}")

5. Ego Networks

An ego network contains a focal node and all nodes connected to it.

[ ]:
focal_agent = next(iter(ydh.agent_mapping()))
ego_net = ydh.ego_network(focal_agent)

print(f"Ego Network for Agent {focal_agent}:")
print(f"  Nodes: {ego_net.number_of_nodes()}")
print(f"  Edges: {ego_net.number_of_edges()}")
print(f"  Degree of focal node: {ego_net.degree(focal_agent)}")

Visualizing an Ego Network

[ ]:
plt.figure(figsize=(12, 10))

pos = nx.spring_layout(ego_net, k=0.5, iterations=50, seed=42)
node_colors = ['red' if node == focal_agent else 'lightblue' for node in ego_net.nodes()]
node_sizes = [1000 if node == focal_agent else 300 for node in ego_net.nodes()]

nx.draw_networkx_nodes(ego_net, pos, node_color=node_colors, node_size=node_sizes, alpha=0.8)
nx.draw_networkx_edges(ego_net, pos, alpha=0.3, arrows=True, arrowsize=10)
labels = {node: str(node) if node == focal_agent else '' for node in ego_net.nodes()}
nx.draw_networkx_labels(ego_net, pos, labels, font_size=12, font_weight='bold')

plt.title(f'Ego Network for Agent {focal_agent}', fontsize=14, fontweight='bold')
plt.axis('off')
plt.tight_layout()
plt.show()

6. Community Detection

Identify communities or clusters within the network.

[ ]:
undirected_network = social_network.to_undirected()

try:
    import community as community_louvain
    communities = community_louvain.best_partition(undirected_network)

    num_communities = len(set(communities.values()))
    print(f"Number of Communities Detected: {num_communities}")

    community_sizes = {}
    for node, comm_id in communities.items():
        community_sizes[comm_id] = community_sizes.get(comm_id, 0) + 1

    print("\nCommunity Sizes:")
    for comm_id, size in sorted(community_sizes.items(), key=lambda x: x[1], reverse=True)[:5]:
        print(f"  Community {comm_id}: {size} nodes")
except ImportError:
    print("python-louvain not installed. Install with: pip install python-louvain")

7. Thread and Community Summaries

The current API also exposes thread-aware diagnostics and compact community metrics.

[ ]:
thread_ids = ydh.thread_ids()
print(f"Threads detected: {len(thread_ids)}")

if thread_ids:
    thread_ref = thread_ids[0]
    print(f"First thread ref: {thread_ref}")
    print("\nThread metrics:")
    print(ydh.thread_metrics(thread_ref))

    print("\nThread summaries preview:")
    thread_summaries = ydh.thread_summaries()
    print(thread_summaries[thread_ref])
else:
    print("No threads detected in this database.")

print("\nCommunity metrics:")
print(ydh.community_metrics(graph_type="social"))

8. Network Comparison

Compare social network with mention network.

[ ]:
fig, axes = plt.subplots(1, 2, figsize=(14, 6))

networks = [social_network, mention_network]
titles = ['Social Network', 'Mention Network']

for ax, net, title in zip(axes, networks, titles):
    degrees = [d for n, d in net.degree()]
    ax.hist(degrees, bins=30, edgecolor='black', alpha=0.7)
    ax.set_xlabel('Degree', fontsize=11)
    ax.set_ylabel('Frequency', fontsize=11)
    ax.set_title(title, fontsize=12, fontweight='bold')
    ax.grid(True, alpha=0.3)
    ax.text(
        0.95,
        0.95,
        f'Nodes: {net.number_of_nodes()}\nEdges: {net.number_of_edges()}\nDensity: {nx.density(net):.4f}',
        transform=ax.transAxes,
        fontsize=9,
        verticalalignment='top',
        horizontalalignment='right',
        bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5),
    )

plt.tight_layout()
plt.show()

Summary

In this tutorial, you learned:

✓ How to extract social and mention networks from simulation data
✓ Computing basic network statistics (density, degree distribution)
✓ Calculating centrality measures to identify important nodes
✓ Analyzing ego networks for individual agents
✓ Detecting communities within networks
✓ Reviewing thread-level summaries and graph metrics
✓ Visualizing network structures
✓ Comparing different types of networks

Next Steps

  • Algorithms Tutorial: Learn about profile similarity, paradox detection, recommendation metrics, and topic lifecycle analysis

  • Visualization Tutorial: Create advanced visualizations of simulation data