[DS] PCA 차원 감소 (PCA Dimensionality Reduction)

AirPlaneMode·2022년 4월 23일
0

1. PCA

주성분 분석 혹은 PCA(Principal Component Analysis) 고차원의 데이터를 저차원의 데이터로 선형변환하는 것을 의미한다.

즉, 데이터셋에 있어서 데이터셋의 column(혹은 feature) 개수를 줄일 수 있는 기법이다.

1.1 Feature의 개수를 왜 줄여야 할까

Feature의 개수가 많다는 것은, 한 데이터를 표현하는 정보의 양(volumn)이 많다는 것을 의미한다.

그러나 모든 feature가 데이터를 표현하기 위해 유의미한 정보를 담고 있는 것은 아니다. feature는 데이터와 관련이 없거나, 연관성이 적은 정보들로 구성될 수도 있는데, 이런 경우 모델의 연산량이 증가할 뿐더러 모델이 필요 없는 정보를 학습하여 성능이 저하될 수 있다. (차원의 저주, Curse of Dimensionality)

따라서 유의미한 feature들과, 이러한 feature 간의 관계는 유지하면서도 불필요한 feature는 제거하는 과정이 필요한데, 이를 Dimensionality Reduction (차원 감소)라고 한다.

2. 코드

2.1 데이터 셋 생성

from sklearn.datasets import make_classification
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt

random_state = 42

data, y = make_classification(n_samples = 1000, n_features=10, n_informative=7,
                              n_redundant=3, n_classes = 3, random_state= random_state)

df = pd.DataFrame(data = data, columns = ["v" + str(i) for i in range(10)])

각 10 개의 feature를 가진 200 개의 sample을 만들었다. 10 개의 feature 중 유의미한(informative) feature는 7개로, 나머지 3개는 무의미(redundant)한 feature임을 확인할 수 있다.

2.2 PCA

from sklearn.model_selection import StratifiedKFold
from sklearn.decomposition import PCA
from sklearn.linear_model import LogisticRegression
from sklearn.pipeline import Pipeline
import numpy as np

loader = StratifiedKFold(n_splits = 5, shuffle = True, random_state = random_state)

for i in range(1,11):
    steps = [('pca', PCA(n_components = i)), ('m', LogisticRegression())]
    scores = []
    
    for train_idx, test_idx in loader.split(df, y):
        train_x = df.iloc[train_idx]
        train_y = y[train_idx]
        
        test_x = df.iloc[test_idx]
        test_y = y[test_idx]
        
        model = Pipeline(steps = steps)
        model.fit(train_x, train_y)
        
        pred = model.predict(test_x)
        matched = len(np.where(pred == test_y)[0])
        
        score = (matched / len(pred))*100
        scores.append(score)
        
    total_score = sum(scores)/len(scores)
    print(f"total_score (n_components = {i}): {total_score}")

PCA class의 n_components 변수는 남겨놓을 component(여기서는 feature)의 개수를 의미한다. 즉, n_components = 5는 10 개의 feature를 5개의 feature로 변환한다는 것을 뜻한다.

n_components의 값을 1부터 10까지 하나씩 올려가면서 PCA를 진행하고 LogisticRegression을 실행했을 때의 결과는 다음과 같다.

total_score (n_components = 1): 42.3
total_score (n_components = 2): 57.3
total_score (n_components = 3): 57.4
total_score (n_components = 4): 70.8
total_score (n_components = 5): 69.9
total_score (n_components = 6): 76.2
total_score (n_components = 7): 80.9
total_score (n_components = 8): 80.9
total_score (n_components = 9): 80.9
total_score (n_components = 10): 80.9

n_component의 값이 올라갈수록 total_score (여기선 accuracy)가 점점 증가하지만, n_component = 7의 지점부터 total_score가 횡보하는 것을 확인할 수 있다.

이는 PCA를 사용하여 10차원의 원본 데이터를 7차원으로 선형변환 했을 때 가장 효율적이라는 것을 의미한다.

0개의 댓글