LDA (Linear Discriminant Analysis)
preface 이번 포스트에서는 분류classification 방법론 가운데 하나인 LDA (Linear Discriminant Analysis) 와 QDA (Quadratic Discriminant Analysis) 에 대하여 설명합니다. 분류classification란 A 그룹과 B 그룹으로 분류된 데이터가 있을 때, 새로 관측된 데이터가 어느 그룹에 속할지 추정하는 것을 말합니다.
알고리즘
다음 자료를 참고하였습니다:
- James, et. al. “An Introduction to Statistical Learning with Application in R” (이하 ISLR)
- http://scikit-learn.org/stable/modules/lda_qda.html
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)