def _train_line( self, ): # train Line model with order self.alpha = self.init_alpha batch_size = self.batch_size t0 = time.time() num_batch = int(self.num_sampling_edge / batch_size) epoch_iter = tqdm(range(num_batch)) for b in epoch_iter: if b % 100 == 0: epoch_iter.set_description( f"Progress: {b *1.0/num_batch * 100:.4f}%, alpha: {self.alpha:.6f}, time: {time.time() - t0:.4f}" ) self.alpha = self.init_alpha * max((1 - b * 1.0 / num_batch), 0.0001) for k in range(self.num_graph): u, v = [0] * batch_size, [0] * batch_size for i in range(batch_size): edge_id = alias_draw(self.edges_prob[k][0], self.edges_prob[k][1]) u[i], v[i] = self.edges[k][edge_id] vec_error = np.zeros((batch_size, self.dimension)) label, target = np.asarray([1 for i in range(batch_size)]), np.asarray(v) for j in range(1 + self.negative): if j != 0: label = np.asarray([0 for i in range(batch_size)]) for i in range(batch_size): neg_node = alias_draw(self.node_prob[k][0], self.node_prob[k][1]) target[i] = self.id2node[k][neg_node] self._update(self.emb_vertex[u], self.emb_context[target], vec_error, label) self.emb_vertex[u] += vec_error
def _train_line(self, order): # train Line model with order self.alpha = self.init_alpha batch_size = self.batch_size t0 = time.time() num_batch = int(self.num_sampling_edge / batch_size) epoch_iter = tqdm(range(num_batch)) for b in epoch_iter: if b % 100 == 0: epoch_iter.set_description( f"Progress: {b *1.0/num_batch * 100:.4f}%, alpha: {self.alpha:.6f}, time: {time.time() - t0:.4f}" ) self.alpha = self.init_alpha * max((1 - b * 1.0 / num_batch), 0.0001) u, v = [0] * batch_size, [0] * batch_size for i in range(batch_size): edge_id = alias_draw(self.edges_table, self.edges_prob) u[i], v[i] = self.edges[edge_id] if not self.is_directed and np.random.rand() > 0.5: v[i], u[i] = self.edges[edge_id] vec_error = np.zeros((batch_size, self.dimension)) label, target = np.asarray([1 for i in range(batch_size)]), np.asarray(v) for j in range(1 + self.negative): if j != 0: label = np.asarray([0 for i in range(batch_size)]) for i in range(batch_size): target[i] = alias_draw(self.node_table, self.node_prob) if order == 1: self._update(self.emb_vertex[u], self.emb_vertex[target], vec_error, label) else: self._update(self.emb_vertex[u], self.emb_context[target], vec_error, label) self.emb_vertex[u] += vec_error
def _path_sampling(self, u, v, r): # sample a r-length path from edge(u, v) and return path end node k = np.random.randint(r) + 1 zp, rand_u, rand_v = 2.0 / self.node_weight[u][v], k - 1, r - k for i in range(rand_u): new_u = self.neighbors[u][alias_draw(self.alias_nodes[u][0], self.alias_nodes[u][1])] zp += 2.0 / self.node_weight[u][new_u] u = new_u for j in range(rand_v): new_v = self.neighbors[v][alias_draw(self.alias_nodes[v][0], self.alias_nodes[v][1])] zp += 2.0 / self.node_weight[v][new_v] v = new_v return u, v, zp
def _node2vec_walk(self, walk_length, start_node): # Simulate a random walk starting from start node. G = self.G alias_nodes = self.alias_nodes alias_edges = self.alias_edges walk = [start_node] while len(walk) < walk_length: cur = walk[-1] cur_nbrs = list(G.neighbors(cur)) if len(cur_nbrs) > 0: if len(walk) == 1: walk.append(cur_nbrs[alias_draw(alias_nodes[cur][0], alias_nodes[cur][1])]) else: prev = walk[-2] next = cur_nbrs[alias_draw(alias_edges[(prev, cur)][0], alias_edges[(prev, cur)][1])] walk.append(next) else: break return walk