def get_alias_edge(self, G, src, dst, p, q): """ Prepare probabilities of edges for Second Order random walk Arguments: src {int} -- source node of the first step dst {int} -- destination node of the first step """ G = self.G p = self.p q = self.q unnormalized_probs = [] for nbr in sorted(G.neighbors(dst)): if nbr == src: G[dst][nbr]['weight'] = 1 / p elif G.has_edge(src, nbr): G[dst][nbr]['weight'] = 1 else: G[dst][nbr]['weight'] = 1 / q unnormalized_probs.append(G[dst][nbr]['weight']) Z = sum(unnormalized_probs) normalized_probs = [float(prob) / Z for prob in unnormalized_probs] return alias_setup(normalized_probs)
def preprocess_nodesdegrees(self): time_start = time.time() logger.info( "preprocessing nodesdegrees with distortion_power = {} ...".format( self._distortion_power)) self._nodes_type_dict = {} for node_type in self._net.node_types: self._nodes_type_dict[node_type] = [[], None] # [nodes, nodes_degrees] for node in self._net.nodes: node_type = self._net.get_node_type(node) self._nodes_type_dict[node_type][0].append(node) # self._nodes_type_dict[node_type][1].append(net.get_degrees(node)) if self._distortion_power == 0: pass else: for node_type in self._nodes_type_dict.keys(): nodes_degrees = self._net.get_degrees( self._nodes_type_dict[node_type][0]) normed_degrees = np.power(nodes_degrees, self._distortion_power) normed_degrees = normed_degrees / np.sum(normed_degrees) if np.sum(normed_degrees) != 1.: normed_degrees = normed_degrees / np.sum(normed_degrees) if np.sum(normed_degrees) != 1.: normed_degrees = normed_degrees / np.sum(normed_degrees) alias_nodesdegrees = utils.alias_setup(normed_degrees) # J, q self._nodes_type_dict[node_type][1] = alias_nodesdegrees logger.info('nodesdegrees processed in {}s'.format(time.time() - time_start))
def PreProcessModifiedWeights(self, G, p, q): """ Prepares the lookuptable probabilites for the Biased Random Walk sampling method (Alias Method) Arguments: G {graph} -- graph being analyzed by the algorithm p {float} -- "Return" hyperparameter q {float} -- "In-Out" hyperparameter """ self.G = G self.p = p self.q = q alias_nodes = {} for node in G.nodes(): unnormalized_probs = [ G[node][nbr]['weight'] for nbr in sorted(G.neighbors(node)) ] Z = sum(unnormalized_probs) normalized_probs = [float(prob) / Z for prob in unnormalized_probs] alias_nodes[node] = alias_setup(normalized_probs) #print(alias_nodes[node]) alias_edges = {} for edge in G.edges(): alias_edges[edge] = self.get_alias_edge(G, edge[0], edge[1], p, q) alias_edges[(edge[1], edge[0])] = self.get_alias_edge( G, edge[1], edge[0], p, q) self.alias_nodes = alias_nodes self.alias_edges = alias_edges #print(alias_edges) #print(alias_nodes) return
def _preprocess_transition_probs(self, nodes): ''' Preprocessing of second-order transition probabilities for guiding the bias random walks. process a probabilities list for each edge in a sparse network, for memory saving. ''' # alias_nodes = {} # not used in unweighted network. # for node in range(self._walk_nodes_size): # unnormalized_probs = [1 for nbr in self._net._nodes_adjlist[node]] # norm_const = sum(unnormalized_probs) # normalized_probs = [float(u_prob) / norm_const for u_prob in unnormalized_probs] # norm_const = sum(normalized_probs) # if norm_const != 1.: # normalized_probs = [float(u_prob) / norm_const for u_prob in normalized_probs] # alias_nodes[node] = utils.alias_setup(normalized_probs) # Get the alias edge setup lists for a given edge. alias_edges = {} # for src, adj_list in self._net._nodes_adjlist.items(): for src in nodes: adj_list = self._net._nodes_adjlist[src] for dst in adj_list: unnormalized_probs = [] for dst_nbr in self._net._nodes_adjlist[dst]: if dst_nbr == src: unnormalized_probs.append(1.0 / self._p) elif self._net.has_edge(src, dst_nbr): unnormalized_probs.append(1.0) else: unnormalized_probs.append(1.0 / self._q) norm_const = sum(unnormalized_probs) normalized_probs = [ float(u_prob) / norm_const for u_prob in unnormalized_probs ] norm_const = sum(normalized_probs) if norm_const != 1.: normalized_probs = [ float(u_prob) / norm_const for u_prob in normalized_probs ] alias_edges[(src, dst)] = utils.alias_setup(normalized_probs) # self._alias_nodes = alias_nodes # self._alias_edges = alias_edges return alias_edges
def preprocess_nodesdegrees(self, net_info_path="./net.info"): if self._distortion_power == 0: self._alias_nodesdegrees = None else: time_start = time.time() net_dir = os.path.split(net_info_path)[0] alias_nodesdegrees_path = os.path.join( net_dir, "alias_nodesdegrees_power_{}.pickle".format( self._distortion_power)) if os.path.exists(alias_nodesdegrees_path): logger.info("reading nodesdegrees from {}".format( alias_nodesdegrees_path)) self._alias_nodesdegrees = pickle.load( open(alias_nodesdegrees_path, "rb")) logger.info('nodesdegrees readed in {}s'.format(time.time() - time_start)) return if not os.path.exists(net_dir): os.makedirs(net_dir) logger.info( "preprocessing nodesdegrees with distortion_power = {} ...". format(self._distortion_power)) nodes_degrees = [ self._net.get_degrees(v) for v in self._walk_nodes ] normed_degrees = np.power(nodes_degrees, self._distortion_power) normed_degrees = normed_degrees / np.sum(normed_degrees) if np.sum(normed_degrees) != 1.: normed_degrees = normed_degrees / np.sum(normed_degrees) if np.sum(normed_degrees) != 1.: normed_degrees = normed_degrees / np.sum(normed_degrees) self._alias_nodesdegrees = utils.alias_setup( normed_degrees) # J, q pickle.dump(self._alias_nodesdegrees, open(alias_nodesdegrees_path, "wb"), -1) logger.info('nodesdegrees processed in {}s'.format(time.time() - time_start))