1-1 군집화와 차원축소
비지도학습은 정말 다양한 방법들이 있지만 우리는 그 중에서 군집화(Clustering)
와 차원축소(Dimensionality Reduction)
를 다뤄보도록 하겠습니다. 아마 여러분들이 데이터분석을 하게 될 때, 가장 많이 사용하게 될 녀석들일 거예요!
배우고 실습하기 전에, 군집화는 무엇인지, 차원축소는 무엇인지 알 필요가 있습니다.
문제
아래의 링크를 보고, 군집화와 차원축소가 무엇인지 각각 여러분만의 언어로 정리해주세요!
1) 클러스터링(군집화)
클러스터링이란?
레이블이 없는 데이터셋을 그룹화하는 것을 클러스터링이라고 한다. 만약 레이블이 있는 데이터셋을 그룹화한다면 지도학습의 일종인 분류가 된다. 데이터셋을 그룹화하려면 유사한것들끼리 묶어야한다. 이를 위해 데이터셋의 특성 데이터를 유사성 측정이라는 측정 항목을 사용으로 결합해서 데이터들 간의 유사성을 측정할 수 있다.
클러스터링의 사용 예시
시장 세분화, 소셜 네트워크 분석, 검색결과 그룹화, 의료영상, 이미지 세분화, 이상 감지
클러스터링을 하면 각 클러스터에 클러스터 ID 라는 번호가 할당된다. 클러스터 ID가 할당되면 예시용 전체 특성 세트를 클러스터 ID로 압축할 수 있다. 이를 통해 복잡한 예를 간단한 클러스터 ID로 표현하면 클러스터링이 강력해진다. 대규모 데이터셋의 처리를 간소화할수있다.
클러스터링 출력은 다운스트림 ML 시스템의 특성 데이터 역할을 합니다.
일반화
클러스터의 일부 예시에 특성 데이터가 누락된 경우 클러스터의 다른 예시에서 누락된 데이터를 추론할 수 있다.
데이터 압축
클러스터의 모든 예시에 대한 특성 데이터는 클러스터 ID로 대체할 수 있다. 이 과정을 거치면 대체로 특성 데이터가 간소화되고 저장장소가 절약된다. 데이터셋의 규모가 커지면 커질수록 이러한 이점들이 두드러진다. 또한, 머신러닝 입력 데이터로 전체 특성 데이터셋 대신에 클러스터터 ID를 사용할수있다.
개인정보 보호
사용자를 클러스터링하고 사용자 데이터를 특정 사용자 대신 클러스터 ID와 매칭해서 개인 정보를 보존할 수 있다. 사용자 데이터로 사용자를 특정할 수 없도록 클러스터는 충분한 수의 사용자를 그룹화해야한다.
2) 차원 축소(Dimension reduction)
차원 축소란 머신러닝이나 통계분야에서 활용되는 기술로 문제의 무작위 변수(random variable)의 규모를 줄여서 주요한 변수의 집합을 구하는 것이다. 차원 축소는 두 과정으로 이루어지는데 첫 번째는 변수 선택(feature selection)과 변수 추출(feature extraction)이다. 변수 선택 과정에서는 모델을 대표할 다차원 데이터의 집합에서 특성들의 작은 부분집합들을 필터링, 임베딩, wrapping을 통해 선택한다. 변수 추출 과정에서는 데이터셋의 차원을 줄여서 변수를 모델화하고 구성 요소들에 대한 분석을 수행한다.
- 차원 축소의 방법들
- Factor Analysis
- Low Variance Filter
- High Correlation Filter
- Backward Feature Elimination
- Forward Feature Selection
- Principal Component Analysis (PCA)
- Linear Discriminant Analysis
- Methods Based on Projections
- t-Distributed Stochastic Neighbor Embedding (t-SNE)
- UMAP
- Independent Component Analysis
- Missing Value Ratio
- Random Forest
Filter Method& Wrapper Method
Filter Method
Machine Learning 과정에서 Best Feature Subset 을 주는 것이 아니라, 사용자에게 feature-rank를 줌으로 각 feature의 영향력을 알려주는 방법이다. 따라서 해당 모델에 Best Feature Subset 은 아닐 수 있더라도, 도움이 된다고 볼 수 있다. 또한 여기서 각 ranking 화 한 Feature 들은 독립변수로 본다.
Wrapper Method
Machine Learning의 예측 정확도 측면에서 가장 좋은 성능을 보이는 Subset을 뽑아내는 방법이다. Machine Learning 을 진행하면서 Best Feature Subset을 찾아가는 방법이기 때문에 시간과 비용이 매우 높게 발생한다. 하지만 최종적으로 Best Feature Subset을 찾아주기 때문에 모델의 성능을 위해서는 적절하다. 물론, 해당 모델의 파라미터와 알고리즘 자체는 완성도가 높아야 제대로 된 Best Feature Subset을 찾을 수 있다.
- Forward Selection(전진 선택) : 변수가 없는 상태로 시작하며 반복할 때마다 가장 중요한 변수를 추가하여 더 이상 성능의 향상이 없을 때까지 변수를 추가한다.
- Backward Elimination(후방 제거) : 모든 변수를 가지고 시작하며, 가장 덜 중요한 변수를 하나씩 제거하면서 모델의 성능을 향상시킨다. 더 이상 성능의 향상이 없을 때까지 반복한다.
- Stepwise Selection(단계별 선택): Foward Selection 과 Backward Elimination 을 결합하여 사용하는 방식으로, 모든 변수를 가지고 시작하여 가장 도움이 되지 않는 변수를 삭제하거나, 모델에서 빠져있는 변수 중에서 가장 중요한 변수를 추가하는 방법이다. 이와 같이 변수를 추가 또는 삭제를 반복한다. 반대로 아무것도 없는 모델에서 출발해 변수를 추가, 삭제를 반복할 수도 있다.
1-2 K-Means
가장 고전적이면서 직관적으로 이해하기 쉬운 군집화 기법입니다. K-Means는 다음과 같은 과정을 통해 군집화가 이루어져요!
임의의 중심점 설정
처음엔 임의의 장소에 사전에 설정해준 군집의 수(k)만큼의 중심점을 배치해줍니다. 그리고 일단 가장 기본적으로 이 중심점을 기준으로 데이터들을 군집화 하게 됩니다.
위쪽에 있는 초록색 중심점과 가까운 데이터들은 초록 중심점 소속으로,
아래에 있는 노란색 중심점과 가까운 데이터들은 노랑 중심점 소속으로
각각 구분이 된다는 것이죠.
그러나 저 중심점의 위치가 과연 정말 최적의 위치일까요? 데이터들을 좀 더 잘 구분하려면 *"중심이 데이터들의 가운데"* 에 있어야 합니다.
가운데로 가기 위해서, 중심점은 데이터와 본인과의 거리를 계산하면서 점점 데이터의 중심으로 이동하기 시작합니다.
평균의 중심으로 중심점 이동
각 데이터와 중심점간의 거리를 나타낸 그림입니다. 이 중심점까지의 거리가 평균적으로 비슷할 때까지 중심점을 이동시키는 것이죠.
중심점이 이동되면, 이동한 중심점에 대해 데이터들의 소속 또한 다시 새롭게 정의됩니다. 지금의 그림에선 나타나지 않지만, 이동하기 전에는 초록색 중심점 소속이었지만, 이동하고 나서는 노란색 중심점 소속일 수도 있다는 것이죠.
보시면 초록색 점이 그나마 데이터들의 중심으로 이동했습니다. 이런 식으로 계속해서 중심점을 이동시킵니다.
중심점 확정 및 최종 군집화
위와 같은 방법으로 중심점은 계속 반복해서 이동합니다. 언제까지 이동하냐구요? 이동해도 그 위치일때까지요!
중심점을 이동하다보면,,
이렇게 거리를 계산해서 이동시켜도 더 이상 움직이지 않는 순간이 생깁니다.
이 순간의 중심점을 최종 중심점으로 잡고, 그 순간의 데이터들의 소속 또한 최종 소속으로 잡는 것이죠. 이렇게 군집화가 이루어집니다.
그럼 우리가 원했던 군집화가 이루어지는 것이죠.
문제
아래의 baseline코드에 비어있는 부분에 적절한 코드를 넣어 완성해주세요.
군집화 알고리즘은 KMeans
로, 군집의 수는 3개
로, random_state는 42
로 지정해주세요!
**import** pandas **as** pd
**import** numpy **as** np
**from** sklearn.cluster **import** KMeans
kmeans **=** ```!!HERE YOUR CODE!!
kmeans.`!!HERE YOUR CODE!!`(X) cluster*labels = kmeans.labels*
df['clusters'] = cluster_labels
clustercenters 는 개별 클러스터의 중심 위치 좌표 시각화를 위해 추출
centers = kmeans.cluster*centers*
unique_labels = np.unique(cluster_labels)
markers=['o', 's', '^', 'P','D','H','x']
군집된 label 유형별로 iteration 하면서 marker 별로 scatter plot 수행.
for label in unique_labels:
label_cluster = df[df['clusters']==label]
center_x_y = centers[label]
plt.scatter(x=label_cluster['x1'], y=label_cluster['x2'],
edgecolor='k', marker=markers[label] )
# 군집별 중심 위치 좌표 시각화
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=200, color='white',
alpha=0.9, edgecolor='k', marker=markers[label])
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=70, color='k', edgecolor='k',
marker='$%d$' % label)
plt.show()
print()
print("👀실제 값과 군집 비교👀")
print(df.groupby('label')['clusters'].value_counts()) ```
검색 힌트 : sklearn kmeans, sklearn kmeans fit_predict
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import make_blobs
kmeans = KMeans(n_clusters=3,random_state = 42)
X,y = make_blobs(n_samples = 500, n_features = 2,
centers = 3, cluster_std = 2, random_state = 42)
df = pd.DataFrame(data = X, columns = ['x1', 'x2'])
df['label'] = y
target_list = np.unique(y)
color_list = ['r','g','b']
for target, color in zip(target_list, color_list):
target_cl = df[df['label'] == target]
plt.scatter(x = target_cl['x1'], y = target_cl['x2'],edgecolor = 'k', color = color)
plt.show()
kmeans = KMeans(n_clusters=3,random_state = 42)
kmeans.fit_predict(X)
cluster_labels = kmeans.labels_#_가 빠짐
df['clusters'] = cluster_labels
centers = kmeans.cluster_centers_
unique_labels = np.unique(cluster_labels)
markers=['o', 's', '^', 'P','D','H','x']
for label in unique_labels:
label_cluster = df[df['clusters']==label]#해당 label에 해당하는 데이터들의 df
center_x_y = centers[label] #해당 label에 맞는 중심의 좌표
plt.scatter(x=label_cluster['x1'], y=label_cluster['x2'], edgecolor='k', marker=markers[label] )
# 군집별 중심 위치 좌표 시각화
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=200, color='white',
alpha=0.9, edgecolor='k', marker=markers[label])
plt.scatter(x=center_x_y[0], y=center_x_y[1], s=70, color='k', edgecolor='k',
marker='$%d$' % label)
plt.show()
print()
print("👀실제 값과 군집 비교👀")
print(df.groupby('label')['clusters'].value_counts())
KMeans 함수의 파라미터중 n_clusters 는 군집의 개수를 정해주는 옵션이고, random_state를 통해서 난수를 고정할 수 있다. 이후 make_blobs로 가상의 데이터를 만들고 X, y에 데이터를 로드한다. 독립변수의 수가 두개이므로 생성한 데이터프레임의 칼럼값은 x1, x2로 정한다. 데이터 프레임의 레이블값으로
make_blobs
로 로드한 y를 추가한다. 여기서 y값은 클러스터의 종류를 표현하는 일종의 레이블이다. Numpy의unique
메서드로 target_list를 선언했다. for문을 이용해서 target_cl이란 데이터 프레임을 새로 선언하고 산점도 그래프로 출력했다.
kmeans.label_ : 각 데이터가 어떤 클러스터에 속하는지 그 결과를 표현한다.
cluster_centers_ : 학습된 kmeans 모델은 centroids(군집의 중심점)을 갖는다. 이를 수치적으로 출력하기 위해서 위 함수로 좌표값을 확인할 수 있다.
1-3 실루엣 계수
문제
위에서 형성한 k-means
기반 군집의 실루엣 계수를 측정해주세요!
**from** sklearn.metrics **import** silhouette_score, silhouette_samples
*## 각 데이터별 실루엣 점수*samples **=** ```!!HERE YOUR CODE!!
df['silhouette'] = samples
전체 실루엣 점수
score = !!HERE YOUR CODE!!
print(f"🚀전체 실루엣 점수🚀\n{score:.2f}\n")
print("📃군집별 평균 실루엣 점수📃")
print(df.groupby('clusters')['silhouette'].mean())
검색 힌트: sklearn silhouette_score, sklearn silhouette_samples
from sklearn.metrics import silhouette_score, silhouette_samples
##각 데이터별 실루엣 점수
samples = silhouette_samples(df, df['clusters'])
df['silhouette'] = samples
score = silhouette_score(df, df['clusters'])
print(f"🚀전체 실루엣 점수🚀\n{score:.2f}\n")
print("📃군집별 평균 실루엣 점수📃")
print(df.groupby('clusters')['silhouette'].mean())
2-1 차원축소
문제
아래의 baseline코드에서 적절한 함수를 입력하여 함수를 완성해주세요! 단, 2개의 축으로 압축시켜주세요.
**import** pandas **as** pd
**import** numpy **as** np
**from** sklearn.datasets **import** ***from** sklearn.preprocessing **import** StandardScaler
**from** sklearn.decomposition **import** PCA
X, y **=** load_iris(return_X_y**=True**, as_frame**=True**)
normal_dataset **=** pd**.**concat([X, y], axis**=**1)
ss **=** StandardScaler()
scaled_X **=** ss**.**fit_transform(X)
pca **=** ```HERE YOUR CODE!!
pca_features = pca.HERE YOUR CODE!!(scaled_X)
pca_col*lst = [f"pca*{i}"
for i in range(1, pca_features.shape[1]+1)]
pca_dataset = pd.DataFrame(pca_features, columns=pca_col_lst)
pca_dataset = pd.concat([pca_dataset, y], axis=1)
print("🚩압축된 각 축이 전체 변수를 얼마나 설명하는지🚩")
print(pca.explained_variance*ratio*, f"-> 전체 설명률 : {sum(pca.explained_variance*ratio*)*100:.2f}%")
pca_dataset
REFERENCE
'인공지능 > 인공지능 기초 개념' 카테고리의 다른 글
Tensor에 대해 (0) | 2024.03.19 |
---|---|
Gradient Descent 직접 구현하기 (0) | 2024.03.19 |
(7) 비지도 학습 (1) | 2024.03.15 |
(6)-2 지도학습 실습 (2) | 2024.03.15 |
(6) 지도학습 (0) | 2024.03.15 |