[머신러닝] 6-3. 주성분 분석
오옹 주성분 분석! 저번에 이미 정리해둔 것이 있다.
이것도 같이 참고해보도록!
차원과 차원 축소
데이터가 가진 속성을 특성이라고 한다. 머신러닝에서는 특성을 차원이라고도 부른다. 이 차원을 줄이면 저장 공간을 절약할 수 있게 된다
다차원 배열에서 차원은 축의 개수이지만 1차원 배열에서는 원소의 개수를 말한다.
차원축소는 데이터를 잘 나타내는 일부 특성을 선택해서 데이터 크기를 줄이고 지도 학습 성능을 향상 시킨다.
손실을 최대한 줄이면서 다시 복원하는 할 수 있다
대표적인 차원 축소 알고리즘 주성분 분석(PCA)를 알아보자
주성분 분석 소개
주성분 분석은 데이터에 있는 분산이 큰 방향을 찾는 것이다. 분산은 데이터가 퍼져있는 정도이다. 분산이 큰 방향이 데이터를 잘 표현하는 것이겠지?
이 벡터를 주성분이라고 한다. 주성분 벡터는 원본 데이터에 있는 어떤 방향이다.
주성분을 이용해서 차원을 줄일 수 있다. s를 p로 만드는 것이다.
주성분은 원본 차원과 같고 주성분으로 바꾼 데이터는 차원이 줄어들게 된다.
- 주성분 찾기
- 벡터에 수직이고 분산이 가장 큰 다음 방향 찾기(두번째 주성분)
주성분은 원본의 특성 개수만큼 찾을 수 있다. 여기서는 2차원이니 2개를 찾을 수 있다.
PCA 클래스
1
2
3
4
!wget https://bit.ly/fruits_300 -0 fruits_300.npy
import numpy as np
fruits=np.load('fruits_300.npy')
fruits_2d=fruits.reshpae(-1, 100*100)
n_components로 주성분 개수 정하기 pca도 비지도 학습인 fit에 타깃값을 제공하지 않는다
1
2
3
from sklearn.decomposition import PCA
pca=PCA(n_compoenents=50)
pca.fit(fruits_2d)
주성분은 components_에 저장되어 있다.
1
2
3
4
#배열 크기 확인
print(pca.components_.shape)
#(50, 10000)
n_components=50이기 때문에 pca.components_배열의 첫 번째 ㅊ원이 50이다. 즉 50개의 주성분을 찾은 것이다. 두번째 차원은 항상 원본 데이터의 특성 개수와 같은 100000이다.
1
draw_fruits(pca.components_.reshape(-1, 100,100))
원본 데이터에서 가장 분산이 큰 방향을 순서대로 나타낸 것이다.
주성분에 투영하여 특성의 개수를 10000개에서 50개로 줄일 수 있다. 원본 데이터를 각 주성분으로 분해하는 것이다.
transform으로 원본 데이터의 차원을 50으로 줄인다.
1
2
3
print(fruits_2d.shape)
#(300, 10000)
1000개의 특성(픽셀)을 가진 300개의 이미지이다.
1
2
3
fruit_pca=pca.transform(fruits_2d)
print(fruits_pca.shape)
#(300, 50)
PCA 모델을 사용해 배열을 변환한다.
원본 데이터 재구성
복원해보자!
1
2
3
fruits_inverse=pca.inverse_transform(fruits_pca)
print(fruits_inverse.shape)
#(300, 10000)
100개씩 출력해보자. 순서대로 사과, 파인애플, 바나나이다.
1
2
3
4
fruits_reconstruct=fruits_inverse.reshpae(-1, 100, 100)
for start in [0, 100, 200]:
draw_fruits(fruits_reconstruct[start:start+100])
print('\n')
잘 복원했군
설명된 분산
주성분이 원본 데이터의 분산을 얼마나 잘 나타내는지 기록한 값을 설명된 분산이라고 한다.
explained_variance_ratio_에 각 주성분이 설명된 분산 비율이 기록되어 있다.
분산 비율을 모두 더하면 50개의 주성분으로 표현하고 있는 총 분산 비율을 얻을 수 있다.
1
2
print(np.sum(pca.explained_variance_raion_))
#0.9215
92%가 넘는 분산을 유지하고 있다. 원본 이미지가 잘 복원된 이유이다.
1
2
#설명된 분산의 비율 그려보기
plt.plot(pca.explained_variance_ratio_)
첫 10개 주성분이 대부분의 분산을 표현하고 있다. 그다음부터는 각 주성분이 설명하고 있는 분산은 작다.
다른 알고리즘과 함께 사용하기
PCA로 차원 축소된 데이터를 사용하여 지도 학습 모델을 훈련해보겠다. 3개 과일 사진을 분류해야 하니 로지스틱 회귀 모델을 사용하겠다.
1
2
3
from sklearn.linear_model import LogisticRegression
lr=LogisticRegression()
타깃값으로 사과는 0, 파인애플 1, 바나나 2로 하겠다. 파이썬 리스트와 정수를 곱해 타깃 데이터를 만든다.
1
target=np.array([0]*100+[1]*100+[2]*100)
cross_validate로 교차검증
1
2
3
4
5
6
7
from skleanr.model_selection import cross_validate
scores=cross_validate(lr, fruits_2d, target)
print(np.mean(scores['test_score']))
print(np.mean(scores['fit_time']))
#0.9966
#0.9422
점수가 0.997로 매우 높다. 과대적합된 모델을 만들기 쉽다.
fit_time에 훈련 시간 0.94초이다. fruit_pca와 비교하면 50개 특성만 사용했는데도 정확도가 100이고 훈련시간은 0.03초로 엄청 단축되었다.
1
2
3
4
5
6
scores=cross_validate(lr, fruits_pca, target)
print(np.mean(scores['test_score']))
print(np.mean(scores['fit_time']))
#1.0
#0.03256
n_components에 주성분 개수 대신 설명된 분산 비율을 입력할 수 있다. PCA 클래스는 지정된 비율에 도달할 때까지 자동으로 주성분을 찾는다.
1
2
3
#설명된 분산 50%에 달하는 주성분을 찾도록
pca=PCA(n_components=0.5)
pca.fit(fruits_2d)
1
2
3
# 주성분 분석 몇 개 찾았는지 확인하기
print(pca.n_components_)
#2
2개로 원본 데이터 분산 50%를 설명할 수 있다.
1
2
3
4
#원본 데이터를 변환
fruits_pca=pca.transform(fruits_2d)
print(fruits_pca.shape)
#(300,2)
1
2
3
4
5
6
7
#2개 교차검증 결과 확인
scores=cross_validate(lr, fruits_pca, target)
print(np.mean(scores['test_score']))
print(np.mean(scores['fit_time']))
#0.9933
#0.0412
2개로 정확도 99%!
차원 축소된 데이터를 사용해 k-평균 알고리즘으로 클로스터 찾아보자
1
2
3
4
5
6
from sklean.cluster import KMeans
km=KMeans(n_clusters=2, random_state=42)
km.fit(fruits_pca)
print(np.unique(km.labels_, return_counts=True))
#(array([0,1,2], dtype=int32), array([91, 99, 110]))
91개, 99개, 110개 포함중이다
1
2
3
4
#이미지 출력하기
for label in range(0,3):
draw_fruits(fruits[km.labels_==label])
print('\n')
차원 축소의 장점! 3개 이하 차원으로 줄이면 화면 출력이 쉽다.
1
2
3
4
5
6
#클러스터 별로 산점도 그리기
for label in range(0,3):
data=fruits_pca[km.labels_==label]
plt.scatter(data[:, 0], data[:, 1])
plt.legend(['apple','banana','pineapple'])
plt.show()
아주 훌륭하군! 사과랑 파인애플이 가까워서 좀 헷갈렸다보다. 시각화로 많은 정보를 얻을 수 있다. 이를 통해 차원 축소가 참 좋다는 것을 알 수 있겠지? 끝!
마무리
키워드
차원 축소 주성분 분석 설명된 분산
핵심 패키지와 함수
핵심 패키지와 함수
scikit-learn
PCA
참고
혼자 공부하는 머신러닝+딜러닝






