In [1]:
import relationalai as rai
from relationalai.std.graphs import Graph
from relationalai.std import alias
import matplotlib.pyplot as plt
import pandas as pd
🔧 Utility Functions for Graph Construction
In [ ]:
# =======================
# ⚠️ Demo-Only Functions ⚠️
# =======================
# The following functions are designed for demonstration purposes only,
# specifically for use in `graphlib-egonetwork.ipynb`.
#
# ⚠️ WARNING: These functions include hardcoded values
# (e.g., node ID is assumed to be under the 'id' property).
#
# ✅ Please modify them accordingly for your production or custom use cases.
def compute_ego_network(graph, node_id, hops=1):
"""
Computes the ego network of a specified node within a given number of hops.
Parameters:
- graph (Graph): The graph to compute the ego network from.
- node (str): The node to center the ego network on.
- hops (int): The number of hops to include in the ego network.
Returns:
- pd.DataFrame: A DataFrame containing the edges of the ego network.
"""
with graph.model.query() as select:
node = graph.Node()
node.id == node_id
a,b = graph.compute.ego_network(node, hops=hops)
ego_response = select(alias(graph.Node(a).id, "u"), alias(graph.Node(b).id, "v"))
ego_df = ego_response.results
return ego_df
def create_graph(model, node_set, edge_list, undirected=False):
graph = Graph(model, undirected=undirected)
with model.rule(dynamic=True):
nodes = []
for id in node_set:
node = graph.Node.add(id=id)
nodes.append(node)
for e in edge_list:
u, v = e[0]-1, e[1]-1
graph.Edge.add(nodes[u], nodes[v])
return graph
📎 Egonet extraction
Let's create a directed graph with a simple community structure: a 4-node clique connected by an edge to a 3-node triangle, plus two isolated nodes. The ego_network function assumes the input graph is directed; for undirected graphs, each undirected edge is represented as two directed edges.
In [3]:
model = rai.Model("Demo_Egonets", keep_model=False)
In [4]:
# Graph structure:
#
# K4 (complete graph on 4 nodes) ----- 5 8, 9 (isolated nodes)
# / \
# 6---7
#
# Edge list:
num_nodes = 9
edge_list = [(1,2), (1,3), (1,4), (2,3), (2,4), (3,4), # 4-clique
(4,5), # edge connecting K4 to node 5
(5,6), (5,7), (6,7) # triangle connected via node 5
]
graph = create_graph(model, range(1,num_nodes+1), edge_list, undirected=True)
graph_style = {
"node": {
"label": lambda n: str(n.get("id")), # or any other key, e.g., "name"
"color": "#92979c",
"size": 10,
},
"edge": {
"color": "#cccccc",
}
}
# let's visualize it
graph.visualize(
three=True,
node_label_size_factor=1.9,
use_links_force=True,
node_hover_neighborhood=True,
style=graph_style
)
▰▰▰▰ Setup complete
Out[4]:
Details for selected element
We now demonstrate how to compute the egonetwork of a specific node.
- Here, we choose node 1 (i.e., node_id=1) with a radius of 2 hops.
- This is done using the compute_ego_network function, which takes the model, graph, node ID, and hop count, and returns a DataFrame containing the edge list of the induced subgraph. We then pass this output to visualize_ego_network, which provides a basic visualization. This step can be customized to suit your preferred graph visualization tool.
In [ ]:
ego_df = compute_ego_network(graph, node_id=1, hops=2)
Using the create_graph function, we create a graphlib object from the pandas dataframe output.
In [6]:
node_set = set(pd.concat([ego_df['v'], ego_df['u']]))
induced_edge_list = list(ego_df[['u', 'v']].itertuples(index=False, name=None))
ego_graph_of_node_1 = create_graph(model, node_set, induced_edge_list, graph.undirected)
# let's visualize it
ego_graph_of_node_1.visualize(
three=True,
node_label_size_factor=1.9,
use_links_force=True,
node_hover_neighborhood=True,
style=graph_style
)
Out[6]:
Details for selected element
📈 Local Community Analysis
Finally, we apply community detection to the ego-network we have extracted. We use the Louvain algorithm with the default parameter values, which outputs two communities, one consisting of the 3-clique consisting of ndoes 1,2,3 and the other community of nodes 4 and 5.
In [8]:
# Find the community label for each person in the graph.
with model.query() as select:
node = ego_graph_of_node_1.Node()
community = ego_graph_of_node_1.compute.louvain(node)
node.set(community = community)
louvain_response = select(alias(node.id,"node"), alias(community, "community_label"))
louvain_comms = louvain_response.results
print(louvain_comms)
node community_label 0 1 2 1 2 2 2 3 2 3 4 1 4 5 1
In [ ]: