Finder 파일 편집 보기
🔍 🔋 📶 --
˚₊·—̳͟͞͞♡ BAXXUB ♡—̳͟͞͞·₊˚
Welcome to my space ⊹ ࣪ ﹏𓊝

BAXXUB 𐔌՞. .՞𐦯

사과가 되지 말고 도마도가 되어라
S/[기록] 프로젝트 기록 2026. 5. 26. 14:09 by 박혁구

[Modeling] LDA, QDA, tSNE

1. LDA

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

df = pd.read_csv('heart_disease_missing_processed.csv')

X = df.drop('Heart Disease Status', axis=1)
y = df['Heart Disease Status']

x_train, x_test, y_train, y_test, = train_test_split(X, y, test_size=0.2, random_state=42)

lda_model = LinearDiscriminantAnalysis()

lda_model.fit(x_train, y_train)
predictions = lda_model.predict(x_test)

print("\n=== LDA (Linear Discriminant Analysis) 최종 결과 ===")
train_predictions = lda_model.predict(x_train)
print(f"Train Accuracy: {accuracy_score(y_train, train_predictions):.4f}")
print(f"Test Accuracy: {accuracy_score(y_test, predictions):.4f}\n")

print("Confusion Matrix:")
print(confusion_matrix(y_test, predictions))

print("\nClassification_report:")
print(classification_report(y_test, predictions))
=== LDA (Linear Discriminant Analysis) 최종 결과 ===
Train Accuracy: 0.7984
Test Accuracy: 0.8065

Confusion Matrix:
[[1613    0]
 [ 387    0]]

Classification_report:
C:\Users\limye\anaconda3\envs\damvenv\Lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
C:\Users\limye\anaconda3\envs\damvenv\Lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
C:\Users\limye\anaconda3\envs\damvenv\Lib\site-packages\sklearn\metrics\_classification.py:1531: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.
  _warn_prf(average, modifier, f"{metric.capitalize()} is", len(result))
              precision    recall  f1-score   support

           0       0.81      1.00      0.89      1613
           1       0.00      0.00      0.00       387

    accuracy                           0.81      2000
   macro avg       0.40      0.50      0.45      2000
weighted avg       0.65      0.81      0.72      2000

 

고차원 데이터의 한계를 극복하기 위해 차원 축소 기법이자 분류기인 LDA 도입. 초기에는 데이터의 극심한 불균형으로 인해 모델의 사전확률이 Class 0 에 편향되어 과소적합이 발생함.

2. priors 통제

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis

df = pd.read_csv('heart_disease_missing_processed.csv')

X = df.drop('Heart Disease Status', axis=1)
y = df['Heart Disease Status']

x_train, x_test, y_train, y_test, = train_test_split(X, y, test_size=0.2, random_state=42)

lda_model = LinearDiscriminantAnalysis(priors=[0.5, 0.5])

lda_model.fit(x_train, y_train)
predictions = lda_model.predict(x_test)

print("\n=== LDA (Linear Discriminant Analysis) 최종 결과 ===")
train_predictions = lda_model.predict(x_train)
print(f"Train Accuracy: {accuracy_score(y_train, train_predictions):.4f}")
print(f"Test Accuracy: {accuracy_score(y_test, predictions):.4f}\n")

print("Confusion Matrix:")
print(confusion_matrix(y_test, predictions))

print("\nClassification_report:")
print(classification_report(y_test, predictions))
=== LDA (Linear Discriminant Analysis) 최종 결과 ===
Train Accuracy: 0.5235
Test Accuracy: 0.4965

Confusion Matrix:
[[820 793]
 [214 173]]

Classification_report:
              precision    recall  f1-score   support

           0       0.79      0.51      0.62      1613
           1       0.18      0.45      0.26       387

    accuracy                           0.50      2000
   macro avg       0.49      0.48      0.44      2000
weighted avg       0.67      0.50      0.55      2000

과소적합을 해결하기 위해 priors=[0.5, 0.5]로 조정하여 Bayesian Bias 통제, 소수 Class 1에 대한 탐지력을 정상화함.

=> 로지스틱 회귀와 LDA는 접근 방식은 완전히 다르지만 둘 다 결국 데이터 공간에 직선을 긋는 모델. 두 모델의 결과가 거의 일치한다는 것은 이 10차원 데이터 공간에서 직선으로 데이터를 가르는 선형적 접근 방식이 이미 수학적 한계(최대치)에 도달했다고 볼 수 있음. 즉, 이 데이터는 선형적으로 분리될 수 없는 데이터.

 

3. QDA 이차 판별 분석

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.discriminant_analysis import QuadraticDiscriminantAnalysis

df = pd.read_csv('heart_disease_missing_processed.csv')

X = df.drop('Heart Disease Status', axis=1)
y = df['Heart Disease Status']

x_train, x_test, y_train, y_test, = train_test_split(X, y, test_size=0.2, random_state=42)

qda_model = QuadraticDiscriminantAnalysis(priors=[0.5, 0.5])
qda_model.fit(x_train, y_train)

predictions = qda_model.predict(x_test)

print("\n=== QDA 최종 결과 ===")
train_predictions = qda_model.predict(x_train)
print(f"Train Accuracy: {accuracy_score(y_train, train_predictions):.4f}")
print(f"Test Accuracy: {accuracy_score(y_test, predictions):.4f}\n")

print("Confusion Matrix:")
print(confusion_matrix(y_test, predictions))

print("\nClassification_report:")
print(classification_report(y_test, predictions))
=== QDA 최종 결과 ===
Train Accuracy: 0.5733
Test Accuracy: 0.5315

Confusion Matrix:
[[878 735]
 [202 185]]

Classification_report:
              precision    recall  f1-score   support

           0       0.81      0.54      0.65      1613
           1       0.20      0.48      0.28       387

    accuracy                           0.53      2000
   macro avg       0.51      0.51      0.47      2000
weighted avg       0.69      0.53      0.58      2000

선형 모델이 완벽하게 동일한 한계점 (f1 0.26)에 부딪힌 반면, 결정 경계를 곡선으로 허용한 비선형 모델 QDA를 적용했을 때 탐지 성능이 소폭 (f1 0.28) 상승했음. 이는 심장병 발병 데이터가 단순한 선형 관계가 아닌 복잡한 비선형 구조를 띠고 있음을 증명함. 그러나 비선형 모델조차 0.3의 벽을 넘지 못하는 것은, 현재 주어진 10개의 임상 feature 만으로는 심장병을 완벽하게 분리할 수 없는 overlapping이 존재함.

 

4. tSNE 시각화 결과

=> 앞선 선형/비선형 분류 모델들이 공통적인 성능 한계에 봉착한 원인을 규명하기 위해 t-SNE를 활용한 비선형 차원 축소 시각화를 진행함. 시각화 결과, Class 0과 Class 1 데이터가 뚜렷한 Cluster를 형성하지 못하고 극도로 overlapping 되어 있는 것을 확인. 이는 모델의 튜닝이나 알고리즘의 문제가 아닌, 데이터 공간 본연의 복잡성과 모호성에서 기인한 한계.

 

해당 임상 지표만으로 심장병을 높은 정밀도로 분류하는 것에는 수학적 한계가 있음을 교차 검증. 향후 예측 성능을 획기적으로 개선하기 위해서는 ECG 파형 데이터, 심장 초음파 결과, 또는 유전자 마커와 같은 보다 직접적이고 고차원적인 의료 도메인 데이터의 추가 수집 및 결합이 필수적.

Dock
최소화된 창이 없어요