Source code for opengsl.data.preprocess.control_homophily

from opengsl.utils.utils import get_homophily
import numpy as np


[docs]def control_homophily(adj, labels, homophily): ''' Control the homophily of original structure by adding edges. More ways to add perturbations will be implemented soon. Parameters ---------- adj : torch.tensor The original structure in sparse form. labels : torch.tensor Ground truth labels. homophily : float Homophily ratio. Returns ------- new_adj : torch.tensor The perturbed structure in sparse form. ''' np.random.seed(0) # change homophily through adding edges adj = adj.to_dense() n_edges = adj.sum()/2 n_nodes = len(labels) homophily_orig = get_homophily(labels, adj, 'edge') # print(homophily_orig) if homophily<homophily_orig: # add noisy edges n_add_edges = int(n_edges*homophily_orig/homophily-n_edges) while n_add_edges>0: u = np.random.randint(0, n_nodes) vs = np.arange(0, n_nodes)[labels!=labels[u]] v = np.random.choice(vs) if adj[u, v]==0: adj[u,v]=adj[v,u]=1 n_add_edges-=1 if homophily>homophily_orig: # add helpful edges n_add_edges = int(n_edges*(1-homophily_orig)/(1-homophily)-n_edges) while n_add_edges > 0: u = np.random.randint(0, n_nodes) vs = np.arange(0, n_nodes)[labels==labels[u]] v = np.random.choice(vs) if u==v: continue if adj[u,v]==0: adj[u,v]=adj[v,u]=1 n_add_edges -= 1 return adj.to_sparse()