PCA (Principal Component Analysis)
data가 많이 있는 축 → 주성분 = principal component(데이터가 주로 분포한 축, 성분)
데이터의 특성을 가장 잘 살릴 수 있는, 가장 많이 분포해있는 축으로 축소시켜야 함.
- Covariance(공분산)이란?
보통 분산은 한 개의 특정한 변수의 데이터 변동을 의미하나, 공분산은 두 변수 간의 변동을 의미함.
Cov(X,Y) > 0 → X가 증가할 때, Y도 증가함을 의미.
공분산 행렬은 여려 변수와 관련된 공분산을 포함하는 정방형 행렬. (분산의 multidimension ver.)


- PCA
= covariance를 SVD 해서 그거의 장축을 고르면 됨.


*** PCA는 covariance 구하고, 그 행렬에 SVD 적용해라.
그리고 컬럼벡터(U) 원하는 차원까지 순서대로 (데이터 많은.. 장축) 뽑아와라. 그리고 X에 곱해주면 차원축소 ***
X가 N x D이면, input이 D차원인거니까 covariance는 D x D.
SVD 분해한 U 행렬에서 원하는 차원(D’)까지 앞에 있는 column vector들 뽑은걸 U’라 하면, 이건 D x D’ 소속.
즉, 축소시킨 행렬 Z는 XU’니까 (N x D)(D x D’)라서 N x D’ 로 축소됨.
- PCA와 SVD 혼합 이해
사실 아까 위에서 AAT를 UΣΣTUT로 바꾼건 PCA 재질.
AAT가 공분산이라면 PCA..
고유벡터(eigen vector) - 행렬 A를 곱하더라도 방향이 변하지 않고 그 크기만 변하는 벡터.
고유벡터는 여러 개가 존재하며, 정방행렬은 최대 그 차원 수 만큼의 고유 벡터를 가질 수 있음.
고유벡터는 행렬이 작용하는 힘의 방향과 관계가 있어서 행렬을 분해하는 데 사용.
공분산 행렬은 정방행렬(square matrix)이며 대칭행렬(symmetric matrix)
정방행렬 중에서도 대각 원소를 중심으로 원소 값이 대칭 되는 행렬, AT= A인 행렬이 대칭행렬.
공분산 행렬은 개별 분산값을 대각 운소로 하는 대칭행렬.
대칭행렬은 항상 고유벡터를 직교행렬(orthogonal matrix)로, 고유값을 정방행렬로 대각화할 수 있다는것
+아까 위에서, AAT는 symmetric하고, 그걸 decomposition하면 무조건 orthonormal 한 basis(합치면 orthogonal matrix)로 튀어나온댔음.
→ 이런 AAT를 UΣΣTUT(U는 고유벡터였고, Σ는 고유값에 루트씌운거였으니..)
C = PΣPT
P는 n x n의 직교행렬, Σ는 n x n의 정방행렬, Pt는 행렬 P의 전치행렬
공분산 C는 고유벡터 직교행렬 * 고유값 정방행렬 * 고유벡터 직교행렬의 전치 행렬로 분해됨.
- e1은 가장 분산이 큰 방향을 가진 고유벡터이며, e2는 e1에 수직이면서 다음으로 가장 분산이 큰 방향을 가진 고유벡터임.
- 입력 데이터의 공분산 행렬이 고유벡터와 고유값으로 분해될 수 있으며, 이렇게 분해된 고유벡터를 이용해 입력 데이터를 선형 변환하는 방식이 PCA
- PCA 구하는 step
1. 입력 데이터 세트의 공분산 행렬 생성
2. 공분산 행렬의 고유벡터와 고유값 계산(SVD 분해)
3. 고유값이 가장 큰 순으로 K개 (PCA 변환 차수만큼) 만큼 고유벡터 추출
4. 고유값이 가장 큰 순으로 추출된 고유벡터를 이용해 새롭게 입력 데이터 변환 (x 곱해줌(투영))
- 코드 구현
PCA는 여러 속성의 값을 연산해야하므로 속성의 스케일에 영향을 받음.
→ 여러 속성을 PCA로 압축하기 전에 각 속성값을 동일한 스케일로 변환해야함.
from sklearn.preprocessing import StandardScaler
# Target 값을 제외한 모든 속성 값을 StandardScaler를 이용하여 표준 정규 분포를 가지는 값들로 변환
iris_scaled = StandardScaler().fit_transform(irisDF.iloc[:, :-1])
from sklearn.decomposition import PCA
pca = PCA(n_components=2)
#fit( )과 transform( ) 을 호출하여 PCA 변환 데이터 반환
pca.fit(iris_scaled)
iris_pca = pca.transform(iris_scaled) #iris_pca는 변환된 pca 데이터 세트를 150 x 2 넘파이 행렬로 가지고 있음.
print(iris_pca.shape) # (150,2)
# PCA 변환된 데이터의 컬럼명을 각각 pca_component_1, pca_component_2로 명명
pca_columns=['pca_component_1','pca_component_2']
irisDF_pca = pd.DataFrame(iris_pca, columns=pca_columns)
irisDF_pca['target']=iris.target
irisDF_pca.head(3)
#setosa를 세모, versicolor를 네모, virginica를 동그라미로 표시
markers=['^', 's', 'o']
#pca_component_1 을 x축, pc_component_2를 y축으로 scatter plot 수행.
for i, marker in enumerate(markers):
x_axis_data = irisDF_pca[irisDF_pca['target']==i]['pca_component_1']
y_axis_data = irisDF_pca[irisDF_pca['target']==i]['pca_component_2']
plt.scatter(x_axis_data, y_axis_data, marker=marker,label=iris.target_names[i])
plt.legend()
plt.xlabel('pca_component_1')
plt.ylabel('pca_component_2')
plt.show()
pca_componet_1이 원본 데이터의 변동성을 잘 반영하고 있음.
PCA 객체의 explained_variance_ratio_ 속성은 전체 변동성에서 개별 PCA 컴포넌트별로 차지하는 변동성 비율 제공
print(pca.explained_variance_ratio_)
[0.72962445 0.22850762]
→ PCA를 2개 요소로만 변환해도 원본 데이터 변동성을 95% 설명가능
- 원본 데이터셋과 PCA로 변환된 데이터셋에 각각 분류 적용 후 결과 비교
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import cross_val_score
import numpy as np
rcf = RandomForestClassifier(random_state=156)
scores = cross_val_score(rcf, iris.data, iris.target,scoring='accuracy',cv=3)
print('원본 데이터 교차 검증 개별 정확도:',scores)
print('원본 데이터 평균 정확도:', np.mean(scores))
원본 데이터 교차 검증 개별 정확도: [0.98 0.94 0.96]
원본 데이터 평균 정확도: 0.96
pca_X = irisDF_pca[['pca_component_1', 'pca_component_2']]
scores_pca = cross_val_score(rcf, pca_X, iris.target, scoring='accuracy', cv=3 )
print('PCA 변환 데이터 교차 검증 개별 정확도:',scores_pca)
print('PCA 변환 데이터 평균 정확도:', np.mean(scores_pca))
PCA 변환 데이터 교차 검증 개별 정확도: [0.88 0.88 0.88]
PCA 변환 데이터 평균 정확도: 0.88
+corr()을 이용해 각 속성 간의 상관도를 구한 뒤 이를 seaborn의 heatmap으로 시각화 해보면 상관도를 볼 수 있는데, 높은 상관도를 가진 속성들은 소수의 PCA만으로도 자연스럽게 이 속성들의 변동성을 수용할 수 있음.
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
corr = X_features.corr()
plt.figure(figsize=(14,14))
sns.heatmap(corr, annot=True, fmt='.1g')
'Machine Learning > 차원 축소' 카테고리의 다른 글
[파이썬 머신러닝 가이드] 차원축소 - LDA, NMF (1) | 2023.12.25 |
---|---|
[파이썬 머신러닝 가이드] 차원 축소 - SVD (1) | 2023.12.25 |