본문으로 바로가기

Feature Extraction (PCA, LDA)

category Data/Data preprocessing 2021. 2. 21. 22:07

개요

1) 변수의 변환을 통해 새로운 변수 추출

2) 차원의 저주로 인한 과적합 줄이기

3) 규제가 없는 모델에서 주로 사용

3) 변수의 개수를 많이 줄일 수 있지만 추출된 변수의 해석이 어려움

 

PCA (주성분 분석)

1) 개요

    - 비지도 학습

    - 특성 사이의 상관관계를 기반으로 고차원 데이터에서 낮은 차원을 갖는 새로운 공간으로 투영

    - 데이터셋에서 분산이 최대인 직교 성분 축을 찾는다.

    - 데이터가 부실한 image classification에서 효과적이다.

    - sjpyo.tistory.com/6

 

주성분 분석 (PCA)

변수선택 및 추출 (selection & extraction) 1) 목적 - 모델링의 효율화 (계산 복잡도 감소) - 중요한 변수 선택 2) 변수선택 (selection) - 목적에 부합하는 소수의 변수만 선택 - 선택된 변수의 해석은 용이

sjpyo.tistory.com


LDA; Linear discriminant analysis (선형 판별 분석)

1) 개요

    - 지도 학습 (차원 축소를 하며 label 정보를 가능한 많이 유지한다.)

    - 클래스를 최적으로 구분할 수 있는 특성 부분 공간을 찾는다.

    - PCA 보다 classification에서 뛰어나다. (SVM 같은 분류 알고리즘에 적절)

2) 특성

    - x축으로 투영하는 선형 판별 벡터는 두 개의 정규 분포 클래스를 잘 구분해낸다.

    - 데이터가 정규분포라고 가정한다.

    - 클래스가 동일한 공분산 행렬을 가지고 샘플은 서로 통계적으로 독립적이라고 가정한다.

    - scatter matrix를 계산할 때, class label이 균등하다고 가정한다.

 

3) 원리

    - 투영 했을 때, 클래스 간 분산은 크게, 클래스 내 분산은 작게 만든다.

    - 클래스 간 분산이 크다 = 클래스 간의 평균이 멀다.

    - 클래스 간 분산 / 클래스 내 분산 -> 최대화

 

4) 수학적 이해

    - www.facweb.iitkgp.ac.in/~sudeshna/courses/ml08/lda.pdf

 

5) 한계

    - LDA의 선형 판별 벡터는 최대 c - 1개이다. (c : feature 개수) 따라서 분류 오류 추정치가 더 많은 feature가 필요하다고 한다면 다른 방식을 통해 추가적인 feature를 제공해야 한다.

    - 데이터의 분산이 non-Gaussian이라면 LDA는 정확하지 않다.

 

6) 과정

    (1) 데이터 표준화 (standardization)

from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
X_train_std = sc.fit_transform(X_train)
X_test_std = sc.transform(X_test)

    (2) 각 클래스에 대해 n 차원의 평균 벡터 계산 (지도 학습)

# 예제 데이터에서는 3개의 클래스를 가지고 있다. (1, 2, 3)
mean_vecs = []

for label in range(1, 4):
    mean_vecs.append(np.mean(X_train_std[y_train == label], axis = 0))
    print(f"MV {label} : {mean_vecs[label - 1]}")

    (3) 클래스 간의 scatter matrix (Sb), 클래스 내의 scatter matrix (Sw) 계산

d = 13 # feature 개수
S_W = np.zeros((d, d))
for label, mv in zip(range(1, 4), mean_vecs):
    class_scatter = np.cov(X_train_std[y_train == label].T, bias = True)
    S_W += class_scatter

    (4) Sw 역행렬 * Sb 행렬의 고유벡터와 고유값 계산

eigen_vals, eigen_vecs = np.linalg.eig(np.linalg.inv(S_W).dot(S_B))

    (5) 고유값을 내림차순으로 정렬하고 고유벡터의 순위를 매김

eigen_pairs = [(np.abs(eigen_vals[i]), eigen_vecs[:, i])
               for i in range(len(eigen_vals))]
eigen_pairs = sorted(eigen_pairs, key = lambda k: k[0], reverse = True)

    (6) 고유값이 가장 큰 k개의 고유벡터를 선택하여 n x k 차원의 변환 행렬 구성

w = np.hstack((eigen_pairs[0][1][:, np.newaxis].real,
               eigen_pairs[1][1][:, np.newaxis].real))

    (7) 정렬된 고유벡터로 기존 변수 변환 (선형 결합)

X_train_lda = X_train_std.dot(w)

 

코드 예시

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA

lda = LDA(n_components = 2)
X_train_lda = lda.fit_transform(X_train_std, y_train)

참고

머신러닝 교과서 (길벗)

'Data > Data preprocessing' 카테고리의 다른 글

Sampling unbalanced data  (1) 2021.02.23
Kernel method  (0) 2021.02.22
Data Scaling (normalization, standardization)  (0) 2021.02.19
Categorical variables encoding / mean, one-hot, label  (0) 2021.01.22
Feature selection (변수 선택)  (0) 2021.01.17