Deep Learning

[Paper] Link Prediction Based on Graph Neural Networks

ju_young 2023. 4. 23. 17:20
728x90

A theory for unifying link prediction heuristics

Definition 1. (Enclosing subgraph)

  • graph $G = (V, E)$
  • $x, y \in V$
  • $G^{h}_{x,y}$ = h-hop enclosing subgraph for (x, y)

Theorem 1.

  • high-order heuristics를 학습하면 small h도 실현 가능
  • γ-decaying heuristic가 h-hop enclosing subgraph로 아주 잘 근사할 수 있음
  • 거의 모든 high-order heuristics가 γ-decaying heuristic으로 통합될 수 있음

Code

아래 깃헙 코드를 확인해보면 dgl 라이브러리를 사용하여 간단하게 dgl.node_subgraph로 subgraph를 얻는 것을 확인할 수 있다.

# https://github.com/dmlc/dgl/blob/master/examples/pytorch/seal/sampler.py
class SEALSampler(object):

    ...

    def sample_subgraph(self, target_nodes):
        """
        Args:
            target_nodes(Tensor): Tensor of two target nodes
        Returns:
            subgraph(DGLGraph): subgraph
        """
        sample_nodes = [target_nodes]
        frontiers = target_nodes

        for i in range(self.hop):
            frontiers = self.graph.out_edges(frontiers)[1]
            frontiers = torch.unique(frontiers)
            sample_nodes.append(frontiers)

        sample_nodes = torch.cat(sample_nodes)
        sample_nodes = torch.unique(sample_nodes)
        subgraph = dgl.node_subgraph(self.graph, sample_nodes)

    ...

 

SEAL: An implemetation of the theory using GNN

다음 3 step으로 진행된다.

1) enclosing subgraph extraction

2) node information matrix construction

3) GNN learning

 

GNN은 일반적으로 (A, X)를 입력으로 받는다. A는 enclosing subgraph의 adjacency matrix(인접행렬)이고 X는 node information matrix이다. 그리고 matrix X는 3가지 components (structural node labels, node embeddings and node attributes)를 가진다.

Node labeling

  • Double-Radius Node Labeling (DRNL)을 제안
  • node $i$에 주는 label을 $f_l (i)$라 한다면 수식을 다음과 같이 나타낸다.

# https://github.com/dmlc/dgl/blob/master/examples/pytorch/seal/utils.py
def drnl_node_labeling(subgraph, src, dst):
    """
    Double Radius Node labeling
    d = r(i,u)+r(i,v)
    label = 1+ min(r(i,u),r(i,v))+ (d//2)*(d//2+d%2-1)
    Isolated nodes in subgraph will be set as zero.
    Extreme large graph may cause memory error.
    Args:
        subgraph(DGLGraph): The graph
        src(int): node id of one of src node in new subgraph
        dst(int): node id of one of dst node in new subgraph
    Returns:
        z(Tensor): node labeling tensor
    """
    adj = subgraph.adj_external().to_dense().numpy()
    src, dst = (dst, src) if src > dst else (src, dst)

    idx = list(range(src)) + list(range(src + 1, adj.shape[0]))
    adj_wo_src = adj[idx, :][:, idx]

    idx = list(range(dst)) + list(range(dst + 1, adj.shape[0]))
    adj_wo_dst = adj[idx, :][:, idx]

    dist2src = shortest_path(
        adj_wo_dst, directed=False, unweighted=True, indices=src
    )
    dist2src = np.insert(dist2src, dst, 0, axis=0)
    dist2src = torch.from_numpy(dist2src)

    dist2dst = shortest_path(
        adj_wo_src, directed=False, unweighted=True, indices=dst - 1
    )
    dist2dst = np.insert(dist2dst, src, 0, axis=0)
    dist2dst = torch.from_numpy(dist2dst)

    dist = dist2src + dist2dst
    dist_over_2, dist_mod_2 = dist // 2, dist % 2

    z = 1 + torch.min(dist2src, dist2dst)
    z += dist_over_2 * (dist_over_2 + dist_mod_2 - 1)
    z[src] = 1.0
    z[dst] = 1.0
    z[torch.isnan(z)] = 0.0

    return z.to(torch.long)

 

Incorporating latent and explicit features

sampled positive training links ($E_p \subseteq E$)와 sampled negative training links ($E_n \cap E = \varnothing$) 를 주고 학습을 시키면 link existence information를 빠르게 찾아내며 그에 맞게 최적화된다. 하지만 이런 결과는 generalization(일반화) 성능에 좋지않아 하나의 트릭을 적용했다.

 

negative injection

negative training link를 E에 추가하여 $G^` = (V, E \cup E_n)$에서 embedding을 만들어 성능을 향상시켰다.

 

* dgl.dataloading.negative_sampler를 사용하여 적용할 수 있다.

 

 

리뷰를 마치며...

 

link prediction task에 관심을 가지고 리뷰를 하게된 이유는 어떤 도형, 선(line)으로 이루어진 2D shape이 있다면 close 상태인지 open 상태인지를 구별할 수 있지 않을까 라는 생각을 시작으로 알아보게 되었다. 예를 들어서 사각형이 4개의 선(line)으로 이루어져있고 실제로 눈으로 ㅁ과 같이 사각형으로 보이긴 하지만 실제로는 각 선(line)의 끝점이 아주 미세하게 일치하지 않을 수가 있다. 즉, open되어 있는 상태이기때문에 link prediction을 통해 끝점(node)들을 연결할 수 있지 않을까 생각된다.

 

[reference]

https://wikidocs.net/178479

https://github.com/dmlc/dgl/blob/master/examples/pytorch/seal/sampler.py

https://towardsdatascience.com/seal-link-prediction-explained-6237919fe575

 

728x90