06-03. LDA(Linear Discriminant Analysis)

Park Jong Hun·2021년 3월 22일
1

위키북스의 파이썬 머신러닝 완벽 가이드 책을 토대로 공부한 내용입니다.


1. LDA 개요


LDA(Linear Discriminant Analysis)는 선형 판별법으로 불리며, PCA와 매우 유사하게 입력 dataset를 저차원 공간에 투영하여 차원을 축소하는 기법이지만, 중요한 차이는 LDA는 지도학습의 분류(Classification)에서 사용하기 쉽도록 개별 클래스를 분별할 수 있는 기준을 최대한 유지하면서 차원을 축소한다. 즉, PCA는 입력 데이터의 변동성의 가장 큰 축을 찾았지만, LDA는 입력 데이터의 결정 값 클래스를 최대한 분리할 수 있는 축을 찾는다.

LDA는 특정 공간상에서 틀래스 분리를 최대화하는 축을 찾기 위해 클래스 간 분산(between-class scatter)과 클래스 내부 분산(width-class scatter)의 비율을 최대화하는 방식으로 차원을 축소한다. 즉, 클래스간 분산은 최대한 크게 가져가고, 클래스 내부의 분산은 최대한 작게 가져가는 방식이다. 일반적으로 LDA를 구하는 스텝은 PCA와 유사하지만 가장 큰 차이는 공분산 행렬이 아닌 클래스간 분산과 클래스 내부 분산 행렬을 생성한 뒤, 이 행렬에 기반해 교유벡터를 구하고 입력 데이터를 투영한다는 점이다.

  • LDA를 구하는 방법
    1. 클래스 내부와 클래스 간 분산 행렬을 구한다. 이 두 개의 행렬은 입력 데이터의 결정 값 클래스별로 개별 feature의 평균 벡터(mean vector)를 기반으로 구한다.
    2. 클래스 내부 분산 행렬을 SWS_W, 클래스 간 분산 행렬을 SBS_B라고 하면 다음 식으로 두 행렬을 고유 벡터로 분해할 수 있다.
    SWTSB=[e1,...,en][λ100λn][e1TenT]S_W^TS_B=[e_1,...,e_n] \left[\begin{matrix} \lambda_1 & \dots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \dots & \lambda_n \\ \end{matrix}\right] \left[\begin{matrix} e_1^T \\ \vdots\\ e_n^T\\ \end{matrix}\right]
    3. 고유값이 가장 큰 순으로 K개(LDA 변환 차수만큼) 추출한다.
    1. 고유값이 가장 큰 순으로 추출된 고유벡터를 이용해 새롭게 입력 데이터를 변환한다.

2. iris dataset에 LDA 적용하기


사이킷런의 LDA를 이용해 변환하고, 그 결과를 품종별로 시각화해 보겠다.

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
from sklearn.preprocessing import StandardScaler
from sklearn.datasets import load_iris

iris = load_iris()
iris_scaled = StandardScaler().fit_transform(iris.data)

lda = LinearDiscriminantAnalysis(n_components=2)
lda.fit(iris_scaled, iris.target)
iris_lda = lda.transform(iris_scaled)

import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

lda_columns=['lda_component_1','lda_component_2']
irisDF_lda = pd.DataFrame(iris_lda,columns=lda_columns)
irisDF_lda['target']=iris.target

#setosa는 세모, versicolor는 네모, virginica는 동그라미로 표현
markers=['^', 's', 'o']

#setosa의 target 값은 0, versicolor는 1, virginica는 2. 각 target 별로 다른 shape으로 scatter plot
for i, marker in enumerate(markers):
    x_axis_data = irisDF_lda[irisDF_lda['target']==i]['lda_component_1']
    y_axis_data = irisDF_lda[irisDF_lda['target']==i]['lda_component_2']

    plt.scatter(x_axis_data, y_axis_data, marker=marker,label=iris.target_names[i])

plt.legend(loc='upper right')
plt.xlabel('lda_component_1')
plt.ylabel('lda_component_2')
plt.show()

[output]

profile
NLP, AI, LLM, MLops

0개의 댓글