Graph data Split : 그래프 데이터 분할

강하예진(Erica)·2023년 4월 30일
1

Graph Neural Network

목록 보기
4/10

Graph Data를 train-test 셋으로 나누는 가장 일반적인 방법은 노드 기반 분할(Node-based splitting)과 엣지 기반 분할(Edge-based splitting)이다.
노드 기반 분할과 엣지 기반 분할의 차이점은 데이터 분할의 핵심이 노드 정보인지 엣지 정보인지에 있다.
또한 Task마다 Graph 분할 방법은 그래프의 구조와 모델의 목적에 따라 선택하는 것이 좋다.

Split Fundamentals

그래프 데이터를 분할하는 원리는 전체 데이터를 무작위로 섞은 후, 지정한 비율에 따라 노드 또는 엣지를 train과 test 셋으로 분할하는 것이다.
노드에 대한 정보를 기반으로 학습하고 예측하는 것이 중요한 경우에는 Node-based splitting 방식으로 그래프의 노드를 분할하고, 엣지에 대한 정보를 기반으로 학습하고 예측하는 것이 중요한 task라면 그래프의 엣지를 분할하는 Edge-based splitting을 진행한다.

Node-based splitting

노드 기반 분할에서는 전체 노드 집합을 train, test (그리고 선택적으로 validation) 셋으로 분할한다.
전체 노드 집합을 셔플한 다음 일정 비율로 분할하는 방식이다. PyTorch Geometric의 random_node_split() 유틸리티 함수를 사용할 수 있다.
전체 노드 집합을 셔플한 다음 일정 비율로 분할하는 방법이다. 앞서 언급한 유틸리티 함수는 랜덤하게 나누는 것이 특징이다. 노드 정보를 기반으로 학습하고 예측한다면 노드 기반 분할이 적합하다. 이 경우 전체 데이터를 Data() 메서드에 넣어 그래프 데이터를 먼저 만들어낸 다음, train_mask를 적용한다. train_mask는 학습에 사용될 노드를 선택하는 데 사용된다.

from torch_geometric.data import random_node_split

train_data, test_data = random_node_split(graph_data, train_ratio=0.8, test_ratio=0.2)

Edge-based splitting

엣지 기반 분할은 전체 엣지 집합을 train, test (validation) 셋으로 분할한다.
다시 말해, 전체 엣지 집합을 셔플한 다음 일정 비율로 분할하는 방식이다. PyTorch Geometric에는 random_edge_split()의 유틸리티 함수를 사용하면 된다.

전체 엣지 집합을 train-test 세트로 분할한다. 전체 엣지 집합을 셔플한 뒤 분할하고, 역시 랜덤하게 나눈다. 엣지 정보를 기반으로 학습하고 예측한다면 노드 기반 분할이 더 적합하다.

from torch_geometric.data import random_edge_split

train_data, test_data = random_edge_split(graph_data, train_ratio=0.8, test_ratio=0.2)

엣지 정보에는 다음과 같은 정보가 포함될 수 있다.

  • Direction(방향성): 방향성이 있는 그래프에서 엣지는 노드 간의 관계가 단방향(Directional)인지 양방향(Bidirectional)인지를 나타s낸다.
  • Time Stamp(타임스탬프): 시간 순서가 있는 그래프에서 엣지는 노드 간의 관계가 발생한 시점을 나타낼 수 있다.
  • Label(레이블): 엣지에 레이블을 붙여 노드 간의 관계 유형을 표현할 수 있다. 예를 들어, 소셜 네트워크에서 친구 관계, 가족 관계, 동료 관계 등 다양한 레이블을 사용할 수 있다.
  • Attribute(속성): 엣지에는 다양한 속성 정보가 포함될 수 있다. 예를 들어, 교통 네트워크에서 도로 간의 거리, 통행료, 속도 제한 등의 속성이 포함될 수 있다.

이런 정보는 edge_attr 텐서를 통해 모델에 전달할 수 있다. 텐서는 (E, F_edge)의 형태를 가지며, 여기서 E는 엣지 수이고, F_edge는 엣지 특성의 수이다. SAGEConv 레이어는 기본적으로 노드 정보와 연결 관계만 처리하지만, 다음과 같이 사용자 정의 GNN 레이어를 작성하여 엣지 정보를 추가로 처리할 수 있다.

class CustomGNNLayer(torch.nn.Module):
    def __init__(self, ...):
        super(CustomGNNLayer, self).__init__()
        # Initialize the necessary layers and parameters.

    def forward(self, x, edge_index, edge_attr):
        # Process the input node features (x), edge connections (edge_index), and edge features (edge_attr).
        # Return the updated node features.

advance

explicit한 평점 정보가 모델 학습에 중요하다면, 엣지 기반 분할이 유리하다. 사용자-도서 간의 선호정보를 나타내는 도서 평점 정보가 pair구조를 유지하며 학습에 반영되어야 하기 때문이다.
이때는 먼저 평점을 고려한 유저-도서 행렬을 랜덤하게 분할하고, train-test로 나눈 다음 Data()메서드에 전달해 그래프를 생성하면 된다. 이렇게 하면 도서와 사용자 간의 상호작용을 고려한 추천 시스템의 성능을 더 정확하게 평가할 수 있다. 각 엣지는 도서와 사용자 간의 특정 상호작용을 나타내므로, 이를 유지한 상태로 데이터를 나누는 것이 중요하다.

사실 무작위로 노드를 선택하는 방식은 도서와 사용자 간의 상호작용을 고려하지 않고 노드를 선택하므로, 그래프 데이터의 구조를 왜곡할 수 있다. 이로 인해 모델의 성능 평가가 정확하지 않을 수 있다.
예를 들어 사용자-영화 평점 데이터를 통해 회귀 예측을 하는 Task의 경우, 노드 기반 분할이나 엣지 기반 분할 대신, 사용자와 영화 사이의 평점을 고려한 분할 방법을 사용하는 것이 좋을 것이다. 이 방법은 엄밀히 따지자면 Edge-based splitting겠지만, 사용자와 영화 사이의 모든 평점을 포함한 Edge list를 먼저 생성한다는 점이 random split과는 다른 점이다.
이렇게 하면 사용자와 영화 사이의 평점 정보를 유지하면서 그래프 데이터를 train과 test 셋으로 분할할 수 있다.

물론 이렇게 하지 않고 전체 데이터를 그래프 데이터로 만든 뒤 train_mask와 test_mask를 적용할 수도 있다.
하지만 [ 도서 사이의 평점 정보를 유지하면서 그래프 데이터를 train과 test 셋으로 분할하고, 모든 노드를 학습에 사용]하는 방식에서는 도서 사이의 평점 정보를 유지하면서 그래프 데이터를 train과 test 셋으로 분할한다. 이는 도서와 사용자 간의 상호작용을 고려한 추천 시스템의 성능을 더 정확하게 평가할 수 있다. 각 엣지는 도서와 사용자 간의 특정 상호작용을 나타내므로, 이를 유지한 상태로 데이터를 나누는 것이 중요하다.

반대로[전체 데이터를 그래프 데이터로 만든 뒤 train_mask와 test_mask를 사용]하는 방식에서는 train_mask와 test_mask를 사용하여 무작위로 노드를 선택한다. 이 방식은 도서와 사용자 간의 상호작용을 고려하지 않고 노드를 선택하므로, 그래프 데이터의 구조를 왜곡할 수 있습니다. 이로 인해 모델의 성능 평가가 정확하지 않을 수 있다.

따라서, 주어진 작업에는 도서 사이의 평점 정보를 유지하면서 그래프 데이터를 train과 test 셋으로 분할하는 1번 방식이 더 낫다.

여담이지만 같은 데이터셋을 노드기반 분할방식과 엣지 기반 방식으로 분할한 다음 모델을 각각 학습해서 앙상블을 할 수도 있는데, 각 모델의 예측을 평균하거나 가중치를 주어 결합할 수 있다. 이 방식이 유의미한지 여부는 데이터셋과 문제에 따라 달라진다. 실험을 통해 앙상블이 성능을 향상시키는지 확인할 수 있다.

profile
Recommend System & BackEnd Engineering

0개의 댓글