클러스터링
유사한 데이터들을 같은 클러스터(집단)으로 묶어 주는 작업을 의미하며, 우리말로는 '군집화' 라고도 한다.
클러스터링은 머신러닝 기법 중, 비지도 학습에 해당한다.
머신러닝은 컴퓨터가 데이터들을 통해 스스로 규칙을 학습하도록 하는 인공지능의 한 방법인데, 이 중 비지도 학습 정답(레이블)을 주지 않은 상태에서 데이터의 특성만 가지고 스스로 규칙을 찾아내는 방식이다.
클러스터링과 분류(Classification)
클러스터링과 비슷하게 데이터들의 특성을 바탕으로 특정 범주로 구분해 주는 분류(Classification) 문제도 있다.
예를 들어서, 100명의 학생이 공부한 시간과 시험에 통과했는지 여부를 체크한 데이터가 있을 때 이 데이터를 바탕으로, 새로운 학생이 몇 시간 공부했는지에 따라 시험에 통과할 수 있을지를 예측해 볼 수 있다.
해당 상황에서는 구분하고 싶은 정답(시험 통과 여부)이 데이터에 이미 존재한다. 그리고, 변수(공부 시간)와 정답 사이의 규칙성을 모델이 미리 학습하여 새로운 데이터를 합격과 불합격 범주 중 하나로 분류한다.
데이터에 미리 정답 레이블이 있는 상태로 모델을 학습시키기 때문에, 이 경우는 지도 학습에 해당된다.
클러스터링과 분류는 데이터의 특성에 따라 범주를 구분한다는 점이 유사합니다.
하지만, 클러스터링은 정답이 없는 상황에서 순수하게 데이터의 특성만으로 구분하고, 분류는 데이터의 특성과 정답 사이의 관계를 학습하여 새로운 데이터가 어떤 범주에 해당할지 구분한다.
이러한 방식의 차이 때문에 둘의 결과에도 차이가 있다. 분류 모델의 결과는 특정한 범주에 할당(위의 예시처럼 공부 시간에 따른 결과가 ‘합격’ 또는 ‘불합격’으로 정해짐)되지만,
클러스터링은 데이터들이 특정 클러스터에 할당될 뿐, 그 클러스터가 무엇을 의미하는지가 함께 결과로 나오진 않는다. 해당 클러스터가 무엇을 의미하는지는 분석하는 사람이 별도로 해석해야 한다.
이렇게, 데이터의 특성에 따라 적용하는 방법이 다르기 때문에 어떤 상황에서 어떤 방법론을 적용해야 할지 잘 판단하여 사용해야 한다.
예제
아래의 좌측 데이터를 바탕으로 우측의 산점도를 그려보았다. 이때, 데이터가 넓고 고르게 분포해있어 단순한 시각화만으로는 많은 정보를 얻기 힘들다. 이에 클러스터링 작업을 진행해보자.
아래의 표와 시각화는 위의 데이터를 바탕으로 클러스터링을 진행한 모습이다.
0번 클러스터에 228명, 1번 클러스터에 146명, 2번 클러스터에 126명이 할당되었다.
이렇게 나누었을 때, 각 클러스터의 특징을 확인할 수 있다.
먼저, 가장 많은 유저가 포함된 클러스터 0은 방문 횟수와 사용 시간이 모두 적다. 이는 다수의 유저들이 앱을 많이 사용하지 않고 있다고 해석할 수 있다. 해당 클러스터의 유저들이 앱에 좀 더 자주 방문하거나 사용 시간을 늘릴 수 있도록 대안이 필요하다고 볼 수 있다.
마찬가지로 클러스터 1과 클러스터2에 포함된 유저들의 특징을 참고면 어떤 조치를 취하는게 좋을 지 결정할 수 있다.
포함된 유저 수 | 월 방문 횟수(평균) | 월 사용 시간(평균) | |
클러스터 0 | 228 | 15.8 | 8.4 |
클러스터 1 | 146 | 14.5 | 21.4 |
클러스터 2 | 126 | 27.2 | 11.6 |
클러스터링의 원리
- 유사한 데이터는 같은 클러스터로 묶는다.
- 유사하지 않은 데이터는 다른 클러스터로 묶는다.
'유사한 데이터'의 정의를 '거리가 가까운 데이터가 유사하다'라는 기준하에 다시 정리하면,
- 거리가 가까운 데이터는 같은 클러스터로 묶는다.
- 거리가 먼 데이터는 다른 클러스터로 묶는다.
위의 정의를 바탕으로 아래 그림을 보면, 왼쪽은 같은 색으로 묶인 데이터 간의 거리가 가까운 반면 다른 색으로 묶인 데이터 간의 거리가 멀다. 반면, 오른쪽은 같은 색 데이터 간의 거리가 가까운 부분도 있으나 먼 부분도 있다. 이를 바탕으로 왼쪽이 오른쪽에 비해 클러스터링이 조금 더 잘 되었다는 것을 알 수있다.
즉, 클러스터링을 할 때에는 어떤 기준을 사용하냐에 따라 결과가 다르게 나오게 된다.
데이터 준비하기
데이터 확인
import pandas as pd
# 판다스 출력 결과를 소수점 둘째 자리 까지로 제한
pd.options.display.float_format = '{:,.2f}'.format
sales_df = pd.read_csv("/content/drive/MyDrive/Colab Notebooks/Codeit/data/sales_data.csv", index_col=['customer_id'])
sales_df
이상치 제거
import seaborn as sns
sns.set(style="darkgrid",
rc={'figure.figsize':(16,9)})
# 데이터 시각화
sns.scatterplot(x=sales_df['total_buy_cnt'], y=sales_df['total_price'], s=200)
IQR방법 사용
def get_outlier_mask(df, weight=1.5):
Q1 = df.quantile(0.25) # 1사분위수(데이터의 25% 지점)
Q3 = df.quantile(0.75) # 3사분위수(데이터의 75% 지점)
# 데이터의 중간 50% 범위
IQR = Q3 - Q1
# 가중치를 적용한 IQR 범위 계산
IQR_weight = IQR * weight
# 이상치 판별 범위 설정
range_min = Q1 - IQR_weight
range_max = Q3 + IQR_weight
# 이상치 판별
outlier_per_column = (df < range_min) | (df > range_max) # 계산된 결과는 각 열에 대해 이상치 여부를 나타내는 불리언 마스크륿 반환
# 이상치가 있는 행 판별
is_outlier = outlier_per_column.any(axis=1) # 행 단위로 이상치가 있는지 판별, 하나의 열이라도 이상치가 있다면 해당 행을 'True'로 표시함
return is_outlier
outlier_idx_cust_df = get_outlier_mask(sales_df, weight=1.5)
# 아웃라이어 제거한 데이터 프레임만 추가
sales_df = sales_df[~outlier_idx_cust_df]
# 아웃라이어 제거한 데이터프레임 시각화
sns.scatterplot(x=sales_df['total_buy_cnt'], y=sales_df['total_price'], s=200)
데이터 표준화(Standardization)
두 변수(total_buy_cnt, total_price)의 단위의 차이가 많이 난다. 이러면 total_price의 영향력이 너무 커져 결과가 잘못될 가능성이 높다. 그러므로 표준화를 통해 변수 단위에 따른 상대적 영향을 제거해야 한다.
표준화와 정규화
표준화(Standardization)와 정규화(Normalization)는 데이터의 크기나 분포를 조정하여 분석에 적합하게 만드는 두 가지 방법입니다. 이들은 머신러닝, 통계분석, 데이터 전처리에서 자주 사용되지만, 목적과 방법에서 차이가 있습니다.
1. 표준화 (Standardization)
표준화는 데이터의 평균을 0으로, 표준편차를 1로 변환하는 방법입니다. 이는 데이터의 분포를 중심으로 위치시키고, 각 변수의 스케일을 동일하게 만듭니다.
- 공식:Xstandard=X−μσX_{standard} = \frac{X - \mu}{\sigma}
- XX: 원본 데이터 값
- μ\mu: 데이터의 평균
- σ\sigma: 데이터의 표준편차
- 목적: 주로 변수들이 서로 다른 단위를 가질 때, 스케일을 맞춰 비교할 수 있도록 하기 위해 사용됩니다. 예를 들어, 키와 몸무게가 같은 데이터셋에 포함될 때, 각각의 값이 같은 범위에 있도록 조정합니다.
- 적용: 데이터가 정규 분포를 따를 때 유용하며, 회귀 분석이나 K-평균 클러스터링과 같은 알고리즘에 자주 사용됩니다.
2. 정규화 (Normalization)
정규화는 데이터를 0과 1 사이의 범위로 변환하는 방법입니다. 이는 데이터의 최소값을 0, 최대값을 1로 변환하여 스케일을 조정합니다.
- 공식:Xnormalized=X−XminXmax−XminX_{normalized} = \frac{X - X_{min}}{X_{max} - X_{min}}
- XX: 원본 데이터 값
- XminX_{min}: 데이터의 최소값
- XmaxX_{max}: 데이터의 최대값
- 목적: 데이터가 다른 범위를 가질 때, 특히 최대와 최소 사이의 차이가 큰 경우 데이터를 동일한 범위로 조정하여 알고리즘의 성능을 향상시키기 위해 사용됩니다. 이는 특히 신경망이나 K-최근접 이웃(KNN)과 같은 알고리즘에서 유용합니다.
- 적용: 데이터가 일정한 범위 내에서 변동할 때 사용됩니다. 예를 들어, 픽셀 값이 0과 255 사이에 있는 이미지 데이터를 0과 1 사이로 조정하는 경우에 적합합니다.
요약
- 표준화: 데이터의 평균을 0, 표준편차를 1로 맞추어 분포를 조정합니다. 데이터가 정규 분포를 따를 때 유용합니다.
- 정규화: 데이터를 0과 1 사이의 범위로 변환하여, 스케일을 맞춥니다. 주로 데이터의 스케일 차이가 크고, 모든 데이터가 동일한 범위로 조정되어야 할 때 사용됩니다.
df_mean = sales_df.mean() # 각 컬럼이 평균값
df_std = sales_df.std() # 각 컬럼의 표준편차
scaled_df = (sales_df - df_mean) / df_std # 컬럼별 표준화 진행
scaled_df.columns = ['total_buy_cnt', 'total_price']
# 인덱스 설정
scaled_df.index = sales_df.index
scaled_df