본문 바로가기
머신러닝/PCA(Principal Component Analysis)

PCA - iris 데이터

by 미생22 2024. 6. 1.
728x90

PCA가 무엇인지 알았으니, 이번에는 iris 데이터를 가지고 실습해보도록 하겠습니다.

 

iris 데이터를 전처리할 pandas와 sklearn에서 iris 데이터를 가져오겠습니다.

import pandas as pd
from sklearn.datasets import load_iris

 

iris = load_iris()
iris_pd = pd.DataFrame(iris.data, columns=iris.feature_names)
iris_pd['species'] = iris.target

iris_pd.head()

 

데이터를 다시 기억해서 알아보기위해 seaborn으로 확인해보겠습니다.

 

import seaborn as sns

sns.pairplot(iris_pd, hue='species', height=3,
             x_vars=['sepal length (cm)', 'petal width (cm)'],
             y_vars=['petal length (cm)', 'petal width (cm)']
             );

이전에는 못보던 옵션이 추가되었죠? x_vars, y_vars인데요, 이게 없으면 어땠었는지 기억나나요

원래 우리가 보던 pairplot은 species에 의해 색상이 구분된 이와같은 그래프였죠. ㅎㅎㅎ x_vars, y_vars로 보고싶은 feature만 구분한겁니다.

 

sns.pairplot(iris_pd, hue='species');

 

일단 scaler를 적용해보겠습니다.

 

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
iris_ss = ss.fit_transform(iris.data)
iris_ss[:3] #3개 데이터만 보겠습니다.

array([[-0.90068117,  1.01900435, -1.34022653, -1.3154443 ],
       [-1.14301691, -0.13197948, -1.34022653, -1.3154443 ],
       [-1.38535265,  0.32841405, -1.39706395, -1.3154443 ]])

 

다시 복습차원에서 Standard Scaler를 살펴보면,

`StandardScaler`는 사이킷런(Scikit-learn) 라이브러리에서 제공하는 데이터 전처리 도구로, 데이터의 각 특성(변수)을 평균이 0이고, 분산이 1이 되도록 표준화(정규화)하는 방법입니다. `StandardScaler`는 데이터 전처리 과정에서 각 특성을 평균 0, 분산 1로 변환하는 방법입니다. 이는 머신러닝 모델이 데이터의 특성 스케일에 민감하지 않게 하고, 최적화 알고리즘이 더 안정적이고 빠르게 수렴하도록 도와줍니다.

 

다른 Scaler도 기억나시나요?

 

StandardScaler : 각 특성의 값을 평균이 0, 분산이 1이 되도록 변환합니다. 데이터의 중심을 맞추고 분산을 동일하게 조정하여, 모델이 각 특성을 균등하게 고려할 수 있게 합니다.
MinMaxScaler : 각 특성의 값을 지정된 최소값과 최대값(기본값: 0과 1) 사이로 변환합니다. 모든 데이터가 같은 범위 내에 위치하게 되어 특성의 크기 차이가 줄어듭니다. 이상치에 민감할 수 있습니다. 이상치가 있는 경우 스케일링 결과가 왜곡될 수 있습니다.
RobustScaler : 중앙값(median)과 IQR(Interquartile Range, 1사분위수와 3사분위수의 차이)을 사용하여 데이터를 스케일링합니다. 이상치(outlier)에 덜 민감합니다. 중앙값과 IQR을 사용하므로 데이터의 분포가 비대칭인 경우에도 효과적입니다.

 

다시 기억해주는 것이 좋습니다.

강의에서는 pca를 받아서 fit 시키고 transform 시키는 과정을 get_pca_data()라는 함수를 만들어 적용합니다.

 

from sklearn.decomposition import PCA

def get_pca_data(ss_data, n_components=2):
	pca = PCA(n_components=n_components)
    pca.fit(ss_data) #scaling이 적용된 데이터라는 뜻입니다.
    
    return pca.transform(ss_data), pca #pca도 필요하므로 같이 출력하겠습니다.

 

위에 scaling 시킨 iris_ss를 넣고, 주성분을 2개로 해서 get_pca_data()함수를 통해 fit, transform 시키겠습니다.

 

iris_pca, pca = get_pca_data(iris_ss, 2)
iris_pca.shape

(150, 2)

 

pca.mean_

array([-1.69031455e-15, -1.84297022e-15, -1.69864123e-15, -1.40924309e-15])

 

feature가 4개다 보니까 중앙값도 4개로 표시되네요.

 

pca.components_

array([[ 0.52106591, -0.26934744,  0.5804131 ,  0.56485654],
       [ 0.37741762,  0.92329566,  0.02449161,  0.06694199]])

 

행이 2개니까, 벡터가 총 2개죠.

 

pca.explained_variance_

array([2.93808505, 0.9201649 ])

 

설명력도 확인해보겠습니다. 그치만 역시 ratio로 보는게 보기 쉽네요.

 

pca.explained_variance_ratio_

array([0.72962445, 0.22850762])

 

두개로 95%정도는 설명이 가능한 것 같습니다.

이제 이렇게 pca처리한 iris를 df화 시키는 함수를 만들어보겠습니다.

 

def get_pd_from_pca(pca_data, cols=['PC1', 'PC2']):
	return pd.DataFrame(pca_data, columns=cols)

컬럼이 2개일때에만 쓸 수 있는 함수이긴 합니다 ㅎㅎ

 

iris_pd_pca = get_pd_from_pca(iris_pca)
iris_pd_pca['species'] = iris.target
iris_pd_pca.head()

 

iris.data에서 scaling 시킨 데이터로 pca를 만들었기 때문에 target은 없는 상태였으므로 target데이터를 species 컬럼에 넣어줍니다.

 

이걸가지고 pairplot을 다시 그려보겠습니다.

 

sns.pairplot(iris_pd_pca, hue='species', height=5, x_vars=['PC1'], y_vars=['PC2'])

강의에서는 기존 feature축도 같이 넣어서 그려줬네요. 저는 코드로 못짜겠습니다. ㅎㅎ

 

주성분 분석위 위력을 보겠습니다.
4개의 feature를 쓰는게 아니라 2개의 feature를 가지고 73% 23%의 설명력을 가졌다고 하면 꽤 괜찮은 것입니다.
이걸로 machine learning을 돌리면 어떤 결과가 나올까요?

 

먼저, pca를 쓰기 전 machine learning을 돌려보겠습니다.

RandomForestClassifier를 쓸 거고 cross_validation_score를 통해 5개의 cv로 나누어 진행하고, 여기서 나온 accuracy를 mean값으로 가져와보는 함수를 만들어봅니다.

from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score

def rf_scores(X, y, cv=5):
    rf = RandomForestClassifier(random_state=13, n_estimators=100)
    scores_rf = cross_val_score(rf, X, y, scoring='accuracy', cv=cv)

    print('Score : ', np.mean(scores_rf))

 

rf_scores(iris_ss, iris.target) #X는 iris_ss, y는 iris.target이죠.

Score :  0.96

 

X는 iris_ss, y는 iris.target이죠.

이번에는 pca를 가지고 똑같이 적용해보겠습니다.

 

pca_X = iris_pd_pca[['PC1', 'PC2']]
rf_scores(pca_X, iris.target)

Score :  0.9066666666666666

 

pca후 전체가 95%의 설명률을 가지고 있고 데이터를 100%반영한게 아니라서 score가 떨어지긴 했습니다. 그러나 특성을 줄여서도 머신러닝을 돌릴 수 있다는걸 알게되었습니다.

728x90

'머신러닝 > PCA(Principal Component Analysis)' 카테고리의 다른 글

MNIST using PCA and kNN  (1) 2024.06.04
HAR using PCA  (0) 2024.06.04
PCA - eigenface  (0) 2024.06.01
PCA - wine 데이터  (0) 2024.06.01
PCA란?  (0) 2024.05.31