4.3 Stochastic Block Models

4.3 Stochastic Block Models#

mode = "svg"

import matplotlib

font = {'family' : 'Dejavu Sans',
        'weight' : 'normal',
        'size'   : 20}

matplotlib.rc('font', **font)

import matplotlib
from matplotlib import pyplot as plt
from graphbook_code import plot_vector
import numpy as np
import os

n = 100  # number of students

fig, axs = plt.subplots(1, 2, figsize=(10, 5), gridspec_kw={"width_ratios": [.3, 1]})
# z is a column vector of 50 1s followed by 50 2s
# this vector gives the school each of the 100 students are from
z = np.repeat([1, 2], repeats=n//2)
plot_vector(z.astype(int), title="(A) $\\vec z$, Node Assignment Vector",
            legend_title="School", 
            ticks=[0.5, 49.5, 99.5], ticklabels=[1, 50, 100],
            ticktitle="Student", ax=axs[0])

from graphbook_code import heatmap

K = 2  # community count
# construct the block matrix B as described above
B = np.array([[0.6, 0.1], 
              [0.1, 0.4]])

heatmap(B, xticklabels=[1, 2], yticklabels=[1,2], vmin=0, 
             vmax=1, annot=True, xtitle="School",
             ytitle="School", title="(B) Block Matrix $B$", legend_title="Block probability", ax=axs[1])

fig.tight_layout()

os.makedirs("Figures", exist_ok=True)
fname = "sbm"
if mode != "png":
    os.makedirs(f"Figures/{mode:s}", exist_ok=True)
    fig.savefig(f"Figures/{mode:s}/{fname:s}.{mode:s}")

os.makedirs("Figures/png", exist_ok=True)
fig.savefig(f"Figures/png/{fname:s}.png")
../../_images/fde7fdb56a8291b5c661ce699512fcea3db5284a7993d01d70b818033be38996.png
from graspologic.simulations import sbm
from graphbook_code import draw_multiplot

# sample a graph from SBM_{100}(tau, B)
A, labels = sbm(n=[n//2, n//2], p=B, directed=False, loops=False, return_labels=True)
import numpy as np
import os

# generate a reordering of the n nodes
permutation = np.random.choice(n, size=n, replace=False)

Aperm = A[permutation][:,permutation]
yperm = labels[permutation]

fig, axs = plt.subplots(1,2,figsize=(10,5))
heatmap(A.astype(int), vmin=0, vmax=1, cbar=False,
        title="(A) $SBM_{100}(\\vec z, B)$ sample", xtitle="Student", 
        xticks=[0.5, 49.5, 99.5], xticklabels=[1,50,100],
        inner_hier_labels=z,
        ax=axs[0])

heatmap(Aperm.astype(int), title="(B) Same network, but \nnodes randomly reordered", xtitle="Student", 
        xticks=[0.5, 49.5, 99.5], xticklabels=[1,50,100], ytitle="Student", 
        yticks=[0.5, 49.5, 99.5], yticklabels=[1,50,100], legend_title="Edge?",
        ax=axs[1])
fig.tight_layout()

fname = "sbm_adj"
if mode != "png":
    fig.savefig(f"Figures/{mode:s}/{fname:s}.{mode:s}")

fig.savefig(f"Figures/png/{fname:s}.png")
../../_images/3211f56d4f1ed0f027284925f959c3d68250c02ae63ebf26960444b39aa83a8f.png
from graphbook_code import lpm_heatmap


def ohe_comm_vec(z):
    """
    A function to generate the one-hot-encoded community
    assignment matrix from a community assignment vector.
    """
    K = len(np.unique(z))
    n = len(z)
    C = np.zeros((n, K))
    for i, zi in enumerate(z):
        C[i, zi - 1] = 1
    return C

def generate_sbm_pmtx(z, B):
    """
    A function to generate the probability matrix for an SBM.
    """
    C = ohe_comm_vec(z)
    return C @ B @ C.T

# the community assignment vector
z = np.repeat([1, 2], 50)
# block matrix
B = np.array([[0.6, 0.1], 
              [0.1, 0.4]])
# probability matrix
P = generate_sbm_pmtx(z, B)

fig, axs = plt.subplots(1, 4, figsize=(16, 5), gridspec_kw={"width_ratios": [2, 3, 12, 12]})

plot_vector(z.astype(int), title="(A) $\\vec z$",
            legend_title="Community", 
            ticks=[0.5, 49.5, 99.5], ticklabels=[1, 50, 100],
            ticktitle="Node", ax=axs[0])

lpm_heatmap(ohe_comm_vec(z), title="(B) $C$", xticks=[0.5, 1.5], xticklabels=[1,2], xtitle="Community",
            yticks=[0.5, 49.5, 99.5], yticklabels=[1, 50, 100], ytitle="Node",
            ax=axs[1])

heatmap(B, xticklabels=[1, 2], yticklabels=[1,2], vmin=0, 
             vmax=1, annot=True, xtitle="Community",
             ytitle="Community", title="(C) $B$", legend_title="Block probability", ax=axs[2])

heatmap(P, title="(D) $P = CBC^\\top$", xtitle="Node", 
        xticks=[0.5, 49.5, 99.5], xticklabels=[1,50,100], ytitle="Node", 
        yticks=[0.5, 49.5, 99.5], yticklabels=[1,50,100], legend_title="Edge probability",
        ax=axs[3], vmin=0, vmax=1)

fig.tight_layout()

fname = "sbm_prob"
if mode != "png":
    fig.savefig(f"Figures/{mode:s}/{fname:s}.{mode:s}")

fig.savefig(f"Figures/png/{fname:s}.png")
../../_images/d02ebd1540cfbe2fd456bafb24604f3850e6eb7237d15dd42c8665a4b6728bc5.png