🐍 파이썬 데이터 분석 프로젝트/🧠 EEG 뇌전증 분석 LSTM

🧠 EEG 뇌전증 분석 LSTM 04. 결과 해석

nyamin9 2023. 2. 9. 11:36

모바일은 화면을 돌려 가로화면으로 보시는 게 읽으시기 편할 수 있습니다. 돌려서 보시는 걸 추천드릴게요!!

 

 


 

🚩 학습된 모델의 성능을 바탕으로 confusion matrix를 그리고, 결과를 해석해보고자 합니다. 

  


🏆Confusion Matrix 해석

 

from sklearn.metrics import roc_curve, auc
from sklearn.metrics import (
    classification_report, confusion_matrix,
    ConfusionMatrixDisplay
)
from enum import Enum
 
input_size = 15
y_hat_vd = np.array([])

# test set의 feature만 정규화. np.array 형태.
dlist = test_x_st
y_vd = np.concatenate((np.zeros(len(test[test['y']==0])),np.ones(len(test[test['y']==1])),
                       np.zeros(len(test[test['y']==2]))+2),axis=0).astype('int64')

# 정의한 net이 15개의 입력을 받기 때문에 input_size는 15로 설정.
# argmax를 통해 가장 확률이 높은 인덱스를 받아 예측 결과를 생성.
for n in range(len(dlist)):
    a = dlist
    a = a[n]
    N = int(np.ceil(len(a)/input_size))
    a = np.pad(a,[0 ,N*input_size-len(a)])
    X = torch.Tensor(a).view(1,N,input_size)
    y_hat = net(X.to(device))
    y_hat = y_hat[:,-1,:]   
    y_hat_vd = np.append(y_hat_vd,torch.argmax(y_hat.cpu().softmax(1),dim=1))
# classification report, confusion matrix 생성
class Diagnosis(Enum):
    Epileptic_Seizures = 0
    Tumor = 1    
    Normal = 2

print(classification_report(
    y_vd,
    y_hat_vd,
    target_names=[d.name for d in Diagnosis]))

cm = confusion_matrix(
    y_vd,
    y_hat_vd,
#    normalize='true',
)
disp = ConfusionMatrixDisplay(
    confusion_matrix=cm,
    display_labels=[d.name for d in Diagnosis],
)
disp.plot(ax=plt.subplots(1, 1, facecolor='white')[1], cmap = 'Blues_r')

 

>>

                    precision    recall  f1-score   support

Epileptic_Seizures       0.97      0.97      0.97       500
             Tumor       0.63      0.65      0.64       500
            Normal       0.88      0.87      0.88      1500

          accuracy                           0.85      2500
         macro avg       0.83      0.83      0.83      2500
      weighted avg       0.85      0.85      0.85      2500
      
      
<sklearn.metrics._plot.confusion_matrix.ConfusionMatrixDisplay at 0x1130f538bb0>
 

 

confusion matrix

 


 

 

프로젝트의 방향성을 뇌파와 뇌전증에 대한 것으로 잡고 데이터를 찾던 중 발견한 데이터가 바로 본 프로젝트에서 사용한 데이터입니다. 증상 혹은 대상군 별 class가 0,1,2,3,4로 깔끔하게 만들어져 있었기 때문에 그 성능도 괜찮을 것이라 생각하였기에 이 데이터를 사용했습니다. 다만 데이터를 살펴본 결과 뇌전증 환자에 대한 class인 0(간질발작), 1(뇌종양) 도 있었지만 class 2,3,4 는  정상인의 뇌파를 측정한 결과였습니다. 따라서 저희 팀은 뇌파 측정 중에 일어난 차이를 가지고 정상인의 class를 나누는 것이 유의미한 일인가 생각했고, 결론적으로 정상인의 class를 하나로 통합했습니다. 다만 이때 걱정되는 문제는 class간 비율이 1:1:3으로 정상인의 데이터가 상대적으로 많아지는 것이었습니다.

 

 

결론부터 말씀드리자면, 모델의 성능에 약간의 영향을 주었습니다. 구체적인 수치 파악을 위해 confusion matrix의 결과를 바탕으로 class 별 accuracy를 계산해 보았으며, 결과는 아래와 같습니다.

 

 

class accuracy
Epileptic_Seizures (0) 0.966
Tumor (1) 0.652
Normal (2) 0.871

 

 

종양만을 가지고 있는 경우는 그 정확도가 떨어졌기에 accuracy는 굉장히 높은 수치까지 성장한 것을 확인했지만, 전체적인 accuracy는 생각보다 낮게 측정되었습니다. 다만 normal class가 상대적으로 많이 데이터였기 때문에 데이터가 어느 정도 불균형하다는 것을 염두에 두고, 저희 팀은 accuracy보다는 f1-score에 좀 더 비중을 두고 분석하는 것이 좋을 수 있다고 생각하였습니다.

 

 

그럼에도 저희 팀이 찾아내고 싶었던 target인 Epileptic_Seizures (label=0)에 대해서는 그 score가 0.97로 굉장히 높은 것을 확인할 수 있었고, 이에 대해서는 좋은 성능을 보이는 모델이라 할 수 있을 듯 합니다. 따라서 프로젝트 진행의 목적에는 적절한 모델이라고 판단하였으며, class를 재분류해 새로운 모델을 만들 필요성은 느끼지 못했습니다. 또한 confusion matrix 에도 나타나 있듯이, 500개의 0 class에 대해 483개의 정확한 예측을 한 모델을 만들 수 있었습니다.

 

 

하지만 상대적으로 Tumor에 대한 f1-score 는 상당히 낮은 것을 확인하였습니다. 이는 아무래도 신호의 파형이 tumor와 normal의 경우가 비슷한 부분들이 존재하기에 tumor를 정확히 파악하기에는 tumor label에 대한 비율이 부족하지 않았을까 싶습니다. 결론적으로 calss를 통합하면서 생긴 상대적 비율 차이가 프로젝트의 주 목적인  Epileptic_Seizures를 알아내는 데에는 지장이 없었지만, 다른 label, 특히 Tumor를 파악하는 데에는 영향을 미쳤다고 생각합니다.

 

 


🚩 confusion matrix를 통해 모델의 결과를 분석해보았습니다. 하지만 인공지능 모델을 다른 데이터에 적용하기 위해서는 모델의 하이퍼파라미터를 저장하고 이를 적용하는 과정이 필수적입니다. 다음 포스팅에서는 이 부분을 다루도록 하겠습니다.