정답이 없는 데이터를 학습하면서 비슷한 패턴을 가진 것끼리 군집으로 묶는다
차원이 높으면 데이터가 희박(sparse)해서 데이터가 더 필요하고 계산이 복잡해져서 시간이 오래 걸린다
(feature가 많은 게 오히려 역효과)
목적 : 차원이 줄어도 성능을 비슷하게 만들기
방법 : PCA, tSNE
# 기본 라이브러리 가져오기
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import *
from sklearn.datasets import load_breast_cancer, load_digits
from sklearn.preprocessing import StandardScaler, MinMaxScaler
# 데이터 로딩
cancer=load_breast_cancer()
x = cancer.data
y = cancer.target
x = pd.DataFrame(x, columns=cancer.feature_names)
# 스케일링(거리계산 기반 차원 축소)
scaler = MinMaxScaler()
x = scaler.fit_transform(x)
# (옵션)데이터 프레임 변환
x = pd.DataFrame(x, columns=cancer.feature_names)
# 데이터 분할
x_train, x_val, y_train, y_val = train_test_split(x, y, test_size = .3, random_state = 20)
선형 축소 방식이고 '분산'을 최대한 유지하고자 함
차원의 수 : feature 수(만큼 축을 찾는다는 얘기)
용도 : 지도학습으로 연계하여 데이터 분석 기법 사용
# 주성분 만들기
from sklearn.decomposition import PCA
# feature 수
x_train.shape[1]
n = x_train.shape[1]
# 주성분 분석 선언
pca = PCA(n_components=n)
#만들고 적용하기
x_train_pc = pca.fit_transform(x_train)
x_val_pc = pca.transform(x_val)
# 칼럼이름 생성
column_names = [ 'PC'+str(i+1) for i in range(n) ]
# 데이터프레임으로 변환하기
x_train_pc = pd.DataFrame(x_train_pc, columns = column_names)
x_val_pc = pd.DataFrame(x_val_pc, columns = column_names)
x_train_pc
# 주성분 1개 짜리
pca1 = PCA(n_components = 1)
x_pc1 = pca1.fit_transform(x_train)
# 주성분 누적 분산 그래프
plt.plot(range(1,n+1), pca.explained_variance_ratio_, marker = '.')
plt.xlabel('No. of PC')
plt.grid()
plt.show()
# 학습
model0 = KNeighborsClassifier()
model0.fit(x_train, y_train)
# 예측 및 평가
pred0 = model0.predict(x_val)
print(confusion_matrix(y_val, pred0))
print(accuracy_score(y_val, pred0))
print(classification_report(y_val, pred0))
비선형 축소 방식이고 '유사도(거리)'를 최대한 유지
차원의 수 : 2~3
용도 : 데이터 시각화
# 2차원 시각화
tsne = TSNE(n_components=2, random_state=20)
x_tsne = tsne.fit_transform(x)
# 데이터프레임으로 변환(옵션)
x_tsne = pd.DataFrame(x_tsne, columns = ['T1', 'T2'])
# 시각화
plt.figure(figsize=(8, 8))
sns.scatterplot(x = 'T1', y = 'T2', data = x_tsne, hue = y)
plt.grid()
plt.show()