Python/Sklearn

[Sklearn] 파이썬 t-SNE 차원 축소 시각화 예제

jimmy_AI 2022. 2. 10. 20:16
반응형

Python tsne 이용 2차원, 3차원 시각화

안녕하세요. 이번 글에서는 파이썬 사이킷런 라이브러리를 이용하여

t-SNE로 2차원 혹은 3차원으로 데이터 차원을 축소한 상태의

시각화를 진행하는 방법에 대해서 살펴보겠습니다.

 

 

t-SNE 시각화 사용 이유, 장점

데이터의 분포를 살펴보는 과정에서 처음에 각 class의 분포를 시각화를 통하여

개략적으로 살피는 것이 도움이 많이 됩니다.

 

그러나, feature가 4종류 이상인 경우, 4차원 이상의 데이터는 직접 시각화가 어렵습니다.

따라서, 보통 시각화가 편리한 2차원이나 3차원으로 차원 축소를 진행 후,

실제 feature가 아닌 축소된 주성분을 기준으로 분포를 간접적으로 시각화하게 됩니다.

 

이 과정에서, 차원 축소 방법으로는 PCA, t-SNE 등 방법을 고려할 수 있는데,

상황에 따라서 t-SNE가 실제 데이터 분포를 덜 망가뜨리고

시각화를 진행할 수 있는 경우가 많습니다.

 

이번 글에서는 이에 기존 4차원인 iris 데이터 셋을 대상으로

tsne 기법으로 차원 축소 후 시각화를 진행하는 예시로 사용 과정 이해를 도우려 합니다.

 

 

Iris 데이터 셋 불러오기

먼저, 아래의 코드로 사이킷런의 기본 데이터 셋인 붓꽃 데이터를 가져와보겠습니다.

from sklearn.datasets import load_iris
import pandas as pd
import numpy as np

# 데이터셋 로드
iris = load_iris()
df = pd.DataFrame(data= np.c_[iris.data, iris.target] , 
                  columns= ['sepal length', 'sepal width', 'petal length', 'petal width', 'target'])

기본적인 데이터 셋의 구성은 위와 같습니다.

 

4가지 종류의 feature와 꽃의 종류를 나타내는 target 열로 구성되어 있는데,

꽃 종류별로 직접 feature들의 분포를 시각화하는 것은

4차원 공간을 표현해야하므로 매우 어려워, t-SNE 차원 축소를 진행 후 그려보도록 하겠습니다.

 

 

2차원 tsne 시각화 파이썬 코드

먼저, 2차원으로 t-SNE 시각화를 진행해보도록 하겠습니다.

 

이를 위하여 사이킷런 라이브러리 내 TSNE 모듈을 임포트한 뒤,

n_components = 2로 설정하여 2차원 임베딩을 준비하겠습니다.

 

또한, target 열은 저희가 요약하고 싶은 feature가 아니므로 제외하도록 하겠습니다.

from sklearn.manifold import TSNE

# class target 정보 제외
train_df = df[['sepal length', 'sepal width', 'petal length', 'petal width']]

# 2차원 t-SNE 임베딩
tsne_np = TSNE(n_components = 2).fit_transform(train_df)

# numpy array -> DataFrame 변환
tsne_df = pd.DataFrame(tsne_np, columns = ['component 0', 'component 1'])

임베딩 과정에는 수 초 가량이 소요될 수 있습니다.

 

차원 축소를 실행하게 되면 처음에는 결과가 numpy array 자료형 형태로 등장하는데,

여기서는 추후 과정에서 다루기에 편리한 데이터프레임 형태로 변환을 하였습니다.

 

2차원으로 축소된 주성분들을 저장한 데이터프레임은 아래와 같습니다.

이제, 위에서 요약된 2차원의 주성분들을 가지고 꽃 종류별 시각화를 진행해보겠습니다.

 

기존 데이터프레임의 target(꽃 종류) 정보를 가져와 색깔을 다르게 표시해보았습니다.

import matplotlib.pyplot as plt

# class target 정보 불러오기 
tsne_df['target'] = df['target']

# target 별 분리
tsne_df_0 = tsne_df[tsne_df['target'] == 0]
tsne_df_1 = tsne_df[tsne_df['target'] == 1]
tsne_df_2 = tsne_df[tsne_df['target'] == 2]

# target 별 시각화
plt.scatter(tsne_df_0['component 0'], tsne_df_0['component 1'], color = 'pink', label = 'setosa')
plt.scatter(tsne_df_1['component 0'], tsne_df_1['component 1'], color = 'purple', label = 'versicolor')
plt.scatter(tsne_df_2['component 0'], tsne_df_2['component 1'], color = 'yellow', label = 'virginica')

plt.xlabel('component 0')
plt.ylabel('component 1')
plt.legend()
plt.show()

2차원 공간 내에 꽃 종류별로 구분이 잘 되어 임베딩된 것을 살펴볼 수 있습니다.

반응형

3차원 tsne 시각화 예제

3차원으로 축소하는 경우도 2차원의 경우와 크게 다르지는 않습니다.

TSNE 모듈에서 n_components 인자를 3으로 설정해주시면 됩니다.

# 3차원 t-SNE 임베딩
tsne_np = TSNE(n_components = 3).fit_transform(train_df)

# numpy array -> DataFrame 변환
tsne_df = pd.DataFrame(tsne_np, columns = ['component 0', 'component 1', 'component 2'])

3차원으로 임베딩된 데이터프레임은 아래와 같이 표현되었습니다.

이번에도 차원 축소 임베딩된 결과를 바탕으로 시각화를 진행해 보겠습니다.

3차원 시각화 모듈을 이용하여 꽃 종류별 산점도를 그려본 결과는 아래와 같습니다.

from mpl_toolkits.mplot3d import Axes3D

# 3차원 그래프 세팅
fig = plt.figure(figsize=(9, 6))
ax = fig.add_subplot(111, projection='3d')

# class target 정보 불러오기 
tsne_df['target'] = df['target']

# target 별 분리
tsne_df_0 = tsne_df[tsne_df['target'] == 0]
tsne_df_1 = tsne_df[tsne_df['target'] == 1]
tsne_df_2 = tsne_df[tsne_df['target'] == 2]

# target 별 시각화
ax.scatter(tsne_df_0['component 0'], tsne_df_0['component 1'], tsne_df_0['component 2'], color = 'pink', label = 'setosa')
ax.scatter(tsne_df_1['component 0'], tsne_df_1['component 1'], tsne_df_1['component 2'], color = 'purple', label = 'versicolor')
ax.scatter(tsne_df_2['component 0'], tsne_df_2['component 1'], tsne_df_2['component 2'], color = 'yellow', label = 'virginica')

ax.set_xlabel('component 0')
ax.set_ylabel('component 1')
ax.set_zlabel('component 2')
ax.legend()
plt.show()

이번에도 꽃 종류별로 임베딩된 주성분들의 분포를 한 눈에 알아볼 수 있었습니다.