LDA (Linear Discriminant Analysis)

LDA (Linear Discriminant Analysis)

preface 이번 포스트에서는 분류classification 방법론 가운데 하나인 LDA (Linear Discriminant Analysis) 와 QDA (Quadratic Discriminant Analysis) 에 대하여 설명합니다. 분류classification란 A 그룹과 B 그룹으로 분류된 데이터가 있을 때, 새로 관측된 데이터가 어느 그룹에 속할지 추정하는 것을 말합니다.

알고리즘

다음 자료를 참고하였습니다:

LDA (Linear Discriminant Analysis)

LDA 란 Lable(Target 값)을 가지고 있는 데이터에 대하여 클래스들 사이의 차별적인 정보를 최대한 보존하면서 차원을 축소하는 기법을 말합니다.

Bayes’ theorem 을 이용하여 $Pr \left( X = x | Y = k \right)$ 를 계산하는 것이 목적입니다.

$\pi_k$ : prior probability

$f_{k} \left( X \right)$ : the density function of $X$ given that $Y = k$

$f_{k} \left( X \right) \equiv \Pr \left( X = x | Y = k \right)$

Bayes’ theorem 에 따라 사후확률(posterior probability)은 다음과 같이 정의됩니다.

(ISLR eq 4.10):

$p_{k} \left( x \right) = \Pr \left( Y = k | X = x \right)$ 를 찾는 것을 목적으로 합니다.

p = 1 인 경우

설명변수가 하나($p=1$)일 때, $x$ 의 분포가 normal distribution 라고 가정하면 확률밀도함수 $f_{k} \left( X \right)$ 는 다음과 같습니다.

(ISLR eq 4.11):

여기에 추가로 모든 클래스의 분산이 동일하다고 가정합시다. ($\sigma_1^2 = \ … \ = \sigma_k^2$)

이렇게 정의된 $f_{k} \left( X \right)$ 를 (ISLR eq 4.10)에 대입하면 다음과 같습니다.

(ISLR eq 4.12):

(ISLR eq 4.12) 에 로그를 취하고 정리하면, 결국 다음 식에 따라 분류하는 것과 같아진다는 것을 확인할 수 있습니다.

(ISLR eq 4.13):

$K=2$ 이고 $\pi_1=\pi_2$ 일 때, $2x \left( \mu_1 - \mu_2 \right) > \mu_1^2 - \mu_2^2$ 이면 1로 분류하고 그 외의 경우 2로 분류합니다. 따라서 Bayes decision boundary 는 다음과 같이 결정됩니다.

(ISLR eq 4.14):

하지만 실제로는 $\pi_k$ , $\mu_k$ , $\sigma^2$ 를 모르므로 다음과 같이 계산합니다.

(ISLR eq 4.15):

(ISLR eq 4.16):

(ISLR eq 4.17):

p > 1 인 경우

설명변수가 2개 이상($p>1$)인 경우입니다. 즉, $X = \left( X_1, X_2, … , X_p \right)$ 가 multivariate normal distribution 을 따르는 경우를 말합니다.

(ISLR eq 4.18):

(ISLR eq 4.19):

Bayes decision boundaries 는 다음과 같이 $\delta_k \left( x \right) = \delta_l \left( x \right)$ 을 만족하는 지점입니다.

(ISLR eq 4.20):

QDA (Quadratic Discriminant Analysis)

QDA 는 LDA 에서 사용했던 모든 클래스의 분산이 동일하다($\sigma_1^2 = \ … \ = \sigma_k^2$)는 가정이 지켜지지 않는 경우입니다. 즉, $k$ th class 에 속한 관측치의 분포가 $X \sim N \left( \mu_k, \Sigma_k \right)$ 와 같은 경우를 말합니다.

(ISLR eq 4.23):

LDA in Python by using scikit-learn

다음 자료를 참고하였습니다:

Iris 데이터를 사용합니다. train set 과 test set 으로 나누었습니다.

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split

names = ['sepal_length', 'sepal_width', 'petal_length', 'petal_width', 'class']
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None, names=names)

X = np.array(df.iloc[:, 0:4])
y = np.array(df['class'])

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.33, random_state=42)

scikit-learn package 를 이용하여 LDA 를 실시합니다.

from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

lda = LinearDiscriminantAnalysis()

X_transform = lda.fit(X_train, y_train).transform(X_train)
y_predict = lda.fit(X_train, y_train).predict(X_test)

from sklearn import metrics
metrics.accuracy_score(y_test, y_predict)

정확도는 0.9799 가 나옵니다.

아래와 같이 LDA 함수에서 n_components 옵션을 조절해줄 수 있습니다.

lda1 = LinearDiscriminantAnalysis(n_components=1)
X_transform1 = lda1.fit(X_train, y_train).transform(X_train)

setosa = X_transform1[y_train == "Iris-setosa"]
versicolor = X_transform1[y_train == "Iris-versicolor"]
virginica = X_transform1[y_train == "Iris-virginica"]

print("setosa range is %f ~ %f" % (np.min(setosa), np.max(setosa)))
print("versicolor range is %f ~ %f" % (np.min(versicolor), np.max(versicolor)))
print("virginica range is %f ~ %f" % (np.min(virginica), np.max(virginica)))

y_predict1 = lda1.fit(X_train, y_train).predict(X_test)
metrics.accuracy_score(y_test, y_predict1)

Tag Cloud

R    SQL    classification    demension reduction    jekyll    python    regression    supervised   
Hyeongjun Kim

Hyeongjun Kim

Financial Economist, Data Scientist, and Hearthstone Player

rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora