-
LDA(Linear Discriminant Analysis)란 무엇인가? (파이썬으로 LDA 구현하기 실습 포함)데이터/처리 및 분석 2024. 10. 18. 10:51
LDA(Linear Discriminant Analysis)는 무엇인가요?
LDA(Linear Discriminant Analysis)는 복잡한 데이터를 쉽게 분류할 수 있도록 도와주는 방법입니다. 특히 여러 클래스(카테고리)로 데이터를 나눌 때 유용합니다. 데이터를 차원 축소하면서도 분류 정확도를 높일 수 있어, 데이터를 더 쉽게 이해할 수 있게 해줍니다. 예를 들어, 여러 변수로 이루어진 복잡한 데이터가 있을 때, LDA는 가장 중요한 정보만 남기면서도 각 클래스(카테고리)의 차이를 강조하여 분류를 더 쉽게 만듭니다.
LDA와 PCA의 차이점은?
LDA와 PCA의 차이점은 크게 두 가지로 나눌 수 있습니다. 목적과 학습 방식입니다. 먼저, PCA는 데이터를 단순화하는 데 중점을 둡니다. 데이터가 어떻게 퍼져 있는지, 즉 분산을 기준으로 중요한 축을 찾아 차원을 축소합니다. 예를 들어, 꽃잎의 길이와 폭처럼 여러 변수들이 있을 때, PCA는 이 변수를 단순화하여 중요한 패턴을 추출하는 과정입니다. 반면에, LDA는 각 클래스 간의 차이에 집중합니다. 데이터가 어떤 카테고리에 속하는지 이미 알고 있는 상황에서, LDA는 서로 다른 카테고리를 더 명확하게 구분할 수 있는 방향을 찾습니다. 예를 들어, 빨간색 점과 파란색 점이 섞여 있을 때, 이 점들을 가장 잘 나눌 수 있도록 직선을 그어주는 역할을 합니다. 이렇게 하면 각 클래스 간의 경계가 명확해져서 분류가 더 쉬워집니다.
또한, LDA와 PCA의 중요한 차이점 중 하나는 지도 학습과 비지도 학습의 차이입니다. LDA는 지도 학습 기법으로, 데이터를 나눌 때 클래스 레이블, 즉 정답이 필요합니다. 데이터를 학습할 때 이미 주어진 클래스 정보를 바탕으로, 각 클래스 간의 차이를 최대화하면서 차원을 줄입니다. 반면에, PCA는 비지도 학습 기법으로, 데이터에 레이블이 없더라도 사용할 수 있습니다. PCA는 데이터를 분산 기준으로 가장 중요한 축을 찾아 차원을 축소하는 방식입니다. 즉, PCA는 데이터 간의 패턴을 찾고 단순화하는 데 중점을 두지만, 레이블 정보는 사용하지 않습니다.
간단히 요약하자면, PCA는 데이터의 전반적인 패턴을 찾고 데이터를 간소화하는 데 목적이 있는 반면, LDA는 클래스 간의 차이를 더 명확하게 구분하여 분류 성능을 극대화하는 방법입니다. PCA는 레이블 없이 데이터를 분석할 수 있는 반면, LDA는 레이블이 주어진 상태에서 더 나은 분류를 목표로 합니다.
LDA의 핵심 개념
LDA는 주로 다음 두 가지 개념을 기반으로 작동합니다:
- 클래스 간 분산 (Between-Class Scatter): 클래스 간의 평균 차이를 계산하여, 각 클래스가 서로 얼마나 잘 구분되는지를 나타냅니다. 이 값이 클수록 각 클래스가 더 명확히 구분됩니다.
- 클래스 내 분산 (Within-Class Scatter): 같은 클래스 내에서 데이터의 분포를 나타내며, 각 클래스의 데이터가 얼마나 퍼져 있는지를 계산합니다. 이 값을 최소화함으로써, 클래스 내의 데이터가 서로 가까워지도록 만듭니다.
LDA는 클래스 간 분산을 최대화하고, 클래스 내 분산을 최소화하는 선형 변환을 찾아 데이터의 차원을 축소합니다.
LDA 계산 과정
데이터 정규화
LDA를 적용하기 전에 데이터 정규화가 필요합니다. 정규화는 각 특징(feature)의 값이 서로 다른 스케일을 가질 경우 발생하는 왜곡을 방지하고, 모든 특징이 동일한 스케일로 변환되도록 도와줍니다. 보통 평균이 0, 표준편차가 1인 형태로 변환합니다.
클래스별 평균 벡터 계산
각 클래스별 평균 벡터를 계산하여, 클래스 간의 차이를 나타낼 수 있는 기준을 만듭니다.
여기서 \( m_k\)는 클래스 \( k \)의 평균 벡터이고, \(n_k\)는 해당 클래스에 속하는 데이터 포인트의 수입니다.
클래스 내 분산 행렬 계산
각 클래스 내 데이터들이 얼마나 퍼져 있는지를 계산합니다. 이때, 각 클래스의 데이터가 평균을 중심으로 얼마나 떨어져 있는지를 나타냅니다.
\( S_W = \sum_{k=1}^K \sum_{i=1}^{n_k} (x_i - m_k)(x_i - m_k)^T \)
여기서 \( S_W \)는 클래스 내 분산 행렬입니다.
클래스 간 분산 행렬 계산
클래스 간 평균 차이를 바탕으로, 클래스 간 분산 행렬을 계산합니다.
\( S_B = \sum_{k=1}^K n_k (m_k - m)(m_k - m)^T \)
여기서 \(S_B\)는 클래스 간 분산 행렬이고, \(m\)은 전체 데이터의 평균 벡터입니다.
고유값 및 고유벡터 계산
클래스 내 분산과 클래스 간 분산의 비율을 최대화하는 선형 변환을 찾기 위해, 분산 행렬의 고유값과 고유벡터를 계산합니다. 고유벡터는 새로운 좌표계의 축을 나타내며, 고유값은 이 축이 데이터의 분산을 얼마나 잘 설명하는지를 나타냅니다.
데이터 변환
가장 중요한 고유값에 해당하는 고유벡터를 선택하여 데이터를 새로운 공간으로 변환합니다. 이 새로운 공간에서는 클래스 간 차이가 더 명확히 드러나게 됩니다.
LDA 실습: Iris 데이터셋에 적용하기
Iris 데이터셋을 사용해 LDA를 파이썬으로 구현하는 방법을 설명하겠습니다.
1. 필요한 라이브러리 임포트
먼저, LDA를 적용하고 Logistic Regression으로 모델 성능을 평가하기 위해 필요한 라이브러리들을 임포트합니다.
import numpy as np import pandas as pd from sklearn.preprocessing import StandardScaler from sklearn.discriminant_analysis import LinearDiscriminantAnalysis from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn.metrics import accuracy_score from sklearn.datasets import load_iris
- NumPy와 Pandas: 데이터 처리 및 조작에 사용됩니다.
- StandardScaler: 데이터를 정규화하기 위한 도구입니다.
- LinearDiscriminantAnalysis: LDA 모델을 구현하는 데 사용됩니다.
- train_test_split: 데이터를 훈련 세트와 테스트 세트로 분리합니다.
- LogisticRegression: Logistic Regression 모델을 통해 분류 작업을 수행합니다.
- accuracy_score: 모델 성능을 평가하는 정확도(accuracy)를 계산하는 데 사용됩니다.
- load_iris: Iris 데이터셋을 불러오는 함수입니다.
2. 데이터 로드 및 데이터프레임 구성
Iris 데이터셋을 로드하고, 이를 Pandas 데이터프레임으로 변환합니다. 데이터프레임은 4개의 특징(꽃받침 길이, 꽃받침 너비, 꽃잎 길이, 꽃잎 너비)과 타겟 값(세 가지 붓꽃 품종)을 포함합니다.
iris = load_iris() df = pd.DataFrame(iris.data, columns=iris.feature_names) df['target'] = iris.target
- iris.data: 붓꽃의 4가지 특징을 나타내는 데이터.
- iris.target: 각 샘플이 어떤 품종인지에 대한 레이블(클래스).
3. 데이터 분할 (Train/Test Split)
데이터를 훈련 세트와 테스트 세트로 분할합니다. train_test_split을 사용해 70%는 훈련 데이터로, 30%는 테스트 데이터로 나누며, random_state=42를 지정하여 재현 가능한 결과를 얻습니다.
X = df.drop(columns=['target']) y = df['target'] X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
- X: 특징 데이터.
- y: 타겟 값(붓꽃 품종).
- X_train, X_test: 훈련과 테스트를 위한 입력 데이터.
- y_train, y_test: 훈련과 테스트를 위한 타겟 값.
4. 데이터 정규화
LDA와 Logistic Regression에 데이터를 적용하기 전에, 각 변수의 값들을 표준화합니다. 표준화는 평균이 0이고, 표준편차가 1이 되도록 값을 변환하는 과정입니다. 이를 통해 변수 간 단위 차이가 결과에 미치는 영향을 줄입니다.
scaler = StandardScaler() X_train_standardized = scaler.fit_transform(X_train) X_test_standardized = scaler.transform(X_test)
- fit_transform: 훈련 데이터에 맞춰 표준화를 적용합니다.
- transform: 학습된 스케일로 테스트 데이터를 변환합니다.
5. LDA 적용
훈련 데이터에 LDA를 적용하여 2개의 주성분으로 차원을 축소합니다. 차원을 축소한 후, 훈련된 LDA 모델을 사용하여 테스트 데이터도 변환합니다.
lda = LinearDiscriminantAnalysis(n_components=2) X_train_lda = lda.fit_transform(X_train_standardized, y_train) X_test_lda = lda.transform(X_test_standardized)
- n_components=2: 두 개의 주성분으로 차원을 축소합니다.
- fit_transform: LDA 모델을 훈련 데이터에 맞춰 학습하고 변환합니다.
- transform: 학습된 LDA 모델을 테스트 데이터에 적용하여 변환합니다.
6. Logistic Regression 적용 및 성능 비교
이제 Logistic Regression 모델을 두 가지 데이터셋에 각각 적용합니다. 첫 번째는 원본 데이터를 사용한 경우이고, 두 번째는 LDA로 차원을 축소한 데이터를 사용한 경우입니다. 그 후 두 모델의 예측 결과를 비교합니다.
log_reg = LogisticRegression() log_reg.fit(X_train_standardized, y_train) y_pred_original = log_reg.predict(X_test_standardized) log_reg_lda = LogisticRegression() log_reg_lda.fit(X_train_lda, y_train) y_pred_lda = log_reg_lda.predict(X_test_lda)
- log_reg.fit: Logistic Regression 모델을 훈련 데이터에 맞춰 학습합니다.
- predict: 테스트 데이터에 대한 예측을 수행합니다.
7. 성능 비교 (정확도 계산)
마지막으로, 두 모델의 정확도를 계산하여 LDA 적용 여부에 따른 성능 차이를 확인합니다.
accuracy_original = accuracy_score(y_test, y_pred_original) accuracy_lda = accuracy_score(y_test, y_pred_lda) print("원본 데이터의 정확도:", accuracy_original) print("LDA 적용한 데이터의 정확도:", accuracy_lda)
- accuracy_score: 모델의 예측 결과와 실제 레이블을 비교하여 정확도를 계산합니다.
코드 결과 및 설명
- 원본 데이터의 정확도는 LDA를 적용하지 않은 상태에서 Logistic Regression을 적용한 경우입니다. 이 경우, 모든 4개의 특징을 사용하여 학습하고 예측했기 때문에 정확도가 높게 나올 가능성이 큽니다.
- LDA 적용한 데이터의 정확도는 차원을 축소하여 두 개의 주성분으로 변환한 후 Logistic Regression을 적용한 결과입니다. 여기서 약간의 정보 손실이 발생할 수 있지만, 중요한 패턴을 유지하면서도 차원 축소 덕분에 계산 비용이 줄어듭니다.
예상 출력 결과는 다음과 같습니다.
원본 데이터의 정확도: 1.0 LDA 적용한 데이터의 정확도: 0.9555555555555556
결과 분석
- 원본 데이터를 사용한 Logistic Regression의 경우, 100%의 정확도를 기록했습니다. 이는 모든 정보를 사용했기 때문에 모델이 데이터를 완벽하게 예측할 수 있음을 나타냅니다.
- LDA로 차원을 2개로 축소한 데이터의 경우, 정확도가 약간 감소하여 95.6%로 나타났습니다. 차원 축소 과정에서 일부 정보가 손실되었지만, 여전히 높은 정확도를 유지하면서 계산 효율성을 높일 수 있음을 보여줍니다.
마무리
LDA는 차원 축소뿐만 아니라 분류 성능을 개선하는 데도 유용한 기법입니다. 클래스 간의 차이를 최대화하면서 데이터의 차원을 줄임으로써, 더 간단한 모델로도 높은 정확도를 유지할 수 있습니다.
LDA와 PCA는 모두 차원 축소 기법이지만, LDA는 지도 학습 기반의 기법으로 클래스 정보를 활용해 데이터를 더 잘 분류할 수 있도록 돕습니다. Python과 같은 언어에서 sklearn 라이브러리를 사용하면, LDA를 쉽게 구현하여 분류 모델 성능을 향상시킬 수 있습니다.
'데이터 > 처리 및 분석' 카테고리의 다른 글
SVD(Singular Value Decomposition)란 무엇인가? (파이썬으로 SVD 구현하기 실습 포함) (0) 2024.10.19 PCA(Principal Component Analysis)란 무엇인가? (파이썬으로 PCA 구현하기 실습 포함) (0) 2024.10.15 차원축소(Dimensionality Reduction)란 무엇인가? 차원 축소 방법/데이터를 잘 다루는 방법 (2) 2024.10.14 수학적 거리의 세계: 나와 상대의 거리는 얼마나 될까? (0) 2024.09.27