계층적 클러스터링(Hierarchical Clustering)이란? AI에서 데이터의 묶음 관계를 트리로 보는 방법
TL;DR
계층적 클러스터링은 작은 그룹을 차례로 합치거나 큰 그룹을 나눠 중첩된 군집 구조를 만드는 방법입니다. 한 번의 그룹 번호뿐 아니라 어떤 묶음이 먼저 생기고 나중에 합쳐졌는지 트리로 살펴봅니다. 대표적인 응집형 방식은 각 사례에서 시작해 연결 기준에 따라 군집 쌍을 합칩니다. 덴드로그램의 높이, 거리 기준, 자르는 수준을 함께 읽어야 하며 트리 모양만으로 실제 집단의 정답을 확정할 수는 없습니다.
핵심 3줄 요약
- 핵심 1
묶음 안에 더 작은 묶음이 있습니다. 계층적 군집화는 최종 그룹뿐 아니라 그룹이 합쳐지거나 나뉘는 관계를 남깁니다. - 핵심 2
연결 기준에 따라 트리가 달라집니다. single·complete·average·Ward는 군집 쌍을 비교하는 규칙이 서로 다릅니다. - 핵심 3
그림의 색과 순서는 정답이 아닙니다. 병합 높이와 절단 기준을 확인하고 대표 사례와 경계 사례를 따로 검토합니다.
이 글에서 다룰 내용
- 계층적 클러스터링의 한 문장 정의
- 문서 묶음으로 이해하는 응집형과 분할형
- 거리와 연결 기준에 따른 병합 과정
- 덴드로그램의 높이·잎·절단선 읽기
- K-means·DBSCAN·분류 트리와의 차이
- 실전 활용과 입력·설정 점검 순서
- 메모리·노이즈·새 데이터 처리 주의점
계층적 클러스터링을 한 문장으로 정의하면 무엇인가요?
계층적 클러스터링(Hierarchical Clustering)은 군집을 순차적으로 병합하거나 분할해 여러 수준의 중첩된 그룹을 구성하는 군집화 알고리즘 계열입니다.
한국어로 계층적 군집화 또는 계층적 군집 분석이라고도 부릅니다. scikit-learn 사용자 가이드는 이 계층을 트리나 덴드로그램으로 표현한다고 설명합니다. 완전한 트리에서는 잎이 개별 사례이고 루트는 모든 사례를 담은 하나의 군집입니다.
응집형은 아래에서 위로 올라갑니다. 각 사례를 따로 둔 뒤 조건에 맞는 군집 쌍을 반복해서 합칩니다. 분할형은 전체 묶음에서 시작해 위에서 아래로 나눕니다. 이 글은 scikit-learn의 AgglomerativeClustering과 SciPy의 linkage로 접하기 쉬운 응집형을 중심으로 설명합니다.
한 줄 정리: 계층적이라는 말은 등급을 매긴다는 뜻이 아니라 작은 묶음과 큰 묶음의 포함 관계를 남긴다는 뜻입니다.
쉬운 예시로 이해해 볼까요?
블로그의 AI 글을 정리한다고 가정해 보겠습니다. 이미지 생성 프롬프트 글과 이미지 편집 글은 서로 가깝고, 회의 녹음 요약 글과 음성 받아쓰기 글도 서로 가깝다고 판단할 수 있습니다. 문서 임베딩으로 이런 관계를 숫자화한 뒤 응집형 군집화를 적용합니다.
처음에는 글마다 별도 묶음입니다. 이미지 관련 글끼리 먼저 합쳐지고 음성 관련 글끼리 다른 묶음이 만들어질 수 있습니다. 더 큰 수준에서는 이 두 묶음이 멀티모달 활용이라는 상위 묶음으로 연결될 수도 있습니다. 실제 병합 순서는 문서 표현과 연결 기준으로 결정됩니다.
작게 자르면 이미지 생성과 편집을 나누고, 크게 자르면 이미지 관련 글을 한 그룹으로 읽습니다. 그룹 이름은 사람이 붙인 예시입니다. 알고리즘이 멀티모달이라는 주제명을 이해해 자동 확정한 것은 아닙니다. 같은 글이라도 제목만 쓰는지 본문까지 쓰는지에 따라 관계가 바뀝니다.
쉬운 예시: 폴더 안에 하위 폴더를 두듯 묶음의 여러 수준을 살펴봅니다. 다만 군집 트리는 데이터의 거리에서 만든 탐색 결과이며 사람이 설계한 분류 체계와 같지는 않습니다.
왜 AI에서 계층적 클러스터링이 중요한가요?
한 가지 그룹 수에만 갇히지 않습니다
완전한 트리를 만들면 같은 계층을 서로 다른 수준에서 잘라 비교할 수 있습니다. 문서의 큰 주제와 세부 주제를 함께 탐색할 때 유용합니다. 최종 군집 수를 미리 정하지 않고 트리부터 살펴보는 흐름도 가능합니다. 다만 일부 구현은 정한 군집 수에서 계산을 일찍 끝내므로 전체 트리인지 확인합니다.
묶음이 만들어진 관계를 확인합니다
최종 라벨만 보면 두 그룹이 얼마나 뒤늦게 합쳐졌는지 알기 어렵습니다. 병합 기록은 가까운 작은 그룹부터 큰 그룹까지 이어지는 관계를 보여 줍니다. 문서 정리와 데이터 탐색에서 경계 사례를 찾아 원문을 다시 읽을 단서가 됩니다.
공간이나 연결 구조를 반영합니다
scikit-learn은 연결 행렬로 병합 후보를 제한할 수 있습니다. 이미지에서는 이웃 픽셀, 다른 데이터에서는 이웃 그래프를 바탕으로 연결을 정합니다. 이런 제약은 계산을 줄이거나 원하는 국소 구조를 반영하지만 결과 자체도 바꾸므로 단순한 속도 옵션으로만 보면 안 됩니다.
계층적 클러스터링은 어떻게 작동하나요?
개별 사례와 거리 기준을 준비합니다
응집형은 각 행을 별도 군집으로 두고 시작합니다. 수치 특징에는 단위에 맞는 거리 기준을, 문서 임베딩에는 표현의 의미에 맞는 거리 기준을 정합니다. 군집화 함수가 서로 다른 단위를 알아서 맞춰 주지는 않으므로 전처리를 먼저 확인합니다.
연결 기준으로 합칠 군집 쌍을 고릅니다
single은 두 군집에서 가장 가까운 점 쌍의 거리, complete는 가장 먼 점 쌍의 거리, average는 두 군집 사이 모든 점 쌍 거리의 평균을 사용합니다. 같은 점 사이 거리를 쓰더라도 군집 전체를 비교하는 규칙이 달라 병합 순서가 달라집니다.
Ward는 병합 뒤 군집 내부의 제곱 오차 합이 가장 적게 늘어나는 쌍을 고릅니다. 유클리드 거리의 분산 최소화 관점이므로 코사인 거리를 그대로 결합하면 안 됩니다. scikit-learn에서는 유클리드 거리 설정과 Ward를 함께 쓰는 것이 기본적인 사용법입니다.
병합 결과를 기록하고 다음 쌍을 비교합니다
두 군집을 합치면 남아 있는 군집들과의 연결 거리를 갱신합니다. 이를 반복해 하나의 루트까지 만들거나 구현의 종료 조건에서 멈춥니다. 표준 응집형 과정은 앞에서 합친 군집을 나중에 다시 나누지 않으므로 초기 병합에 영향을 준 노이즈가 위쪽 구조에도 남을 수 있습니다.
트리와 최종 라벨을 따로 보관합니다
SciPy의 linkage 결과는 병합한 두 군집의 번호, 병합 거리, 새 군집에 속한 원래 사례 수를 담습니다. scikit-learn은 children_에 병합 관계를, labels_에 최종 군집 번호를 남깁니다. distances_는 거리 임계값을 쓰거나 compute_distances를 켰을 때 계산하므로 시각화에 필요한 값을 미리 확인합니다.
핵심 인사이트: 거리 기준은 사례끼리 얼마나 다른지, 연결 기준은 여러 사례가 든 군집끼리 어떻게 비교할지를 정합니다. 두 설정을 구분해 기록하세요.
덴드로그램의 높이와 절단선은 어떻게 읽나요?
잎의 순서보다 병합 지점을 봅니다
일반적인 위쪽 방향 덴드로그램에서는 아래쪽 잎이 개별 사례이고 위에서 만나는 선이 병합을 나타냅니다. 선이 만나는 높이는 선택한 연결 기준의 병합 거리입니다. 옆에 나란히 그려졌다고 원본 공간에서도 가장 가까운 두 점이라는 뜻은 아닙니다. 좌우 배치는 가지를 뒤집거나 정렬해 달라질 수 있습니다.
절단 수준은 분석 목적에 맞춰 정합니다
한 높이에서 트리를 자르면 그 아래에서 이어진 가지들이 군집 후보가 됩니다. 높은 위치에서 자를수록 큰 묶음으로 보는 방식입니다. scikit-learn에서 distance_threshold를 지정하면 n_clusters는 None, compute_full_tree는 True여야 합니다. 임계값 이상인 연결 거리에서는 병합하지 않습니다.
색상과 생략된 가지를 확인합니다
SciPy의 color_threshold는 그림의 가지 색을 정하는 설정입니다. 그림 색상만 바꿨다고 저장된 군집 라벨이 새로 정해지는 것은 아닙니다. 큰 트리를 축약하면 잎처럼 보이는 끝부분이 여러 사례를 포함한 군집일 수 있으므로 축약 모드와 사례 수를 함께 확인합니다.
계층적 클러스터링과 헷갈리는 용어는 무엇이 다른가요?
클러스터링과 계층적 클러스터링의 차이
클러스터링은 비슷한 데이터를 묶는 작업 전체를 가리킵니다. 계층적 클러스터링은 그중 중첩된 묶음 관계를 만드는 계열입니다. 전체 개념을 설명하는 글과 달리 여기서는 연결 기준, 병합 기록, 트리를 자르는 방법을 구분해 읽는 것이 핵심입니다.
K-means와의 차이
K-means는 정한 수의 중심점과 사례 배정을 반복해서 조정합니다. 응집형 계층적 방법은 군집 쌍을 순서대로 합칩니다. Ward와 K-means는 군집 내부 제곱 오차라는 관련 기준을 쓰지만 탐색 절차가 달라 같은 군집 수를 지정해도 결과가 같다는 보장은 없습니다.
DBSCAN과의 차이
DBSCAN은 이웃이 충분한 밀집 영역을 확장하고 묶이지 않는 사례를 노이즈로 남깁니다. 일반적인 응집형 군집화는 모든 사례를 트리에 포함하며 자동으로 노이즈 라벨을 부여하지 않습니다. single 연결이 길게 이어진 모양을 만들 수 있어도 밀도 조건을 쓰는 DBSCAN과 같은 알고리즘은 아닙니다.
분류 트리와의 차이
분류용 결정 트리는 정답 라벨을 보고 특징값 조건으로 분기하는 예측 모델입니다. 군집 덴드로그램의 가지는 사례나 군집이 합쳐진 관계입니다. 모양이 나무처럼 보인다고 새 입력을 자동 분류하는 규칙이나 원인 관계가 들어 있는 것은 아닙니다.
실전에서는 어디에 쓰이나요?
문서의 큰 주제와 세부 묶음을 탐색합니다
문서 임베딩을 묶어 콘텐츠 목록을 정리하거나 비슷한 문의를 검토할 때 사용합니다. 완성된 트리에서 큰 주제 수준과 세부 주제 수준을 비교합니다. 자동으로 붙인 주제명은 대표 문서와 예외 문서를 읽어 확인하고 원문에 없는 의미를 덧붙이지 않습니다.
이미지의 이웃 영역을 묶습니다
픽셀이나 영역의 특징에 공간 연결 제약을 더하면 인접한 부분을 병합하는 방식으로 이미지를 나눌 수 있습니다. scikit-learn은 동전 이미지에 구조화된 Ward 군집화를 적용한 예시를 제공합니다. 영역을 나눴다는 사실만으로 물체 이름까지 인식한 것은 아닙니다.
서로 비슷한 특징을 모읍니다
FeatureAgglomeration은 사례 대신 특징을 응집형 방식으로 묶는 도구입니다. 유사한 특징을 합쳐 차원을 줄이는 데 사용합니다. 문서 행을 묶는 군집화와 입력 열을 묶는 특징 응집은 결과의 대상이 다르므로 데이터의 행과 열을 먼저 구분합니다.
계층적 클러스터링을 적용할 때 어떤 순서로 확인하나요?
1. 입력 행렬과 전처리를 확인합니다
각 행이 문서인지 사람인지, 각 열이 무엇을 뜻하는지 기록합니다. 결측값과 무한대, 중복 사례, 극단적인 값을 점검합니다. SciPy linkage는 관측 벡터의 이차원 배열 또는 압축된 일차원 거리 배열을 받습니다. 정사각 거리 행렬을 그대로 넣으면 관측 벡터로 해석될 수 있어 입력 형식을 구분해야 합니다.
2. 거리와 연결 기준을 함께 선택합니다
single·complete·average·Ward를 같은 데이터에서 비교하되 지원하는 거리 조건을 맞춥니다. 미리 계산한 거리를 쓰더라도 Ward에 필요한 유클리드 조건은 사라지지 않습니다. scikit-learn의 사전 계산 거리 입력과 SciPy의 압축 거리 입력은 형식이 다르다는 점도 확인합니다.
3. 트리 수준과 경계 사례를 비교합니다
군집 수 또는 거리 임계값을 바꾸며 작은 그룹과 큰 그룹의 의미를 살펴봅니다. 대표 사례만 보지 말고 늦게 합쳐지는 사례, 지나치게 커진 그룹, 혼자 남은 사례도 확인합니다. 같은 데이터에서 그럴듯한 그림이 나왔다는 이유만으로 실제 업무에 유용하다고 확정하지 않습니다.
4. 계산 조건과 후속 처리 규칙을 남깁니다
특징 순서, 전처리, 거리, 연결 기준, 연결 행렬, 절단 조건과 라이브러리 버전을 저장합니다. 새로운 자료가 추가됐을 때 전체를 다시 묶을지 별도 배정 규칙을 둘지도 정합니다. 군집 번호는 식별자이므로 재계산 후 같은 번호가 같은 주제라는 가정은 피합니다.
사용할 때 무엇을 주의해야 하나요?
첫째, single 연결의 사슬 효과를 살펴봅니다. 가까운 점들이 다리처럼 이어지면 서로 멀리 떨어진 영역까지 한 그룹으로 연결될 수 있습니다. 노이즈가 이런 다리를 만들기도 합니다. complete나 average로 바꾼 결과와 비교하되 특정 연결 기준이 모든 데이터에 가장 좋다고 단정하지 않습니다.
둘째, 표본 수에 따른 메모리 비용을 확인합니다. SciPy linkage 문서는 해당 구현의 알고리즘들이 표본 수의 제곱에 비례하는 메모리를 사용한다고 안내합니다. 전체 쌍의 관계를 다루는 비용을 고려해 작은 표본에서 먼저 시험합니다. 연결 제약을 넣어 계산을 줄일 때도 원래 분석하려던 관계가 달라지는지 점검합니다.
셋째, 병합 높이를 확률이나 유의성으로 읽지 않습니다. Ward의 높이와 average의 높이는 같은 해석 기준이 아닙니다. 긴 가지가 생겼다고 통계적으로 검증된 집단이라는 뜻도 아닙니다. 원본 사례, 다른 특징 조합과 표본 구성에서 유지되는 구조를 함께 봅니다.
넷째, 새 데이터 예측 기능을 가정하지 않습니다. scikit-learn의 AgglomerativeClustering은 학습에 사용한 사례의 라벨을 구하며 일반적인 predict 메서드를 제공하지 않습니다. 새 사례를 가까운 기존 그룹에 붙이는 별도 규칙은 원래 계층적 군집화와 구분해 평가해야 합니다.
주의: 군집 트리는 사람의 등급이나 타고난 유형을 증명하지 않습니다. 민감한 개인정보를 불필요하게 넣지 않고 자동 제재나 자격 판단으로 곧바로 연결하지 않습니다.
자주 묻는 질문
Q1. 계층적 군집화와 응집형 군집화는 같은 말인가요?
계층적 군집화가 더 넓습니다. 응집형은 작은 군집에서 시작해 합치는 방식이고 분할형은 큰 군집에서 시작해 나눕니다. AgglomerativeClustering은 응집형을 구현한 도구입니다.
Q2. 클러스터 수를 먼저 정해야 하나요?
완전한 계층을 만든 뒤 절단 수준을 고를 수 있어 반드시 먼저 정할 필요는 없습니다. 다만 사용하는 함수가 최종 군집 수를 요구하거나 일찍 계산을 멈출 수 있으므로 전체 트리와 라벨 출력의 설정을 구분합니다.
Q3. 덴드로그램에서 가까이 그려진 문서는 비슷한가요?
가로 간격만으로 판단하면 안 됩니다. 같은 가지에서 어느 높이에 합쳐지는지 확인합니다. 잎의 순서나 그림 방향을 바꿔도 병합 관계는 유지될 수 있으므로 레이아웃과 거리 정보를 구분해서 읽습니다.
Q4. Ward에 코사인 거리를 써도 되나요?
Ward는 유클리드 기하의 분산 최소화 기준을 사용합니다. 코사인 거리를 그대로 결합하지 말고 코사인 비교가 필요한 경우 average 등 지원되는 연결 기준을 검토합니다. 이름만 바꿔 거리 조건을 우회해서는 안 됩니다.
Q5. 그림의 색상 수가 최종 군집 수인가요?
반드시 그렇지는 않습니다. SciPy 덴드로그램의 색상 임계값은 시각화 설정입니다. 최종 군집은 선택한 절단 규칙에 따라 별도로 구하고 저장된 라벨과 그림의 설명이 일치하는지 확인합니다.
출처
마무리
계층적 클러스터링은 작은 군집과 큰 군집의 포함 관계를 트리로 남기는 방법입니다. 응집형에서는 거리와 연결 기준으로 군집 쌍을 차례로 합칩니다. 덴드로그램은 그 기록을 읽는 그림이며 가지의 높이, 절단 수준, 대표 사례를 함께 봐야 합니다.
처음 접한다면 작은 문서 묶음에서 연결 기준을 바꿔 비교해 보세요. 보기 좋은 색상이나 군집 번호보다 어느 사례들이 먼저 합쳐지는지, 다른 수준으로 잘라도 의미가 유지되는지 확인하는 편이 좋습니다. 입력 형식과 계산 비용까지 기록하면 결과를 다시 점검하기도 쉬워집니다.
