준비하는 대학생

[Machine Learning] 주성분 분석(PCA) 본문

Programming/Machine learning

[Machine Learning] 주성분 분석(PCA)

Bangii 2023. 3. 28. 14:36

PCA(주성분 분석) 개요

PCA는 다변량 데이터의 차원을 축소하면서 정보 손실을 최소화하는 방법으로, 데이터의 분산을 최대한 보존하는 새로운 축(주성분)을 찾아 원래 데이터를 이 주성분에 투영함으로써 차원을 축소합니다. 이를 통해 데이터의 중요한 정보를 유지하면서 차원을 줄이고, 시각화 및 기계 학습 알고리즘의 성능을 향상할 수 있습니다.

PCA의 과정은 다음과 같습니다.

  1. 데이터 전처리: 데이터를 표준화(평균 0, 표준편차 1)하거나 정규화(최소값 0, 최댓값 1)하여 스케일을 조정합니다.
  2. 공분산 행렬 계산: 데이터의 공분산 행렬을 계산합니다. 공분산 행렬은 변수 간의 선형 관계를 나타내며, 이를 통해 데이터의 분포와 구조를 파악할 수 있습니다.
  3. 고윳값 및 고유벡터 계산: 공분산 행렬의 고윳값과 고유벡터를 계산합니다. 고윳값은 데이터의 분산을 나타내고, 고유벡터는 주성분의 방향을 나타냅니다.
  4. 주성분 선택: 고유값이 큰 순서대로 주성분을 선택합니다. 주성분 개수를 선택하는 방법으로, 누적 설명 분산 비율(cumulative explained variance ratio)을 활용할 수 있습니다. 누적 설명 분산 비율이 일정 수준(예: 95% 또는 99%) 이상인 주성분까지 선택하여 차원 축소를 수행합니다.
  5. 주성분으로 원본 데이터 변환: 선택된 주성분(고유벡터)을 이용하여 원본 데이터를 변환합니다. 이 과정에서 원본 데이터의 차원이 축소되며, 새로운 주성분 축에 투영된 데이터를 얻게 됩니다.

이제 PCA를 사용하여 Iris 데이터셋을 차원 축소하고 시각화하는 방법을 알아보겠습니다.

필요한 라이브러리 불러오기

먼저 필요한 라이브러리를 불러옵니다.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.datasets import load_iris
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score

데이터 준비 및 전처리

 

붓꽃(iris) 데이터셋을 사용할 것입니다. 이 데이터셋은 3가지 종류의 붓꽃에 대한 꽃받침 길이, 꽃받침 너비, 꽃잎 길이, 꽃잎 너비의 측정값을 포함하고 있습니다. Iris 데이터셋을 불러오고 표준화를 진행합니다

iris = load_iris()
X = iris.data
y = iris.target

scaler = StandardScaler()
X_std = scaler.fit_transform(X)

PCA를 사용하여 데이터 차원 축소 및 시각화

 

PCA를 수행하기 위해 PCA 클래스를 사용할 것입니다. 여기서는 차원을 2로 축소해 볼 것입니다.

pca = PCA(n_components=2)
X_pca = pca.fit_transform(X)

결과 시각화하기

PCA 결과를 시각화해서 차원 축소의 효과를 확인해봅시다.

def plot_pca_result(X_pca, y, target_names):
    plt.figure(figsize=(8, 6))
    colors = ['r', 'g', 'b']
    for color, i, target_name in zip(colors, [0, 1, 2], target_names):
        plt.scatter(X_pca[y == i, 0], X_pca[y == i, 1], color=color, alpha=0.8, lw=2, label=target_name)
    plt.legend(loc='best', shadow=False, scatterpoints=1)
    plt.xlabel('Principal Component 1')
    plt.ylabel('Principal Component 2')
    plt.title('PCA of Iris Dataset')
    plt.show()

plot_pca_result(X_pca, y, iris.target_names)

위 코드를 실행하면, 아래그림과 같이 Iris 데이터셋의 PCA 결과를 2차원으로 시각화한 그래프를 볼 수 있습니다. 각 점은 하나의 샘플을 나타내며, 색상은 해당 샘플의 클래스를 나타냅니다. 이렇게 PCA를 사용하여 고차원 데이터를 저차원으로 시각화하면 데이터의 패턴을 쉽게 파악할 수 있습니다.

분류 모델 학습 및 평가

이제 PCA를 사용한 경우와 사용하지 않은 경우의 분류 성능을 비교해 보겠습니다. 분류 모델로는 k-NN(k-Nearest Neighbors) 알고리즘을 사용하겠습니다.

데이터를 학습용과 테스트용으로 분리합니다.

X_train, X_test, y_train, y_test = train_test_split(X_std, y, test_size=0.3, random_state=42)
X_train_pca, X_test_pca, y_train_pca, y_test_pca = train_test_split(X_pca, y, test_size=0.3, random_state = 42)

k-NN 모델을 학습시킵니다.

knn = KNeighborsClassifier(n_neighbors=3)

# PCA를 사용하지 않은 경우 학습 및 평가
knn.fit(X_train, y_train)
y_pred = knn.predict(X_test)
accuracy_without_pca = accuracy_score(y_test, y_pred)

# PCA를 사용한 경우 학습 및 평가
knn.fit(X_train_pca, y_train_pca)
y_pred_pca = knn.predict(X_test_pca)
accuracy_with_pca = accuracy_score(y_test_pca, y_pred_pca)

 

성능을 비교합니다.

print("Accuracy without PCA: {:.2f}".format(accuracy_without_pca))
print("Accuracy with PCA: {:.2f}".format(accuracy_with_pca))
Accuracy without PCA: 1.00
Accuracy with PCA: 0.96

결과를 확인하면, PCA를 사용한 경우와 사용하지 않은 경우의 분류 성능 차이를 확인할 수 있습니다. 이 예제에서는 PCA를 사용하여 차원을 축소했음에도 불구하고, 분류 성능이 크게 저하되지 않았습니다. 이를 통해 PCA가 원본 데이터의 중요한 정보를 최대한 보존하면서 차원을 축소했음을 알 수 있습니다.

결론

PCA는 데이터의 차원 축소와 시각화에 유용한 방법입니다. 이를 통해 고차원 데이터의 패턴을 쉽게 파악할 수 있고, 기계 학습 알고리즘의 성능을 향상할 수 있습니다. 

 

Comments