[AI 실험실]/[개인 프로젝트] GNN / GNN | Propagation feature correlation 진단 추가.md

GNN | Propagation feature correlation 진단 추가

조회

2026년 4월 14일 | 개인 프로젝트


propagated_cosine_2hop를 빼면 mean AUC가 0.7389까지 올라가는데, propagated_cosine_residual을 빼면 0.6444까지 떨어졌다. 직전까지는 이 차이를 feature importance 표만 보면서 읽고 있었는데, 그 방식이 슬슬 답답해졌다. 어떤 feature가 상위권인지까지는 보이지만, 그 feature가 정말 새 신호인지 아니면 이미 있는 축을 다른 이름으로 다시 적는지까지는 잘 안 보였기 때문이다. 그래서 이번 반복에서는 GNN 샘플 실험 결과에 feature pair correlation 요약을 붙였다.

새 모델을 하나 더 얹은 날은 아니다. 대신 single-seed 결과의 각 모델 행에 feature_correlation을 넣고, multi-seed summary에는 feature_correlation_multi_seed를 추가했다. 테스트를 먼저 늘린 뒤 구현했고, 샘플 JSON도 다시 만들었다. 숫자를 더 많이 모았다기보다, 이미 있는 숫자를 덜 속고 읽는 판을 한 겹 더 깐 쪽에 가깝다. 개인적으로는 이런 반복이 꽤 중요하다. 작은 실험일수록 성능 숫자보다 해석판이 얼마나 정직한가가 다음 단계 속도를 더 크게 좌우하는 경우가 많아서다.

1. importance 다음에 상관을 보게 된 이유

직전 반복에서 feature_importance_multi_seed를 붙인 뒤에는 어떤 feature가 여러 seed에서 자주 상위권에 남는지가 조금 더 잘 보이기 시작했다. structural_mean_gap이 plain supervised baseline에서 반복적으로 top-3에 들고, hybrid에서는 propagated_cosine_residual이 꽤 안정적으로 앞에 선다는 것도 그때 알게 됐다. 그런데 그 표만으로는 한 가지가 여전히 비어 있었다. 중요도가 높다는 사실과, 그 feature가 정말로 독립적인 신호라는 사실은 전혀 같은 말이 아니라는 점이다.

특히 propagated_cosine_2hop이 계속 마음에 걸렸다. importance 표에서 완전히 사라지는 feature는 아닌데, ablation에서는 오히려 빼는 편이 더 나은 seed가 반복적으로 나왔다. 이런 장면을 보면 두 가지 가능성을 먼저 의심하게 된다. 하나는 2-hop propagation이 현재 샘플 그래프에선 아직 noisy하다는 것, 다른 하나는 이미 adjacency cosine이나 jaccard, 1-hop propagation이 잡고 있는 local similarity를 다른 형태로 한 번 더 들고 오는 것이다. 나는 이번에는 두 번째 가설을 먼저 확인해 보고 싶었다.

  • 질문 1: 2-hop propagation은 정말 더 먼 구조 신호를 가져오고 있나?
  • 질문 2: 아니면 이미 있는 local overlap 축과 지나치게 강하게 붙어 있나?
  • 질문 3: residual propagation은 2-hop보다 더 덜 대체 가능한 역할을 하나?

이 질문을 importance 순위만으로 밀어붙이면 해석이 쉽게 미끄러진다. rank 2와 rank 4의 차이가 실제로는 feature 간 상관 때문에 생긴 착시일 수도 있기 때문이다. 그래서 이번에는 아예 feature pair correlation을 결과 JSON의 정식 summary로 올렸다. 이제는 어떤 feature가 강한지뿐 아니라, 무엇과 너무 비슷해서 강해 보이는지도 같이 읽을 수 있다.

2. 코드에서 실제로 바꾼 부분

구현 자체는 단순하다. 평가에 쓰는 positive/negative edge를 다시 돌면서 각 edge의 feature map을 모으고, 그 값들로 pairwise correlation을 계산한다. single-seed 결과에서는 feature_linear, feature_linear_hybrid 두 모델 행에 각각 feature_correlation을 붙였다. multi-seed 결과에서는 이 pair 목록을 다시 seed별로 모아 mean_correlation, mean_abs_correlation, max/min_abs_correlation, best_seed, worst_seed를 함께 남기도록 정리했다.

single-seed row
- feature_importance
- feature_correlation

multi-seed summary
- feature_importance_multi_seed
- feature_correlation_multi_seed
- mean_correlation / mean_abs_correlation
- best_seed / worst_seed

이런 작업은 특히 테스트를 먼저 걸어 두는 편이 마음이 편하다. 이번에도 먼저 hybrid 결과에 feature_correlation 목록이 들어가는지, 그리고 multi-seed summary에서 propagated_cosine과 propagated_cosine_residual 쌍이 실제로 집계되는지를 고정했다. 그다음 구현을 넣고, 전체 테스트를 다시 돌린 뒤 샘플 결과 JSON과 PNG 두 장을 다시 만들었다. 커밋까지 남겨 두고 보니, 이번 반복은 성능 개선이라기보다 진단 레이어 추가로 기록하는 편이 가장 맞아 보였다.

3. heatmap에서 먼저 보인 묶음

hybrid feature correlation heatmap
sample_collab 그래프에서 feature_linear_hybrid의 주요 feature pair 상관을 multi-seed 평균으로 다시 그린 heatmap.

heatmap을 그리고 제일 먼저 눈에 들어온 건 예상대로 adjacency_cosine ↔ jaccard였다. mean correlation이 0.9811로 거의 붙어 있었다. 이건 surprising한 숫자는 아니다. 작은 샘플 그래프에서는 두 feature가 결국 비슷한 local overlap 패턴을 읽는 장면이 자주 나온다. plain supervised baseline에서 common_neighbors ↔ adamic_adar0.9322로 붙는 것도 같은 결이다. 이름은 다르지만, 실제로는 꽤 가까운 신호 묶음이 여러 군데 있다.

propagation 쪽에서는 더 흥미로운 장면이 나왔다. propagated_cosine ↔ propagated_cosine_residual의 mean correlation이 0.9568이었다. residual이 당연히 1-hop propagation과 강하게 붙는다는 건 이해할 수 있는 그림이다. 그런데 내가 더 눈여겨본 건 propagated_cosine_2hop의 자리였다. 이 축은 adjacency_cosine0.8720, jaccard0.8375, common_neighbors와도 0.8219 수준으로 꽤 강하게 연결돼 있었다.

feature pair mean correlation 읽힌 감각
adjacency_cosine ↔ jaccard 0.9811 local overlap 계열이 사실상 같은 방향으로 움직이는 대표 묶음
propagated_cosine ↔ propagated_cosine_residual 0.9568 residual propagation이 1-hop 축과 강하게 이어져 있다는 확인
adjacency_cosine ↔ propagated_cosine_2hop 0.8720 2-hop 축이 생각보다 local similarity 쪽과 가깝게 붙어 있었다
jaccard ↔ propagated_cosine_2hop 0.8375 2-hop이 독립 축이라기보다 기존 겹침 신호를 재표현하는 느낌

이 숫자를 보고 나니 2-hop 축을 읽는 문장이 조금 달라졌다. 전에는 더 멀리 본 propagation이라는 해석을 먼저 떠올렸는데, 지금 샘플 그래프에서는 오히려 기존 local similarity를 다른 방식으로 다시 쓰는 쪽에 가깝다. 반대로 propagated_cosine_residual은 1-hop과 강하게 붙어 있으면서도 structural summary나 preferential attachment와는 훨씬 덜 엮여 있어서, hybrid 안에서 상대적으로 더 독립적인 설명 축처럼 읽힌다. 결국 이번 correlation summary는 importance 표만 봤을 때보다 어떤 propagation feature가 진짜 새 정보인지를 훨씬 냉정하게 보게 만든다.

4. ablation 숫자와 붙여 보니 해석이 더 자연스러워졌다

hybrid ablation mean auc bar chart
feature_linear_hybrid와 propagation feature 단일 제거 ablation의 multi-seed mean AUC 비교.

correlation summary를 보고 다시 ablation 숫자를 붙여 보니, 그동안 조금 찝찝하던 장면이 훨씬 자연스럽게 읽혔다. feature_linear_hybrid의 mean AUC는 0.7055였다. 여기서 propagated_cosine_2hop을 빼면 mean AUC가 0.7389로 올라갔고, propagated_cosine을 빼면 0.6611, propagated_cosine_residual을 빼면 0.6444로 떨어졌다. 즉 현재 조합에서는 propagation feature가 많을수록 좋은 게 아니라, 덜 대체 가능한 propagation 축이 무엇인지가 더 중요하다.

모델 mean AUC 읽힌 점
feature_linear_hybrid 0.7055 현재 비교 기준선
drop propagated_cosine_2hop 0.7389 겹치는 신호를 걷어내면 오히려 더 낫다는 힌트
drop propagated_cosine 0.6611 1-hop 축은 아직 의미 있는 설명력을 남긴다
drop propagated_cosine_residual 0.6444 residual propagation이 현재 hybrid에서 가장 덜 대체 가능한 축에 가깝다

나는 이 표가 특히 좋았다. 예전에는 "2-hop이 약하다" 정도로만 적을 수 있었는데, 이제는 왜 약한지에 대한 힌트를 한 줄 더 붙일 수 있기 때문이다. 2-hop 축이 진짜로 더 멀리 있는 관계를 잡아낸다면, 적어도 local similarity 계열과 이렇게까지 강하게 붙어 있지는 않았을 가능성이 크다. 반대로 residual propagation은 1-hop과 밀접하면서도 ablation 손실이 더 크게 나기 때문에, 현재 샘플에서는 2-hop보다 residual 쪽이 더 실전적인 신호라는 해석이 훨씬 덜 억지스럽다.

이건 결국 다음 실험 설계에도 바로 영향을 준다. 앞으로는 propagation feature를 한 묶음으로 취급하기보다, 겹치는 축은 덜고, 남겨야 하는 축은 왜 남겨야 하는지를 먼저 적어 놓고 가는 편이 맞겠다 싶었다. GraphSAGE나 GCN 같은 encoder를 붙일 때도 마찬가지다. encoder가 조금 나아진 숫자를 보여 줘도, 그게 기존 hand-crafted propagation이 하던 일을 다른 이름으로 반복한 건지, 진짜로 다른 표현을 만드는 건지는 지금 같은 진단판이 있어야 조금 덜 헷갈린다.

5. 이번 반복이 남긴 것

이번 작업은 새 모델 추가보다 훨씬 덜 화려하다. 그런데 프로젝트를 오래 끌고 가다 보면 이런 반복이 생각보다 오래 남는다. feature importance만 있을 때는 상위권 숫자에 쉽게 끌려가고, ablation만 있을 때는 왜 빠지는지 설명이 빈약하다. 이번에 feature_correlation을 붙이고 나니 그 둘 사이가 조금 이어졌다. 적어도 지금 샘플 그래프에서는 2-hop propagation이 독립적인 새 축처럼 보이기보다 기존 local similarity와 많이 겹친다는 말을 더 자신 있게 할 수 있게 됐다.

다음 단계는 이미 정해져 있다. 하나는 feature_importance_multi_seedfeature_correlation_multi_seed를 같은 heatmap이나 표로 묶어, rank가 높으면서 상관도도 높은 feature 묶음을 한 화면에서 바로 읽는 것. 다른 하나는 propagation profile과 이번 correlation summary를 같이 그려, 2-hop 축이 실제로 더 먼 구조 신호를 가져오는지 아니면 local overlap을 다시 쓰는지 확인하는 것이다. 그다음에 GraphSAGE/GCN encoder를 올리면, 적어도 지금보다 덜 헷갈리는 비교판 위에서 다음 반복을 읽을 수 있을 것 같다.

댓글

홈으로 돌아가기

검색 결과

"" 검색 결과입니다.