본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.
본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.
이미지 로딩 중...
AI Generated
2025. 12. 6. · 16 Views
DBSCAN과 계층적 클러스터링 완벽 가이드
밀도 기반 클러스터링 알고리즘 DBSCAN과 계층적 클러스터링의 핵심 개념을 실무 예제와 함께 설명합니다. 초급 개발자도 쉽게 이해할 수 있도록 비유와 스토리텔링으로 풀어냅니다.
목차
- DBSCAN_기본_개념
- DBSCAN_핵심_파라미터_튜닝
- 계층적_클러스터링_기본_개념
- 연결_방법의_종류와_선택
- 덴드로그램_해석과_클러스터_수_결정
- DBSCAN과_계층적_클러스터링_비교
- 실전_프로젝트_고객_세그멘테이션
1. DBSCAN 기본 개념
어느 날 김개발 씨가 고객 데이터를 분석하다가 이상한 점을 발견했습니다. K-Means로 클러스터링을 했는데, 결과가 영 이상합니다.
원형이 아닌 불규칙한 형태의 군집이 제대로 분리되지 않는 것이었습니다.
DBSCAN은 Density-Based Spatial Clustering of Applications with Noise의 약자로, 밀도 기반 클러스터링 알고리즘입니다. 마치 사람들이 모여 있는 곳을 찾아 "이 무리가 하나의 그룹이다"라고 판단하는 것과 같습니다.
K-Means와 달리 클러스터 개수를 미리 지정할 필요가 없고, 이상치도 자동으로 탐지할 수 있습니다.
다음 코드를 살펴봅시다.
from sklearn.cluster import DBSCAN
import numpy as np
# 샘플 데이터 생성
X = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]])
# DBSCAN 모델 생성
# eps: 이웃 반경, min_samples: 최소 이웃 수
dbscan = DBSCAN(eps=3, min_samples=2)
# 클러스터링 수행
labels = dbscan.fit_predict(X)
# 결과 출력 (-1은 노이즈를 의미)
print(f"클러스터 레이블: {labels}")
김개발 씨는 입사 6개월 차 데이터 분석가입니다. 오늘 팀장님으로부터 고객 세그멘테이션 업무를 받았습니다.
"고객들을 비슷한 특성별로 묶어서 분석해 봐요." 김개발 씨는 가장 먼저 떠오르는 K-Means 알고리즘을 적용했습니다. 그런데 결과를 시각화해보니 뭔가 이상합니다.
길쭉하게 늘어선 형태의 고객 그룹이 두 개로 쪼개져 버린 것입니다. 선배 박시니어 씨가 화면을 들여다봅니다.
"K-Means는 원형 클러스터에 강하지만, 이런 불규칙한 형태에는 약해요. DBSCAN을 써보는 게 어떨까요?" 그렇다면 DBSCAN이란 정확히 무엇일까요?
쉽게 비유하자면, DBSCAN은 마치 밤하늘의 별자리를 찾는 것과 같습니다. 별들이 촘촘하게 모여 있는 곳을 하나의 별자리로 인식하고, 홀로 떨어져 있는 별은 "어디에도 속하지 않는 별"로 분류합니다.
이처럼 DBSCAN도 데이터 포인트들이 밀집된 영역을 하나의 클러스터로 인식합니다. DBSCAN의 핵심에는 두 가지 파라미터가 있습니다.
첫 번째는 eps로, 이웃을 정의하는 반경입니다. 두 번째는 min_samples로, 핵심 포인트가 되기 위한 최소 이웃 수입니다.
알고리즘의 동작 원리를 살펴보겠습니다. 먼저 임의의 점에서 시작하여 eps 반경 내의 이웃을 찾습니다.
이웃이 min_samples 이상이면 그 점은 핵심 포인트가 됩니다. 핵심 포인트의 이웃들도 같은 과정을 반복하며 클러스터가 확장됩니다.
위 코드를 살펴보면, eps=3은 반경 3 단위 내의 점들을 이웃으로 간주한다는 의미입니다. min_samples=2는 최소 2개 이상의 이웃이 있어야 핵심 포인트로 인정한다는 뜻입니다.
실제 현업에서는 어떻게 활용할까요? 예를 들어 신용카드 사기 탐지 시스템을 개발한다고 가정해봅시다.
정상적인 거래 패턴은 밀집된 클러스터를 형성하지만, 사기 거래는 이 패턴에서 벗어난 이상치로 나타납니다. DBSCAN은 이런 이상치를 -1 레이블로 자동 분류해줍니다.
하지만 주의할 점도 있습니다. eps와 min_samples 값을 어떻게 설정하느냐에 따라 결과가 크게 달라집니다.
값이 너무 작으면 대부분이 노이즈로 분류되고, 너무 크면 모든 데이터가 하나의 클러스터로 뭉쳐버립니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.
DBSCAN을 적용하자 불규칙한 형태의 고객 그룹도 정확하게 분리되었습니다. 팀장님도 만족스러운 표정을 지었습니다.
실전 팁
💡 - eps 값은 K-distance 그래프를 그려서 엘보 포인트를 찾아 결정하세요
- 데이터 스케일링을 반드시 먼저 수행해야 합니다
2. DBSCAN 핵심 파라미터 튜닝
김개발 씨가 DBSCAN을 적용했지만, 결과가 만족스럽지 않았습니다. 어떤 설정에서는 클러스터가 너무 많이 생기고, 다른 설정에서는 모든 데이터가 하나로 뭉쳐버립니다.
도대체 eps와 min_samples를 어떻게 설정해야 할까요?
DBSCAN의 파라미터 튜닝은 알고리즘 성능을 좌우하는 핵심 과정입니다. eps는 이웃 반경을, min_samples는 핵심 포인트의 조건을 결정합니다.
K-distance 그래프를 활용하면 최적의 eps 값을 찾을 수 있습니다.
다음 코드를 살펴봅시다.
from sklearn.neighbors import NearestNeighbors
import numpy as np
import matplotlib.pyplot as plt
# 샘플 데이터
X = np.random.randn(100, 2)
# K-distance 계산 (k = min_samples)
k = 4
neighbors = NearestNeighbors(n_neighbors=k)
neighbors.fit(X)
distances, indices = neighbors.kneighbors(X)
# k번째 이웃까지의 거리를 정렬
k_distances = np.sort(distances[:, k-1])
# 엘보 포인트를 찾아 eps 결정
plt.plot(k_distances)
plt.xlabel('Points')
plt.ylabel(f'{k}-distance')
plt.title('K-distance Graph for eps selection')
김개발 씨는 DBSCAN의 기본 개념은 이해했지만, 실제로 적용하려니 막막했습니다. eps를 0.5로 하면 클러스터가 수십 개로 쪼개지고, 5로 하면 전부 하나로 합쳐집니다.
박시니어 씨가 조언을 건넵니다. "DBSCAN에서 가장 중요한 건 eps 값 설정이에요.
이걸 잘못하면 아무리 좋은 알고리즘이라도 무용지물이 됩니다." 그렇다면 어떻게 적절한 eps를 찾을 수 있을까요? 가장 널리 사용되는 방법은 K-distance 그래프입니다.
마치 등산로에서 경사가 급격히 바뀌는 지점을 찾는 것과 같습니다. 그 지점이 바로 최적의 eps 값입니다.
K-distance 그래프의 원리는 간단합니다. 각 데이터 포인트에서 k번째로 가까운 이웃까지의 거리를 계산합니다.
이 거리들을 오름차순으로 정렬하여 그래프로 그립니다. 그래프에서 기울기가 급격히 변하는 엘보 포인트가 최적의 eps입니다.
위 코드에서 k=4로 설정한 이유가 있습니다. 일반적으로 min_samples는 데이터 차원 수의 2배로 설정합니다.
2차원 데이터라면 min_samples=4가 적당합니다. NearestNeighbors를 사용해 각 점의 4번째 이웃까지의 거리를 계산합니다.
이 거리들을 정렬하면 점점 증가하다가 어느 순간 급격히 증가하는 구간이 나타납니다. 실무에서는 시각적으로 엘보 포인트를 찾는 것이 일반적입니다.
하지만 자동화가 필요하다면 기울기의 변화율을 계산하여 최댓값 지점을 찾을 수도 있습니다. min_samples에 대해서도 알아봅시다.
값이 너무 작으면 노이즈도 클러스터로 인식됩니다. 반대로 너무 크면 작은 클러스터들이 모두 노이즈로 처리됩니다.
김개발 씨가 K-distance 그래프를 그려보니, 거리 0.8 부근에서 급격한 변화가 보였습니다. eps=0.8로 설정하고 다시 DBSCAN을 실행하자, 드디어 합리적인 클러스터링 결과가 나왔습니다.
"역시 데이터를 먼저 분석하고 파라미터를 결정해야 하는군요." 김개발 씨가 고개를 끄덕였습니다.
실전 팁
💡 - min_samples는 2 * 차원 수를 기본값으로 시작하세요
- 여러 eps 값을 테스트하며 실루엣 점수를 비교해보세요
3. 계층적 클러스터링 기본 개념
이번에는 다른 요구사항이 들어왔습니다. "클러스터들 사이의 관계도 보고 싶어요.
어떤 그룹이 더 비슷한지 계층 구조로 보여줄 수 있나요?" 김개발 씨는 새로운 알고리즘을 찾아봐야 했습니다.
계층적 클러스터링은 데이터를 트리 구조로 군집화하는 방법입니다. 마치 생물 분류학에서 종-속-과-목 순으로 분류하는 것처럼, 데이터도 유사도에 따라 계층적으로 묶습니다.
결과는 덴드로그램이라는 나무 형태의 그래프로 시각화됩니다.
다음 코드를 살펴봅시다.
from scipy.cluster.hierarchy import dendrogram, linkage
from sklearn.cluster import AgglomerativeClustering
import numpy as np
# 샘플 데이터
X = np.array([[1, 2], [1.5, 1.8], [5, 8], [8, 8], [1, 0.6], [9, 11]])
# 계층적 클러스터링 (병합 방식)
# linkage: 클러스터 간 거리 계산 방법
linked = linkage(X, method='ward')
# 덴드로그램 시각화
dendrogram(linked)
# sklearn으로 클러스터 할당
hc = AgglomerativeClustering(n_clusters=2, linkage='ward')
labels = hc.fit_predict(X)
print(f"클러스터 레이블: {labels}")
김개발 씨에게 새로운 미션이 주어졌습니다. 마케팅팀에서 고객 세그먼트뿐 아니라, 세그먼트들 사이의 관계도 알고 싶다는 요청이 온 것입니다.
"A 그룹과 B 그룹이 비슷한가요, 아니면 A와 C가 더 비슷한가요?" 마케팅 담당자의 질문에 김개발 씨는 잠시 생각에 잠겼습니다. 박시니어 씨가 해결책을 알려줍니다.
"그럴 땐 계층적 클러스터링을 써보세요. 클러스터들의 관계를 트리 구조로 보여줄 수 있어요." 계층적 클러스터링은 마치 가족 족보를 만드는 것과 같습니다.
가장 가까운 사람들부터 하나씩 묶어 나가며 점점 큰 그룹을 형성합니다. 최종적으로는 모든 데이터가 하나의 큰 가족으로 연결됩니다.
이 알고리즘에는 두 가지 접근 방식이 있습니다. 병합 방식은 각 데이터를 개별 클러스터로 시작해서 점점 합쳐나갑니다.
분할 방식은 반대로 전체를 하나의 클러스터로 시작해서 점점 나눕니다. 실무에서는 병합 방식이 더 많이 사용됩니다.
위 코드에서 linkage 함수는 클러스터 간 거리를 계산합니다. method='ward'는 워드 연결법을 사용한다는 의미입니다.
워드 방법은 클러스터 내 분산을 최소화하는 방향으로 병합합니다. 덴드로그램은 이 병합 과정을 시각화한 것입니다.
나무를 거꾸로 세운 모양으로, 아래에서 위로 갈수록 더 큰 클러스터가 형성됩니다. 세로축의 높이는 병합 시점의 거리를 나타냅니다.
실제로 클러스터를 할당하려면 AgglomerativeClustering을 사용합니다. n_clusters 파라미터로 원하는 클러스터 개수를 지정할 수 있습니다.
또는 덴드로그램에서 적절한 높이에 수평선을 그어 클러스터를 나눌 수도 있습니다. 마케팅팀에 덴드로그램을 보여주자 담당자의 눈이 반짝였습니다.
"오, 이 두 고객 그룹이 가장 비슷하군요. 이들을 타겟으로 같은 캠페인을 진행해봐야겠어요."
실전 팁
💡 - 덴드로그램의 높은 곳에서 수평선을 그으면 적은 수의 클러스터가 생깁니다
- 대용량 데이터에서는 계산 비용이 크므로 샘플링을 고려하세요
4. 연결 방법의 종류와 선택
김개발 씨가 계층적 클러스터링을 적용하던 중 의문이 생겼습니다. linkage 함수에 'ward', 'complete', 'average' 같은 옵션들이 있는데, 이게 다 무슨 차이일까요?
결과도 달라지는 것 같습니다.
연결 방법은 클러스터 간의 거리를 어떻게 계산할지 결정합니다. 단일 연결은 가장 가까운 점 기준, 완전 연결은 가장 먼 점 기준, 평균 연결은 모든 점 쌍의 평균 거리를 사용합니다.
워드 방법은 분산 증가를 최소화합니다.
다음 코드를 살펴봅시다.
from scipy.cluster.hierarchy import dendrogram, linkage
import numpy as np
import matplotlib.pyplot as plt
X = np.random.randn(20, 2)
# 다양한 연결 방법 비교
methods = ['single', 'complete', 'average', 'ward']
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
for ax, method in zip(axes.flatten(), methods):
linked = linkage(X, method=method)
dendrogram(linked, ax=ax)
ax.set_title(f'{method.capitalize()} Linkage')
# 워드 방법이 가장 균형 잡힌 클러스터를 만듦
plt.tight_layout()
김개발 씨는 같은 데이터에 다른 연결 방법을 적용해봤습니다. 결과가 상당히 다르게 나왔습니다.
어떤 방법을 선택해야 할까요? 박시니어 씨가 화이트보드에 그림을 그리며 설명합니다.
"연결 방법은 두 클러스터 사이의 거리를 어떻게 정의할지를 결정해요." 첫 번째는 단일 연결입니다. 두 클러스터에서 가장 가까운 점 사이의 거리를 클러스터 간 거리로 정의합니다.
마치 두 나라 사이의 거리를 국경에서 가장 가까운 두 도시 간 거리로 측정하는 것과 같습니다. 단일 연결의 문제점은 체이닝 현상입니다.
길쭉하게 늘어선 클러스터가 형성되기 쉽습니다. 하지만 불규칙한 형태의 클러스터를 찾을 때는 유용합니다.
두 번째는 완전 연결입니다. 이번에는 가장 먼 점 사이의 거리를 사용합니다.
두 나라에서 가장 먼 도시 간 거리로 비유할 수 있습니다. 완전 연결은 조밀하고 둥근 형태의 클러스터를 만드는 경향이 있습니다.
세 번째는 평균 연결입니다. 두 클러스터의 모든 점 쌍 사이 거리의 평균을 사용합니다.
단일 연결과 완전 연결의 중간 정도 특성을 보입니다. 네 번째는 워드 방법입니다.
이 방법은 조금 다릅니다. 두 클러스터를 합쳤을 때 증가하는 분산을 최소화하는 방향으로 병합합니다.
결과적으로 크기가 비슷한 균형 잡힌 클러스터를 만듭니다. 위 코드는 네 가지 방법을 한 번에 비교합니다.
같은 데이터라도 연결 방법에 따라 덴드로그램의 모양이 확연히 다릅니다. 실무에서는 워드 방법이 가장 많이 사용됩니다.
대부분의 경우 합리적인 결과를 제공하기 때문입니다. 하지만 특수한 형태의 클러스터가 예상된다면 다른 방법도 시도해볼 필요가 있습니다.
김개발 씨는 네 가지 방법을 모두 적용해보고, 도메인 지식과 가장 일치하는 결과를 선택했습니다. "결국 데이터의 특성을 이해하는 게 가장 중요하군요."
실전 팁
💡 - 일반적인 경우 워드 방법부터 시작하세요
- 체인 형태의 클러스터가 필요하면 단일 연결을 사용하세요
5. 덴드로그램 해석과 클러스터 수 결정
덴드로그램을 그리긴 했는데, 이걸 어떻게 해석해야 할까요? 그리고 클러스터를 몇 개로 나눠야 할지도 모르겠습니다.
김개발 씨는 덴드로그램 앞에서 한참을 고민했습니다.
덴드로그램은 계층적 클러스터링의 결과를 트리 형태로 시각화한 것입니다. 세로축은 클러스터 간 거리를, 가로축은 개별 데이터를 나타냅니다.
적절한 높이에서 수평선을 그으면 원하는 수의 클러스터를 얻을 수 있습니다.
다음 코드를 살펴봅시다.
from scipy.cluster.hierarchy import dendrogram, linkage, fcluster
import numpy as np
X = np.random.randn(30, 2)
linked = linkage(X, method='ward')
# 덴드로그램 그리기
plt.figure(figsize=(10, 7))
dendrogram(linked,
truncate_mode='lastp', # 마지막 p개 병합만 표시
p=12,
leaf_rotation=90,
leaf_font_size=10)
# 특정 거리에서 클러스터 자르기
distance_threshold = 5
clusters = fcluster(linked, t=distance_threshold, criterion='distance')
print(f"클러스터 수: {len(set(clusters))}")
# 또는 클러스터 개수로 자르기
clusters = fcluster(linked, t=3, criterion='maxclust')
김개발 씨 앞에 복잡한 덴드로그램이 펼쳐져 있습니다. 나무처럼 생긴 이 그래프를 어떻게 읽어야 할까요?
박시니어 씨가 차근차근 설명합니다. "덴드로그램은 아래에서 위로 읽으면 돼요.
아래쪽의 각 잎사귀는 개별 데이터 포인트입니다." 두 개의 잎이 만나는 지점은 두 데이터가 하나의 클러스터로 합쳐지는 순간입니다. 이 지점의 세로축 높이가 바로 두 데이터 또는 클러스터 간의 거리입니다.
위로 올라갈수록 점점 더 큰 클러스터가 형성됩니다. 맨 위에서는 모든 데이터가 하나의 클러스터로 합쳐집니다.
그렇다면 클러스터를 몇 개로 나눠야 할까요? 가장 직관적인 방법은 거리가 급격히 증가하는 지점을 찾는 것입니다.
덴드로그램에서 세로 막대가 갑자기 길어지는 부분이 있습니다. 그 직전에 수평선을 그으면 자연스러운 클러스터 구분이 됩니다.
위 코드에서 fcluster 함수는 덴드로그램을 실제로 자르는 역할을 합니다. criterion='distance'를 사용하면 특정 거리 임계값에서 자릅니다.
criterion='maxclust'를 사용하면 원하는 클러스터 개수를 직접 지정할 수 있습니다. truncate_mode='lastp' 옵션은 큰 데이터셋에서 유용합니다.
마지막 p개의 병합만 표시하여 덴드로그램을 간소화합니다. 수백, 수천 개의 데이터를 다룰 때 필수적인 옵션입니다.
실무 팁 하나를 알려드리겠습니다. 덴드로그램에서 가장 긴 세로 막대를 찾으세요.
그 막대를 가로지르는 수평선을 그으면 대개 좋은 클러스터 개수를 찾을 수 있습니다. 김개발 씨가 덴드로그램을 다시 살펴봅니다.
거리 5 부근에서 급격한 점프가 보입니다. 그 아래로 수평선을 그으니 3개의 클러스터가 자연스럽게 구분되었습니다.
"아, 클러스터 개수를 미리 정하지 않아도 데이터가 알려주는군요!" 김개발 씨의 눈이 반짝였습니다.
실전 팁
💡 - 가장 긴 세로 막대를 기준으로 자르면 자연스러운 클러스터를 얻습니다
- 대용량 데이터는 truncate_mode로 덴드로그램을 간소화하세요
6. DBSCAN과 계층적 클러스터링 비교
프로젝트가 마무리될 즈음, 팀장님이 물었습니다. "두 알고리즘 중에 어떤 걸 쓰면 좋을까요?" 김개발 씨는 두 알고리즘의 장단점을 정리해보기로 했습니다.
DBSCAN과 계층적 클러스터링은 각각 다른 상황에 적합합니다. DBSCAN은 이상치 탐지와 불규칙한 형태의 클러스터에 강하고, 계층적 클러스터링은 클러스터 간 관계 파악과 유연한 클러스터 수 결정에 유리합니다.
다음 코드를 살펴봅시다.
from sklearn.cluster import DBSCAN, AgglomerativeClustering
from sklearn.datasets import make_moons
import numpy as np
# 초승달 형태의 데이터 (불규칙한 형태)
X, _ = make_moons(n_samples=200, noise=0.05)
# DBSCAN - 불규칙한 형태에 강함
dbscan = DBSCAN(eps=0.2, min_samples=5)
dbscan_labels = dbscan.fit_predict(X)
print(f"DBSCAN 클러스터 수: {len(set(dbscan_labels)) - (1 if -1 in dbscan_labels else 0)}")
# 계층적 클러스터링 - 구형 클러스터에 적합
hc = AgglomerativeClustering(n_clusters=2)
hc_labels = hc.fit_predict(X)
print(f"계층적 클러스터링 클러스터 수: {len(set(hc_labels))}")
# 시각화하면 DBSCAN이 초승달을 더 잘 분리함
김개발 씨는 두 알고리즘을 비교하는 표를 만들기 시작했습니다. 각각의 장단점을 명확히 정리해야 팀장님께 설명할 수 있으니까요.
먼저 클러스터 개수 지정 측면입니다. DBSCAN은 클러스터 개수를 미리 지정하지 않습니다.
eps와 min_samples만 설정하면 알고리즘이 알아서 클러스터를 찾습니다. 반면 계층적 클러스터링은 덴드로그램을 먼저 그린 후, 적절한 위치에서 자르는 방식으로 클러스터 개수를 결정합니다.
이상치 처리 측면에서는 DBSCAN이 압도적입니다. 밀도가 낮은 영역의 데이터를 자동으로 노이즈로 분류합니다.
계층적 클러스터링은 모든 데이터를 어딘가에 할당하므로 이상치 탐지 기능이 없습니다. 클러스터 형태 측면을 보겠습니다.
DBSCAN은 밀도만 충분하다면 어떤 형태의 클러스터도 찾을 수 있습니다. 초승달, S자, 동심원 등 복잡한 형태도 문제없습니다.
계층적 클러스터링은 연결 방법에 따라 다르지만, 대체로 구형 클러스터에 더 적합합니다. 위 코드는 초승달 형태의 데이터를 생성하여 두 알고리즘을 비교합니다.
make_moons 함수는 두 개의 초승달이 서로 맞물린 형태의 데이터를 만듭니다. DBSCAN은 이 초승달들을 정확히 분리합니다.
밀도가 높은 영역을 따라가며 클러스터를 형성하기 때문입니다. 반면 계층적 클러스터링은 가까운 점끼리 묶으려 하므로, 초승달의 끝부분이 잘못 연결될 수 있습니다.
계산 복잡도도 중요한 고려 사항입니다. DBSCAN은 O(n log n)으로 효율적입니다.
계층적 클러스터링은 O(n^2) 이상의 복잡도를 가져 대용량 데이터에서는 느릴 수 있습니다. 하지만 계층적 클러스터링만의 장점도 있습니다.
덴드로그램을 통해 클러스터 간의 관계를 한눈에 파악할 수 있습니다. 비즈니스 인사이트를 얻는 데 매우 유용합니다.
김개발 씨가 정리를 마쳤습니다. "결론적으로 이상치 탐지나 불규칙한 형태가 예상되면 DBSCAN을, 클러스터 간 관계 파악이 필요하면 계층적 클러스터링을 쓰면 되겠군요."
실전 팁
💡 - 데이터를 먼저 시각화하여 클러스터의 예상 형태를 파악하세요
- 두 알고리즘을 모두 적용해보고 결과를 비교하는 것도 좋은 방법입니다
7. 실전 프로젝트 고객 세그멘테이션
이론 공부는 충분했습니다. 이제 실제 프로젝트에 적용할 차례입니다.
김개발 씨에게 쇼핑몰 고객 데이터를 분석하여 마케팅 타겟 그룹을 찾으라는 업무가 주어졌습니다.
실전에서는 데이터 전처리, 알고리즘 선택, 결과 해석까지 모든 과정을 통합해야 합니다. 고객 세그멘테이션은 클러스터링의 대표적인 활용 사례로, 구매 패턴이 비슷한 고객들을 그룹화하여 맞춤형 마케팅 전략을 수립합니다.
다음 코드를 살펴봅시다.
from sklearn.preprocessing import StandardScaler
from sklearn.cluster import DBSCAN, AgglomerativeClustering
import pandas as pd
import numpy as np
# 고객 데이터 (구매금액, 구매빈도, 가입기간)
data = {
'spending': [100, 150, 200, 1000, 1100, 50, 60],
'frequency': [2, 3, 2, 20, 22, 1, 1],
'tenure': [12, 14, 10, 36, 38, 2, 3]
}
df = pd.DataFrame(data)
# 스케일링 (중요!)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(df)
# DBSCAN으로 클러스터링 및 이상치 탐지
dbscan = DBSCAN(eps=0.8, min_samples=2)
df['cluster'] = dbscan.fit_predict(X_scaled)
# 결과: VIP 고객, 일반 고객, 신규 고객 그룹 식별
print(df.groupby('cluster').mean())
드디어 실전입니다. 김개발 씨 앞에 1만 명의 고객 데이터가 놓여 있습니다.
구매 금액, 구매 빈도, 가입 기간 등 다양한 변수가 있습니다. 박시니어 씨가 첫 번째 조언을 합니다.
"실전에서 가장 먼저 할 일은 데이터 전처리예요. 특히 스케일링을 빠뜨리면 안 됩니다." 왜 스케일링이 중요할까요?
구매 금액은 수십만 원 단위이고, 구매 빈도는 한 자릿수입니다. 이 상태로 거리를 계산하면 구매 금액의 영향이 압도적으로 커집니다.
빈도의 차이는 거의 무시되어 버립니다. StandardScaler를 사용하면 모든 변수가 평균 0, 표준편차 1로 변환됩니다.
이제 각 변수가 동등한 영향력을 가집니다. 스케일링이 끝나면 본격적인 클러스터링입니다.
위 코드에서는 DBSCAN을 사용했습니다. 이상치 고객을 찾아내야 하기 때문입니다.
결과를 보니 cluster 값이 -1인 고객들이 있습니다. 이들은 다른 고객들과 패턴이 많이 다른 특이 고객입니다.
VIP 고객일 수도 있고, 비정상적인 거래를 한 고객일 수도 있습니다. cluster 값이 0인 그룹은 구매 금액과 빈도가 높은 충성 고객입니다.
cluster 값이 1인 그룹은 최근 가입한 신규 고객입니다. 이런 식으로 각 클러스터에 비즈니스적 의미를 부여합니다.
마케팅팀에 결과를 전달할 때는 기술적인 용어보다 비즈니스 용어를 사용해야 합니다. "클러스터 0"이 아니라 "VIP 고객군"이라고 말하는 것이 좋습니다.
마지막으로 결과를 검증합니다. 실루엣 점수를 확인하거나, 도메인 전문가에게 결과가 합리적인지 피드백을 받습니다.
클러스터링은 정답이 없는 비지도 학습이므로, 비즈니스 맥락에서의 검증이 중요합니다. 김개발 씨는 보고서를 완성했습니다.
VIP 고객 관리 프로그램, 신규 고객 온보딩 캠페인, 이탈 위험 고객 리텐션 프로그램 등 구체적인 마케팅 전략이 도출되었습니다.
실전 팁
💡 - 클러스터링 전 반드시 스케일링을 수행하세요
- 결과를 비즈니스 관점에서 해석하고 명명하세요
- 도메인 전문가와 함께 결과를 검증하세요
이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!
댓글 (0)
함께 보면 좋은 카드 뉴스
Helm 마이크로서비스 패키징 완벽 가이드
Kubernetes 환경에서 마이크로서비스를 효율적으로 패키징하고 배포하는 Helm의 핵심 기능을 실무 중심으로 학습합니다. Chart 생성부터 릴리스 관리까지 체계적으로 다룹니다.
보안 아키텍처 구성 완벽 가이드
프로젝트의 보안을 처음부터 설계하는 방법을 배웁니다. AWS 환경에서 VPC부터 WAF, 암호화, 접근 제어까지 실무에서 바로 적용할 수 있는 보안 아키텍처를 단계별로 구성해봅니다.
AWS Organizations 완벽 가이드
여러 AWS 계정을 체계적으로 관리하고 통합 결제와 보안 정책을 적용하는 방법을 실무 스토리로 쉽게 배워봅니다. 초보 개발자도 바로 이해할 수 있는 친절한 설명과 실전 예제를 제공합니다.
AWS KMS 암호화 완벽 가이드
AWS KMS(Key Management Service)를 활용한 클라우드 데이터 암호화 방법을 초급 개발자를 위해 쉽게 설명합니다. CMK 생성부터 S3, EBS 암호화, 봉투 암호화까지 실무에 필요한 모든 내용을 담았습니다.
AWS Secrets Manager 완벽 가이드
AWS에서 데이터베이스 비밀번호, API 키 등 민감한 정보를 안전하게 관리하는 Secrets Manager의 핵심 개념과 실무 활용법을 배워봅니다. 초급 개발자도 쉽게 따라할 수 있도록 실전 예제와 함께 설명합니다.