앞 장의 DB는 "누가 누구인지" 이름을 미리 알고 있을 때 쓰는 방법입니다. 그런데 이름표 없이 사진 수백 장만 있고 "같은 사람끼리 묶어 줘"가 필요할 때가 있습니다. 사진 앱이 앨범 속 인물을 자동으로 그룹 짓는 그 기능입니다. 이 장에서는 인코딩을 클러스터링해 사진을 자동 분류합니다.
클러스터링이란
클러스터링(clustering)은 라벨 없이 비슷한 것끼리 묶는 일입니다. PART 04에서 본 임베딩 공간을 떠올리면 직관이 명확합니다. 같은 사람의 인코딩은 한 군데 모이므로, 그 군집을 찾아내면 곧 "같은 사람 묶음"이 됩니다. 이름을 모르는 채로도, 가까운 점들의 덩어리를 발견하는 것입니다.
DBSCAN으로 묶기
얼굴 클러스터링에는 DBSCAN이 잘 맞습니다. DBSCAN은 "몇 개의 그룹으로 나눌지"를 미리 정하지 않아도 되는 알고리즘입니다. 등장 인물이 몇 명인지 모르는 상황에 딱 맞고, 어디에도 속하지 않는 외톨이 사진을 노이즈로 따로 빼 줍니다.
# 파일: cluster.py"""라벨 없는 사진을 DBSCAN으로 인물별로 묶는다."""import globimport numpy as npimport face_recognitionfrom sklearn.cluster import DBSCANpaths, encodings = [], []for path in glob.glob("photos/*.jpg"): img = face_recognition.load_image_file(path) encs = face_recognition.face_encodings(img) for enc in encs: paths.append(path) encodings.append(enc)X = np.array(encodings)# eps: 같은 군집으로 볼 거리 한계 / min_samples: 군집 최소 인원clt = DBSCAN(metric="euclidean", eps=0.5, min_samples=3).fit(X)labels = clt.labels_ # -1은 어디에도 안 속한 노이즈num_people = len(set(labels)) - (1 if -1 in labels else 0)print(f"발견된 인물 수: {num_people}")for label in sorted(set(labels)): group = [paths[i] for i in range(len(labels)) if labels[i] == label] name = "노이즈" if label == -1 else f"인물 {label}" print(f" {name}: {len(group)}장")
DBSCAN에 인코딩 배열을 넣으면 labels_에 각 얼굴이 몇 번 군집인지 표시됩니다. 같은 번호끼리가 같은 사람이고, -1은 어디에도 충분히 가깝지 않은 외톨이(노이즈)입니다. 군집 번호에는 이름이 없으므로, 나중에 사람이 "0번은 홍길동" 하고 이름을 달아 주면 됩니다.
두 손잡이 — eps와 min_samples
DBSCAN의 결과는 두 값에 크게 좌우됩니다.
| 인자 | 의미 | 크게 하면 | 작게 하면 |
|---|---|---|---|
eps |
같은 군집으로 볼 최대 거리 | 다른 사람도 한데 묶임 | 같은 사람이 여러 군집으로 쪼개짐 |
min_samples |
군집이 되기 위한 최소 얼굴 수 | 작은 그룹은 노이즈 처리 | 두세 장도 군집 인정 |
eps는 PART 04의 임계값과 같은 성격입니다. face_recognition 인코딩에서는 0.5 안팎이 출발점으로 무난합니다. 같은 사람이 자꾸 여러 군집으로 쪼개지면 eps를 조금 키우고, 다른 사람이 한데 섞이면 줄이세요. min_samples는 사진이 적은 인물도 잡고 싶으면 낮춥니다.
실무 팁. 클러스터링 결과를 사람이 한 번 검수하는 단계를 꼭 두세요. 자동 분류는 완벽하지 않아, 닮은 두 사람이 한 군집에 섞이거나 같은 사람이 조명 때문에 둘로 갈리기도 합니다. 실제 사진 앱들도 "이 사람이 맞나요?" 하고 사용자에게 확인을 받습니다. 자동 분류로 80%를 해결하고 나머지를 사람이 다듬는 흐름이 현실적입니다.
이 장에서 기억할 것
클러스터링은 이름표 없이 비슷한 인코딩끼리 묶어 사람을 자동 분류하는 일이며, 인물 수를 미리 몰라도 되는 DBSCAN이 잘 맞습니다. labels_의 같은 번호가 같은 사람, -1은 노이즈이고, eps(거리 한계)와 min_samples(최소 인원)로 결과를 조절합니다. 자동 분류 뒤 사람의 검수를 더하는 것이 현실적입니다. 다음 장에서는 지금까지 잘 써 온 face_recognition의 한계와 함정을 정직하게 짚습니다.