Neo4j에서 ML 돌리려면 GDS부터 깔아야 한다고?
노드가 많아지면 눈으로 못 찾는다
온톨로지에 노드를 채우다 보면 어느 순간 "이거 더 이어야 하는 거 아닌가?" 싶은 느낌이 오거든요. 노드끼리 관계가 빠져 있는 것 같은데, 수백 개 넘어가니까 하나하나 확인하는 게 불가능해요. 에러가 나는 것도 아니고, 그냥 조용히 빠져 있으니까요.
그래서 "사람 눈 말고 다른 방법으로 빠진 연결을 찾을 수 없나?" 찾아보다가 만난 게 GDS였어요.
GDS가 뭘까?
GDS는 Graph Data Science의 줄임말이에요. Neo4j에 플러그인처럼 얹는 라이브러리인데, 이걸 깔면 Cypher 쿼리 안에서 그래프 ML 알고리즘을 바로 돌릴 수 있어요. 노드 유사도 계산, 링크 예측, 커뮤니티 탐지 같은 것들이요.
별도로 파이썬 환경 세팅하고 데이터 뽑아서 ML 돌리고 다시 넣고… 이런 과정 없이, Neo4j 안에서 다 해결된다는 게 핵심이에요.
GDS 설치 — 5분이면 끝난다
Docker로 Neo4j를 쓰고 있으면 설치가 정말 간단하더라고요. docker-compose.yml에 환경변수 한 줄 추가하면 돼요.
yaml
environment:
- NEO4J_PLUGINS=["graph-data-science"]이거 넣고 컨테이너 재시작하면 Neo4j가 알아서 GDS 플러그인을 다운받아서 설치해요. 설치 끝났는지 확인은 Neo4j Browser에서 이 쿼리 하나 날려보면 돼요.
cypher
RETURN gds.version()버전 번호가 나오면 성공이에요. 여기까지가 설치의 전부예요.
설치했으면 바로 써보자 — 그래프 프로젝션
GDS에서 알고리즘을 돌리려면 먼저 그래프 프로젝션이라는 걸 해야 해요. DB에 있는 전체 그래프 중에서 "이 노드들, 이 관계들만 가지고 분석할게"라고 범위를 잡아서 메모리에 올리는 과정이에요.
비유하자면, 도서관에서 책을 전부 분석하는 게 아니라 "이번엔 이 책장에 있는 것만 볼게"하고 꺼내서 책상 위에 펼쳐놓는 느낌이에요. 메모리 위에 올려놓고 계산해야 빠르니까 이런 구조를 쓰는 거거든요.
Cypher로는 이렇게 생겼어요.
cypher
CALL gds.graph.project(
'my-graph',
'Concept',
'RELATED_TO'
)첫 번째가 프로젝션 이름, 두 번째가 노드 라벨, 세 번째가 관계 타입이에요. 이렇게 하면 Concept 노드들과 RELATED_TO 관계만 골라서 메모리에 올라가요.
실행하면 "nodeCount 몇 개, relationshipCount 몇 개 올렸다"는 결과가 나오는데, 이걸로 내가 의도한 범위가 맞는지 확인할 수 있어요.
첫 알고리즘 — 노드 유사도 돌려보기
프로젝션이 올라갔으면 드디어 알고리즘을 돌릴 수 있어요. 처음 써본 건 노드 유사도(Node Similarity)였어요. 이전 글에서 정리했던 그거 — "연결 구조가 비슷한 노드끼리 찾아주는" 알고리즘이요.
cypher
CALL gds.nodeSimilarity.stream('my-graph')
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS node1,
gds.util.asNode(node2).name AS node2,
similarity
ORDER BY similarity DESC
LIMIT 10이 쿼리를 돌리면 유사도 점수가 높은 노드 쌍이 위에서부터 쭉 나와요. similarity가 1.0에 가까울수록 "이 둘은 연결 구조가 거의 같다"는 뜻이에요.

결과를 보고 느낀 것
처음 결과를 봤을 때 솔직히 "이게 맞나?" 싶었어요. 유사도 0.85라고 나온 쌍을 보면, "아 이 둘이 비슷하긴 하지" 싶은 것도 있고, "이게 왜 비슷하다고 나오지?" 싶은 것도 있었거든요.
그래서 결과를 하나하나 확인해봤는데, 대부분은 납득이 되더라고요. 두 노드가 직접 연결은 안 되어 있는데, 같은 노드들이랑 많이 연결되어 있으니까 구조적으로 비슷하다고 잡아낸 거예요. 사람 눈으로는 놓치기 쉬운 패턴을 잡아주니까, 이래서 ML을 쓰는 거구나 싶었어요.
반대로 "왜 이게 비슷하지?" 싶은 결과는, 그래프 자체가 아직 관계가 덜 채워져 있어서 그런 경우가 많았어요. 데이터가 부족하면 알고리즘도 정확도가 떨어진다는 걸 체감한 거죠.
주의할 점 두 가지
하나는 GDS 버전과 Neo4j 버전 호환이에요. GDS는 Neo4j 버전마다 지원하는 버전이 다르거든요. Docker 이미지 태그에서 Neo4j 버전을 확인하고, 그에 맞는 GDS가 깔리는지 공식 호환 표를 한 번 보는 게 안전해요.
다른 하나는 Community Edition 제약이에요. GDS 자체는 Community에서도 돌아가는데, 일부 알고리즘이나 기능은 Enterprise에서만 되는 것들이 있어요. 처음 돌려볼 때는 Community로 충분한데, 나중에 "이 기능 왜 안 되지?" 싶으면 이 차이일 수 있으니까 알아두면 좋더라고요.
정리하면
GDS 설치는 Docker 환경변수 한 줄, 프로젝션이랑 알고리즘 실행까지 Cypher 몇 줄이면 돼요. 공식 문서가 영어라 막막할 수 있는데, 막상 해보면 진입 장벽은 낮은 편이에요. 결과로 나온 유사도 점수를 하나씩 확인해보면, 사람 눈으로 놓치던 구조적 패턴이 꽤 나와요.
다만 그래프 데이터가 충분해야 의미 있는 결과가 나오니까, 노드가 어느 정도 쌓인 다음에 돌려보는 걸 추천합니다.