이지훈님의 블로그
주성분분석 (Principal Component Analysis) 본문
주성분분석 (PCA) <위키피디아>
고차원의 데이터를 저차원의 데이터로 환원시키는 기법이다. 새로운 변수를 원 변수의 선형결합으로 만들어 변수를 축약한다.
장점 : 고차원의 데이터를 큰 정보손실없이 변환해 준다.시각화 편리
-> 변수를 줄임
-> 학습집합의 크기를 줄여줌
-> 학습 시 빠름
한계 : 특징벡터의 Label을 고려하지 않음.
결과값이 특징구분을 좋게한다는 보장은 없음.
PCA분석을 이해하기 위해서는 공분산, 고유벡터와 고유값에 대한 개념이 필요하다.
공분산 <위키피디아>
2개의 확률변수의 상관정도를 나타내는 값이다.
cov(x, y) > 0 이면 x가 증가할 때 y도 증가
cov(x, y) < 0 이면 x가 증가할 때 y는 감소
cov(x, y) = 0 이면 상관관계가 없음
다른 차원과의 공분산을 모두 구하고 행렬에 넣어준다. 즉, 아래와 같은 매트릭스를 만들어 준다.
고유값과 고유벡터 <위키피디아>
A는 N*N(정방행렬)일 때,
를 만족하는 0이 아닌 벡터 x가 존재하면 λ를 고유값, 벡터 x를 고유벡터라고 한다.
아래 식에서 행렬 (3, 2)는 고유벡터, 4는 고유값이 된다.
PCA분석 (IRIS)
|
sepal_len |
sepal_wid |
petal_len |
petal_wid |
145 |
6.7 |
3.0 |
5.2 |
2.3 |
146 |
6.3 |
2.5 |
5.0 |
1.9 |
147 |
6.5 |
3.0 |
5.2 |
2.0 |
148 |
6.2 |
3.4 |
5.4 |
2.3 |
149 | 5.9 | 3.0 | 5.1 | 1.8 |
0. 데이터를 불러온다.
import numpy as np import numpy.linalg as linalg from sklearn.preprocessing import StandardScaler from numpy import genfromtxt iris_data = genfromtxt('iris.csv', delimiter=',') iris_data = np.array(iris_data[:,:4], dtype=np.float64)
1 .데이터를 표준화한다.
PCA는 축을 따라 분산을 최대화하는 피쳐 부분 공간을 산출하기 때문에 특히 다른 척도로 측정 된 경우 데이터를 표준화하는 것이 좋다. 아이리스 데이터 세트의 모든 기능은 센티미터 단위로 측정되었지만 많은 기계 학습 알고리즘의 최적 성능을 위해서는 단위 크기 (평균 = 0 및 분산 = 1)로 데이터를 변환한다.
iris_std = StandardScaler().fit_transform(iris_data)
2. 공분산을 구하고, 공분산의 고유벡터, 고유값을 구한다.
iris_cov = (np.cov(iris_std.T)) eig_vals, eig_vecs = np.linalg.eig(iris_cov)
3. 고유벡터와 표준화한 데이터와 행렬연산을 하여 PC1, PC2.. 등의 새로운 값을 만들어준다.
마지막 print는 확인작업이다.
PC1으로 생성된 값의 공분산은 선택한 고유벡터의 고유값과 같아야 한다.
eig_vals_sum = np.sum(eig_vals) for eig_val in eig_vals: print ("contain " + str(eig_val/eig_vals_sum)) PC1 = iris_std.dot(np.reshape(eig_vecs.T[0], (4, 1))) print (eig_vals[0]) print (np.cov(PC1.T))
전체코드
import numpy as np import numpy.linalg as linalg from sklearn.preprocessing import StandardScaler from numpy import genfromtxt iris_data = genfromtxt('iris.csv', delimiter=',') iris_data = np.array(iris_data[:,:4], dtype=np.float64) iris_std = StandardScaler().fit_transform(iris_data) iris_cov = (np.cov(iris_std.T)) eig_vals, eig_vecs = np.linalg.eig(iris_cov) eig_vals_sum = np.sum(eig_vals) for eig_val in eig_vals: print ("contain " + str(eig_val/eig_vals_sum)) PC1 = iris_std.dot(np.reshape(eig_vecs.T[0], (4, 1))) print (eig_vals[0]) print (np.cov(PC1.T))
참고자료
<영문 자료: 링크 1>
<한글 자료: 링크 2>