Freeman’s Segregation Index¶
Freeman’s Segregation Index (Freeman, 1978; Bojanowski, 2014) measures segregation by comparing the actual number of cross-group ties in a network to what we would expect if the network’s ties were formed completely at random.
To calculate it, we define two variables:
\(p\) (Observed cross-group density): The actual number of ties between different groups divided by the total possible number of cross-group ties.
\(\pi\) (Expected cross-group density): The overall edge density of the entire graph. In a purely random network, the density of ties between groups would simply equal this overall density.
Using these variables, Freeman’s index is calculated as:
In Freeman’s case, a random network with the same edge density servers as a null-model.
from netseg import freeman
import igraph as ig
import matplotlib.pyplot as plt
from matplotlib.colors import LinearSegmentedColormap, to_hex, Normalize, BoundaryNorm
import random
import numpy as np
from time import perf_counter
from mpl_toolkits.axes_grid1 import make_axes_locatable
from matplotlib.cm import ScalarMappable
import matplotlib.patches as mpatches
%config InlineBackend.figure_format = 'retina'
COLORS = [
'#2C486F',
'#436796',
'#5E8FAE',
'#80BDD6',
'#B1DDE0',
"#fdf8e7",
'#F8E5B2',
'#F3CF63',
'#E9A64C',
'#E3843B',
'#DA584E'
]
def make_symmetric_sbm(p_in, p_out, n_groups, nodes_per_group, membership, **kwargs):
pref_matrix = [
[p_in if i == j else p_out for j in range(n_groups)]
for i in range(n_groups)
]
block_sizes = [nodes_per_group] * n_groups
g = ig.Graph.SBM(pref_matrix, block_sizes, **kwargs)
g.vs['membership'] = membership
return g
Basic Usage¶
membership= [0 if i < 50 else 1 for i in range(100)]
random.seed(2)
g = make_symmetric_sbm(0.08, 0.004, 2, 50,membership, directed = False)
fig, ax = plt.subplots(figsize = (8,8))
ig.plot(g,
vertex_size = 24,
edge_color = "black",
vertex_color = [COLORS[2] if i == 0 else COLORS[-3] for i in membership],
edge_width = 0.3,
edge_arrow_size = .6,
layout = g.layout_kamada_kawai(),
target = ax)
g1 = mpatches.Patch(color = COLORS[2], label = "Group I")
g2 = mpatches.Patch(color = COLORS[-3], label = "Group II")
ax.legend(handles = [g1,g2], loc = "lower right", title = "Nodal Attributes")
plt.show()
freeman_score = freeman("membership",g)
print(freeman_score)
0.8986976744186046
We can generate a random network, since Freeman subtracts a random network with the same edge density, the score should be approximately 0.
g_er = ig.Graph.Erdos_Renyi(100, 0.3)
g_er.vs['membership'] = membership
freeman_random_score = freeman("membership", g_er)
print(freeman_random_score)
-0.0012575250836119878
Multiple Groups¶
membership_multiple = ["foo"] * 50 + ["bar"] * 50 + ["baz"] * 50
colors_dict = {"foo":3, "bar":9, "baz":6}
random.seed(4)
g_multiple = make_symmetric_sbm(0.2, 0.001, 3, 50, membership_multiple, directed = False)
fig, ax = plt.subplots(figsize = (8,8))
ig.plot(g_multiple, vertex_size = 24, edge_arrow_size = .6, edge_width = .3, layout = g_multiple.layout_kamada_kawai(), vertex_color = [COLORS[colors_dict[i]] for i in membership_multiple],target = ax)
g1 = mpatches.Patch(color = COLORS[3], label = "Group I")
g2 = mpatches.Patch(color = COLORS[6], label = "Group II")
g3 = mpatches.Patch(color = COLORS[9], label = "Group II")
ax.legend(handles = [g1,g2,g3], loc = "lower right", title = "Nodal Attributes")
plt.show()
freeman_multiple = freeman("membership", g_multiple)
print(freeman_multiple)
0.9921164021164021
Example¶
We use the “UK Faculty” dataset to demonstrate the Freeman’s Segregation Index. Edges indicate personal friendship connections between faculty members at a UK university. We measure the segregation with the nodal attribute “Group”, which represents the school affiliation of each individual. Original dataset can be found here.
COLORS = [
"#9B4D2E",
"#A8952A",
"#2A5C4A",
"#2A415C"]
g_example = ig.Graph.Read_GML('../assets/uk_faculty/ukfaculty.gml')
colors_dict = dict(zip(set(g_example.vs['Group']), COLORS))
fig, ax = plt.subplots(figsize = (8,8))
ig.plot(g_example, layout = g_example.layout_kamada_kawai(),
vertex_size = 24, target = ax, vertex_color = [colors_dict.get(i) for i in g_example.vs['Group']],
edge_width = .3)
plt.show()
freeman_score_example = freeman("Group", g_example)
print(freeman_score_example)
0.7246273651555877
References¶
Bojanowski, M., & Corten, R. (2014). Measuring segregation in social networks. Social networks, 39, 14-32.
Freeman, L. C. (1978). Segregation in social networks. Sociological Methods & Research, 6(4), 411-429.