3.8 Edge-weight global rescaling

3.8 Edge-weight global rescaling#

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 graspologic.simulations import sbm
import numpy as np
from graphbook_code import heatmap
from graspologic.utils import symmetrize
from graspologic.utils import is_unweighted, is_loopless, is_symmetric

wtargsa = [[dict(n=50, p=.09), dict(n=50, p=.02)],
          [dict(n=50, p=.02), dict(n=50, p=.06)]]
# activity network as upper triangle matrix
A_activity_uppertri = sbm(n=[25, 25], p=[[1,1], [1,1]], wt=np.random.binomial, wtargs=wtargsa, loops=False, directed=False)
A_activity_uppertri = np.triu(A_activity_uppertri)
# upper-triangle symmetrize the upper triangle
A_activity = symmetrize(A_activity_uppertri, method="triu")

# friend network
wtargsf = [[dict(a=4, b=2), dict(a=2, b=6)],
          [dict(a=2, b=6), dict(a=6, b=2)]]
A_friend = sbm(n=[25, 25], p=[[.8, .4], [.4, 1]], wt=np.random.beta, wtargs=wtargsf, directed=True)
from scipy.stats import zscore

def z_score_loopless(X, undirected=False):
    if not is_loopless(X):
        raise TypeError("The network has loops!")
    if is_symmetric(X):
        raise TypeError("The network is undirected!")
    # the entries of the adjacency matrix that are not on the diagonal
    non_diag_idx = np.where(~np.eye(X.shape[0], dtype=bool))
    Z = np.zeros(X.shape)
    Z[non_diag_idx] = zscore(X[non_diag_idx])
    return Z

ZA_friend = z_score_loopless(A_friend)
from graspologic.utils import pass_to_ranks

RA_friend = pass_to_ranks(A_friend)
from seaborn import histplot
import os

fig, axs = plt.subplots(2,2, figsize=(15, 8), gridspec_kw={"height_ratios": [1, .5]})

def discard_diagonal(A):
    """
    A function that discards the diagonal of a matrix,
    and returns its non-diagonal edge-weights.
    """
    # create a mask that is True for the non-diagonal edges
    non_diag_idx = np.where(~np.eye(A.shape[0], dtype=bool))
    return A[non_diag_idx].flatten()
# get the non-diagonal edge-weights
friend_nondiag_ew = discard_diagonal(A_friend)
# get the non-zero, non-diagonal edge weights
friend_nondiag_nz_ew = friend_nondiag_ew[friend_nondiag_ew > 0]

heatmap(A_friend, xticks=[0, 24, 49], yticks=[0, 24, 49],
        xtitle="Student", ytitle="Student", xticklabels=[1,25,50],
        yticklabels=[1,25,50], vmin=0, vmax=1, ax=axs[0][0])
axs[0][0].set_title("(A) Friendship network")

histplot(friend_nondiag_nz_ew, bins=20, binrange=(0, 1), ax=axs[1][0], color="gray")
axs[1][0].set_xlabel("Edge-weight")
axs[1][0].set_title("(C) Edge-weight distribution")


# get the non-diagonal edge-weights
friend_nondiag_ra = discard_diagonal(RA_friend)
# get the non-zero, non-diagonal edge weights
friend_nondiag_nz_ra = friend_nondiag_ra[friend_nondiag_ra > 0]

heatmap(RA_friend, xticks=[0, 24, 49], yticks=[0, 24, 49],
        xtitle="Student", ytitle="Student", xticklabels=[1,25,50],
        yticklabels=[1,25,50], vmin=0, vmax=1, ax=axs[0][1])
axs[0][1].set_title("(B) ptr(friendship network)")

histplot(friend_nondiag_nz_ra, bins=20, binrange=(0, 1), ax=axs[1][1], color="gray")
axs[1][1].set_xlabel("ptr(edge-weight)")
axs[1][1].set_title("(D) ptr(edge-weight) distribution")


fig.tight_layout()

os.makedirs("Figures", exist_ok=True)
fname = "ptr"
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/4aa8e46bb8f532afe124618ba42aaf629f58ffb4c5a8a8e4894b25d7e58dccf9.png
RA_friend_zb = pass_to_ranks(A_friend, method="zero-boost")

fig, axs = plt.subplots(1,2, figsize=(15,5), gridspec_kw={"width_ratios": [1.2, 2]})

# get the non-diagonal edge-weights
friend_nondiag_razb = discard_diagonal(RA_friend_zb)
# get the non-zero, non-diagonal edge weights
friend_nondiag_nz_razb = friend_nondiag_razb[friend_nondiag_razb > 0]

heatmap(RA_friend_zb, xticks=[0, 24, 49], yticks=[0, 24, 49],
        xtitle="Student", ytitle="Student", xticklabels=[1,25,50],
        yticklabels=[1,25,50], vmin=0, vmax=1, ax=axs[0])
axs[0].set_title("(A) zbptr(friendship network)")

histplot(friend_nondiag_nz_razb, bins=20, binrange=(0, 1), ax=axs[1], color="gray")
axs[1].set_xlabel("zbptr(edge-weight)")
axs[1].set_title("(B) zbptr(edge-weight) distribution")
fig.tight_layout()

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

fig.savefig(f"Figures/png/{fname:s}.png")
../../_images/c5ae04277b11ddec7876265ac50fedb48f7e3be8dc05f9bd8dfa871bbb7a58e0.png
fig, axs = plt.subplots(1, 2, figsize=(15, 5))

# find the indices which are in the upper triangle and not in the diagonal
upper_tri_non_diag_idx = np.where(np.triu(np.ones(A_activity.shape), k=1).astype(bool))
histplot(A_activity[upper_tri_non_diag_idx].flatten(), color="gray", ax=axs[0])
axs[0].set_title("(A) Upper triangle edge-weight distribution")
axs[0].set_xlabel("Edge-weight")

x = np.linspace(.001, 10000, num=10000)
logx = np.log10(x)
axs[1].plot(x, logx, color="black")
axs[1].set_xlabel("$x$")
axs[1].set_ylabel("$log_{10}(x)$")
axs[1].set_title("(B) Values of the logarithm function")
fig.tight_layout()

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

fig.savefig(f"Figures/png/{fname:s}.png")
../../_images/1a956fcb68db8f37afc117721c48c280e16b17dbf36354fe45e5e6cb94730a56.png
def augment_zeros(X, base=10):
    if np.any(X < 0):
        raise TypeError("The logarithm is not defined for negative values!")
    am = np.min(X[np.where(X > 0)])  # the smallest non-zero entry of X
    eps = am/base  # epsilon is one order of magnitude smaller than the smallest non-zero entry
    return X + eps  # augment all entries of X by epsilon
def log_transform(X, base=10):
    """
    A function to log transform an adjacency matrix X, which may
    have zero-weight edges.
    """
    X_aug = augment_zeros(X, base=base)
    return np.log(X_aug)/np.log(base)

A_activity_log = log_transform(A_activity)

fig, axs = plt.subplots(1, 2, figsize=(12, 5))
heatmap(A_activity, xticks=[0, 24, 49], yticks=[0, 24, 49],
        xtitle="Student", ytitle="Student", xticklabels=[1,25,50],
        yticklabels=[1,25,50], ax=axs[0])
axs[0].set_title("(A) Activity/hobby network")

heatmap(A_activity_log, xticks=[0, 24, 49], yticks=[0, 24, 49],
        xtitle="Student", ytitle="Student", xticklabels=[1,25,50],
        yticklabels=[1,25,50], vmin=0, vmax=1, ax=axs[1])
axs[1].set_title("(A) log-xfm activity/hobby network")
fig.tight_layout()

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

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