비지도학습
비지도학습(Unsupervised Learning): 정답 라벨 없이 변수만 있는 데이터 활용
예측보다 데이터 안의 숨은 구조와 반복 패턴 파악이 목적
주요 활용 분야
데이터를 의미 있는 성질로 쪼개는 군집분석(Clustering)
불필요한 차원/노이즈를 걸러내는 차원 축소(Dimensionality Reduction)
운항 이상 징후를 감지하는 이상치 탐지(Anomaly Detection)
군집분석의 목적과 절차
변수값이 비슷한 개체끼리 여러 군집(Cluster)으로 자동 그룹화
같은 군집 안의 개체는 서로 비슷해야 함
다른 군집의 개체와는 충분히 달라야 함
클러스터링의 종류
파티션(partition) 알고리즘: 수평적인 군집들로 나눔
K-Means
Mixture of Gaussian
Spectral Clustering
위계적(hierarchical) 알고리즘: 큰 군집 안에 작은 군집들이 포함되는 형태로 나눔
k-평균 군집화
대표적인 파티션 클러스터링 알고리즘 중 하나
K-Means: "K개의 평균"이라는 뜻
각 사례가 다른 군집보다 자신이 속한 군집의 중심점에 가장 가깝게 만듦
각 군집의 중심점은 해당 군집에 속한 사례들의 평균
예시 절차
사례들을 두 개의 군집으로 나눌 경우, 무작위로 두 군집의 중심점을 설정
각 사례들을 두 중심점 중 더 가까운 중심점의 군집으로 분류
각 군집에 속한 사례들을 평균하여 새로운 중심점을 설정
더 이상 군집에 변화가 없을 때까지 분류와 중심점 갱신을 반복
K-Means 실습: 데이터 로딩
pip install pandas seaborn scikit-learn openpyxl numpy
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
df_ship = pd.read_excel('ship_cluster.xlsx' )
K-Means 실습: 군집에 사용할 변수 선택
feature_cols = [
'route_distance_nm' ,
'avg_payload_ton' ,
'daily_engine_hour' ,
'service_speed_knot' ,
'fuel_use_ton_day' ,
'port_stay_hour' ,
'maintenance_interval_day' ,
]
X_cluster = df_ship[feature_cols]
표준화의 필요성
K-Means는 두 데이터 점 사이의 거리를 기준으로 비슷한 정도 계산
운항거리, 적재량, 연료 사용량처럼 여러 변수의 차이를 합쳐 거리 계산
변수 범위가 다르면 큰 숫자의 변수가 군집 결과를 좌우
표준화는 변수마다 평균 0, 표준편차 1로 맞춰 같은 기준에서 비교
z = σ x − x ˉ
K-Means 실습: 표준화 및 군집화
여러 운항 변수를 함께 사용해 군집화
각 운항 사례에 군집 번호 부여
X_scaled = StandardScaler().fit_transform(X_cluster)
kmeans = KMeans(n_clusters=3 , random_state=42 , n_init=10 )
df_ship['cluster' ] = kmeans.fit_predict(X_scaled)
df_ship[['case_id' , 'operation_case' , 'cluster' ]].head()
계층적 군집화
데이터를 단계적으로 묶어가며 군집 구조를 찾는 방법
군집 개수를 처음부터 꼭 정하지 않아도 됨
기본 방식
병합형: 각 데이터를 하나의 군집으로 시작해 가장 가까운 군집끼리 차례로 합침
분할형: 전체 데이터를 하나의 군집으로 시작해 점점 작은 군집으로 나눔
결과 표현
덴드로그램으로 군집이 합쳐지는 과정을 시각화
어느 높이에서 자르느냐에 따라 군집 개수가 달라짐
밀도 기반 군집화
데이터가 많이 모여 있는 밀집 영역을 군집으로 찾는 방법
대표 알고리즘: DBSCAN
기본 아이디어
가까운 이웃이 충분히 많은 점을 중심으로 군집을 형성
밀도가 낮은 지역의 점은 군집에 포함하지 않고 이상치로 볼 수 있음
주요 개념
반경: 주변 이웃을 찾는 거리 기준
최소 이웃 수: 군집 중심으로 인정되기 위한 최소 데이터 수
이상치: 어느 밀집 영역에도 속하지 않는 점
장점
군집 개수를 미리 정하지 않아도 됨
둥근 모양이 아닌 복잡한 형태의 군집도 찾을 수 있음
이상치 탐지에 유용
군집 결과 평가
분류와 달리 정답 라벨이 없는 상황에서 군집의 적절성을 판단
좋은 군집의 기준
같은 군집 안의 데이터는 서로 비슷해야 함
다른 군집의 데이터는 서로 달라야 함
군집 수가 너무 많거나 너무 적지 않아야 함
관성(inertia)
K-Means에서 자주 쓰는 평가 지표
각 데이터가 자신이 속한 군집 중심에서 얼마나 떨어져 있는지를 제곱해 모두 더한 값
관성이 작을수록 군집 내부가 더 조밀하다는 뜻
단, 군집 수를 늘리면 관성은 거의 항상 작아지므로 단독 기준으로 쓰기 어려움
평가 방법
엘보 방법: 군집 수를 늘릴 때 관성 감소 폭이 급격히 줄어드는 지점을 찾음
실루엣 계수: 같은 군집 안에서는 가깝고, 다른 군집과는 먼 정도를 평가
해석 가능성: 각 군집이 실제 업무나 도메인 지식으로 설명 가능한지 확인
최적의 군집 개수 탐색: 엘보우 방법
K-Means는 몇 개의 묶음(K )으로 나눌지 분석가가 사전에 결정해야 함
K 를 1개부터 늘려가며 관성(inertia)을 계산
관성: 군집 안 거리의 제곱합, 즉 군집이 퍼진 정도
K 가 늘면 관성이 줄지만, 어느 순간부터 개선 폭 감소
그래프가 급하게 내려가다 완만해지는 지점을 후보 K 로 판단
실습 데이터에서는 K = 3 부근의 변화 확인
inertia = []
for k in range (1 , 8 ):
km = KMeans(n_clusters=k, random_state=42 , n_init=10 ).fit(X_scaled)
inertia.append(km.inertia_)
sns.lineplot(x=range (1 , 8 ), y=inertia, marker="o" )
군집 분리 정도 확인: 실루엣 계수
각 데이터가 같은 군집에는 얼마나 가깝고 다른 군집에는 얼마나 먼지 평가
값의 범위는 − 1 부터 1
1 에 가까울수록 군집 내부는 조밀하고 군집 사이는 잘 분리됨
0 에 가까우면 군집 경계가 서로 겹침
음수이면 다른 군집에 더 가까운 데이터가 있을 수 있음
여러 K 의 실루엣 계수를 비교하되 엘보우 결과와 해석 가능성도 함께 고려
from sklearn.metrics import silhouette_score
silhouette_scores = []
for k in range (2 , 8 ):
labels = KMeans(
n_clusters=k, random_state=42 , n_init=10
).fit_predict(X_scaled)
silhouette_scores.append(silhouette_score(X_scaled, labels))
sns.lineplot(x=range (2 , 8 ), y=silhouette_scores, marker="o" )
실습 데이터: 물류센터 작업 패턴
물류센터 작업 기록 480건
일별 주문량, 피킹 작업, 인력, 설비 가동률, 초과근무 패턴으로 운영 유형 탐색
정답 라벨 없이 여섯 개 숫자형 변수를 표준화하여 K-Means 적용
컬럼 설명 operation_id작업 기록 식별자 daily_order_count일일 처리 주문 수(건) avg_picking_min주문당 평균 피킹 시간(분) picking_error_pct피킹 오류율(%) worker_count작업 인원(명) equipment_utilization_pct설비 가동률(%) overtime_hour일평균 초과근무 시간(시간)
데이터 불러오기와 변수 선택
df_warehouse = pd.read_excel("warehouse_operations.xlsx" )
warehouse_feature_cols = [
"daily_order_count" ,
"avg_picking_min" ,
"picking_error_pct" ,
"worker_count" ,
"equipment_utilization_pct" ,
"overtime_hour" ,
]
X_warehouse = df_warehouse[warehouse_feature_cols]
X_warehouse_scaled = StandardScaler().fit_transform(X_warehouse)
위에서 사용한 K-Means, 엘보우 방법, 실루엣 계수 코드를 적용하여 다음 문제에 답하세요.