# Part 7.4: 그래프 신경망 (GNN)

**⬅️ 이전 시간: [Part 7.3: LangChain으로 LLM 애플리케이션 개발 맛보기](./part_7.3_llm_application_development_with_langchain.md)**
**➡️ 다음 시간: [Part 7.5: 강화학습 (Reinforcement Learning)](./part_7.5_reinforcement_learning.md)**

---

> [!WARNING]
> 이 파트는 현재 준비 중입니다. GNN의 핵심 개념과 PyTorch Geometric을 사용한 실습 코드가 추가될 예정입니다.

## 1. 학습 목표 (Learning Objectives)

이번 파트가 끝나면, 여러분은 다음을 할 수 있게 됩니다.

- 그래프(Graph) 데이터의 구조와 특징을 이해합니다.
- GNN이 왜 필요한지, 기존의 신경망과 무엇이 다른지 설명할 수 있습니다.
- GNN의 핵심 아이디어인 메시지 패싱(Message Passing)의 기본 개념을 이해합니다.
- PyTorch Geometric 라이브러리를 사용하여 간단한 GNN 모델을 구성할 수 있습니다.

## 2. 핵심 키워드 (Keywords)

`그래프 신경망(GNN)`, `그래프 데이터(Graph Data)`, `노드(Node)`, `엣지(Edge)`, `인접 행렬(Adjacency Matrix)`, `메시지 패싱(Message Passing)`, `PyTorch Geometric`

## 3. 도입: 관계를 학습하는 모델, GNN

세상은 연결의 집합입니다.
- **소셜 네트워크**: 사람(노드)들은 친구 관계(엣지)로 연결됩니다.
- **분자 구조**: 원자(노드)들은 화학 결합(엣지)으로 연결됩니다.
- **도로망**: 교차로(노드)들은 도로(엣지)로 연결됩니다.

이처럼 **객체(노드)와 그들의 관계(엣지)로 표현되는 데이터**를 **그래프 데이터**라고 합니다. 기존의 MLP나 CNN, RNN은 이러한 복잡한 관계성을 직접 다루기 어렵습니다.

**그래프 신경망(Graph Neural Network, GNN)**은 그래프 구조 자체를 입력으로 받아, 노드의 특징과 노드 간의 연결 관계를 종합적으로 학습하는 강력한 아키텍처입니다.

---

## 4. GNN의 핵심 아이디어: 메시지 패싱 (Message Passing)

GNN의 핵심 원리는 "이웃 노드로부터 정보를 받아서 나의 정보를 업데이트한다"는 **메시지 패싱** 아이디어로 요약할 수 있습니다.

![Message Passing](https://distill.pub/2021/gnn-intro/images/gnn-computation-2.gif)
*(이미지 출처: distill.pub)*

1.  **메시지 생성**: 각 노드는 자신의 이웃 노드들에게 보낼 '메시지'를 생성합니다.
2.  **정보 취합 (Aggregation)**: 각 노드는 이웃들로부터 받은 메시지들을 하나로 모읍니다. (예: 평균을 내거나, 합산)
3.  **정보 업데이트 (Update)**: 각 노드는 취합된 정보와 자기 자신의 기존 정보를 바탕으로 새로운 상태(표현 벡터)를 계산합니다.

이 과정을 여러 번 반복(여러 GNN 레이어를 쌓음)함으로써, 노드들은 더 멀리 있는 이웃들의 정보까지 전달받아 자신의 표현을 더욱 풍부하게 만들 수 있습니다.

---

## 5. 직접 해보기 (Hands-on Lab): (내용 추가 예정)

PyTorch Geometric 라이브러리를 사용하여 소셜 네트워크의 사용자 직업을 예측하는 GNN 모델을 만들어볼 예정입니다.

---

## 6. 되짚어보기 (Summary)

- **GNN**: 노드와 엣지로 구성된 그래프 구조의 데이터를 직접 처리하기 위한 신경망입니다.
- **핵심 원리**: 이웃 노드와 '메시지'를 주고받으며 자신의 정보를 업데이트하는 **메시지 패싱**을 기반으로 합니다.
- **활용**: 추천 시스템, 신약 개발, 금융 사기 탐지 등 관계 속에서 패턴을 찾아내는 다양한 분야에 활용됩니다.

---

**➡️ 다음 시간: [Part 7.5: 강화학습 (Reinforcement Learning)](./part_7.5_reinforcement_learning.md)**

### 참고 자료

*   [A Gentle Introduction to Graph Neural Networks](https://distill.pub/2021/gnn-intro/): GNN에 대한 시각적이고 직관적인 설명이 담긴 distill.pub 아티클
*   [PyTorch Geometric 라이브러리](https://pytorch-geometric.readthedocs.io/en/latest/): PyTorch 기반의 GNN 라이브러리

---

### ⚠️ What Could Go Wrong? (토론 주제)

GNN은 관계형 데이터를 다루는 강력한 패러다임이지만, 실제 적용 시에는 고유한 기술적 난제들을 마주하게 됩니다.

1.  **과잉 평탄화 문제 (Over-smoothing Problem)**
    *   GNN 레이어를 깊게 쌓았을 때, 여러 홉 떨어진 노드들의 정보가 섞이면서 결국 모든 노드 임베딩이 서로 유사해져 버리는 '과잉 평탄화' 현상이 발생합니다. 이 때문에 깊은 GNN 모델의 성능이 얕은 모델보다 오히려 떨어질 수 있는데, 왜 이런 현상이 발생할까요?
    *   이를 해결하기 위해 제안된 방법들(예: Jumping Knowledge, GCNII, Skip-connection)은 어떤 원리로 이 문제를 완화하며, 각각 어떤 장단점을 가질까요?

2.  **이웃 폭발 및 확장성 문제 (Neighbor Explosion & Scalability Issues)**
    *   하나의 노드 임베딩을 계산하기 위해 이웃 노드들을 재귀적으로 참조하다 보면, 몇 홉만 거쳐도 관련 노드의 수가 기하급수적으로 증가하여 '이웃 폭발'이 발생합니다. 이는 대규모 그래프에서 메모리 부족(Out-of-Memory)과 연산량 폭증의 원인이 됩니다.
    *   GraphSAGE에서 제안한 '이웃 샘플링(Neighbor Sampling)' 방식은 이 문제를 어떻게 해결하나요? 샘플링이 가져오는 성능과 연산량 간의 트레이드오프는 무엇일까요?

3.  **동적 그래프 처리의 어려움 (Difficulty with Dynamic Graphs)**
    *   실세계의 많은 그래프(소셜 네트워크, 금융 거래망)는 시간이 지남에 따라 노드와 엣지가 끊임없이 변하는 '동적 그래프'입니다. 새로운 노드가 추가될 때마다 전체 모델을 다시 학습시켜야 할까요?
    *   시간의 흐름에 따른 변화를 GNN 모델이 학습하게 하려면 어떤 접근법(예: Temporal GNNs)이 필요하며, 기존 GNN과 비교하여 어떤 점이 더 복잡할까요?

4.  **비관계형 데이터에 대한 부적절한 적용 (Inappropriate Application to Non-relational Data)**
    *   모든 데이터를 그래프 형태로 표현할 수는 있지만, 그것이 항상 유용한 것은 아닙니다. 노드 간의 '관계'가 명확하지 않거나 의미 없는 데이터를 억지로 그래프로 구성하여 GNN을 적용하면 어떤 문제가 발생할 수 있을까요?
    *   GNN이 다른 모델(예: CNN, RNN, Transformer)에 비해 확실한 강점을 가지는 데이터의 특징은 무엇이라고 생각하시나요?

5.  **그래프 구조 자체의 편향 (Bias in Graph Structure)**
    *   소셜 네트워크에서 특정 인구 집단이 다른 집단보다 더 촘촘하게 연결된 '에코 체임버'나 '필터 버블'이 존재할 수 있습니다. 이런 편향된 구조를 학습한 GNN 모델이 소수 집단에 대해 불공정한 예측을 내릴 위험은 없을까요? 이러한 구조적 편향을 어떻게 탐지하고 완화할 수 있을까요?

---

## 캡스톤 프로젝트 연계 미니 프로젝트: 소셜 네트워크 기반 친구 추천 시스템

이 챕터에서 배운 GNN의 개념을 활용하여, 15장 캡스톤 프로젝트의 '추천 시스템' 아이디어에 적용해볼 수 있는 미니 프로젝트를 진행합니다. 사용자의 연결 관계(그래프)를 기반으로 새로운 친구를 추천하는 모델을 직접 만들어보면서, GNN의 실용성을 체감하는 것을 목표로 합니다.

### 프로젝트 목표
- `PyTorch Geometric`을 사용하여 소셜 네트워크 데이터를 로드하고 시각화합니다.
- 간단한 GCN(Graph Convolutional Network) 모델을 구축하여, 그래프의 '링크 예측(Link Prediction)' 문제를 해결합니다.
- 특정 사용자가 주어졌을 때, 연결될 가능성이 가장 높은 다른 사용자(새로운 친구)를 추천하는 API의 프로토타입을 구상합니다.

### 개발 과정
1. **데이터셋 선정**: `PyTorch Geometric`에 내장된 `Cora` 또는 `CiteSeer`와 같은 인용 네트워크 데이터셋을 소셜 네트워크라고 가정하고 사용합니다. 각 논문은 '사용자', 인용 관계는 '친구 관계'로 간주합니다.
2. **모델링**:
    - 노드(사용자)의 특징을 입력으로 받아, GCN 레이어를 통과시켜 임베딩을 생성합니다.
    - 두 노드 임베딩의 내적(dot product)을 계산하여, 두 노드 사이에 링크(친구 관계)가 존재할 확률을 예측하는 모델을 만듭니다.
3. **학습 및 평가**:
    - 기존의 링크 중 일부를 일부러 숨기고(train/test split), 모델이 이 숨겨진 링크를 얼마나 잘 예측하는지 평가합니다. (AUC, Accuracy 등)
4. **결과 해석 및 활용**:
    - 학습된 모델을 사용하여, 현재 연결되지 않은 노드 쌍 중에서 연결 확률이 가장 높은 쌍을 찾습니다.
    - 이를 "사용자 A에게 사용자 B, C, D를 추천합니다"와 같은 기능으로 연결하여, 캡스톤 프로젝트에서 만들 최종 서비스의 그림을 그려봅니다.

### 캡스톤 프로젝트 연계 방안
- **추천 시스템 고도화**: 실제 캡스톤 프로젝트에서는 단순 친구 관계를 넘어, '사용자-상품' 관계, '영화-배우-감독' 관계 등 더 복잡한 그래프를 구축하여 GNN 기반 추천 모델을 만들 수 있습니다.
- **FastAPI 연동**: 이 미니 프로젝트에서 개발한 모델을 `part_8_model_serving_with_fastapi.md`에서 배울 FastAPI를 사용해 API로 서빙하는 기능을 구현해볼 수 있습니다. 예를 들어, `GET /users/{user_id}/recommendations` 와 같은 엔드포인트를 설계할 수 있습니다. 