인생마커
article thumbnail
Published 2021. 7. 26. 00:01
(ML/DL)Heart Attack 예측 모델 인공지능

 

 

Heart Attack Analysis & Prediction Dataset

A dataset for heart attack classification

www.kaggle.com

 

Kaggle 데이터셋으로 Traditional Machine Learning 과 Deep Learning을 진행했습니다.

 

Heart Attack Analysis dataset은 의료분야에서 인공지능이 활발하게 이용되기도 하고 Kaggle에 양질의 데이터가 많습니다.

 

다만, 이번에 사용한 데이터 갯수는 300개 정도입니다.

 

모델을 학습시키기에 현저히 적은 데이터 갯수지만 많은 데이터로 진행을 한다고 해서 맥락이 바뀌진 않습니다.

 

전체적으로 Google Colab에서 진행했습니다.

 

훈련 data에 대한 feature 수는 총 13개 입니다.

 

ouput 과 상관관계가 높게 보이는 feature 들을 표시해 두었습니다.

 

특히나 CP(가슴 통증 유형)의 상관관계가 가장 높았는데 시각화 후에 좀 더 정확히 판단을 해보도록 합시다.

 

 

 

cp와 exang가 각각 양과 음에서 가장 상관관계 절대치가 높이 보입니다.

 

 

확실히 질병 유무에 따른 바그래프가 눈에 띄게 다른걸 확인했습니다.

 

Kaggle에서 받은 양질의 데이터라 결측치나 outlier로 판단되는 부분이 극히 적어서 전처리 과정이 편했습니다.

 

우선 chol(BMI 센서를 통해 가져온 콜레스테롤 (mg/dl)) 부분에서 outlier 가 확인되었고 drop시켜줬습니다.

 

 

 

Data Preprocessing(데이터 전처리)

 

data 를 train data와 test data 로 나누어 줍니다.

 

모델 학습에 데이터 셋을 전부 사용해버린다면 예측을 수행할 때 모델의 정확도를 알 수 없습니다.

 

가지고 있는 데이터는 이미 모델이 학습해버린 데이터이기 때문이죠.

 

그래서 test data는 모델과 접촉이 없어야 나중에 결과를 확인할 때 신빙성이 있습니다.

 

SMOTE

 

클래스 불균형 문제를 해결하기 위한 수단 중 하나입니다.

 

클래스 불균형이란 classfication 에서 output이 극단적으로 한쪽에 쏠릴때를 말하는데

 

예를 들어서 , 데이터에 질병에 걸린 사람이 90%이고 안걸린 사람이 10%이라고 가정했을 때

 

학습결과가 질병에 걸렸다고만 예측을 해도 정확도가 90%가 될 것입니다.

 

 

[Python] SMOTE를 통한 데이터 불균형 처리

* 본 포스트는 개인연구/학습 기록 용도로 작성되고 있습니다. 데이터 분석시 쉽게 마주하게 되는 문제 중 하나가 데이터의 불균형이다. 우리가 찾고자하는 데이터의 타겟의 수가 매우 극소수인

mkjjo.github.io

 

이 데이터 셋은 클래스 불균형 문제는 없지만

 

데이터의 갯수가 너무 적어서 oversampling 과정을 진행했습니다.

 

나중에 비교해보니 학습할 때 validation data의 accuracy 는 당연 향상이 되었지만 test data에 대한 정확도는 큰 차이를 보이지 않았습니다.

 

성능향상을 기대하고 oversampling 과정을 진행한게 아니라 google auto ML 을 돌릴 때 dataset의 갯수가 1000개가 넘지 않으면 사용해 볼 수가 없었습니다.

 

그리고 oversampling 을 한 김에 이 데이터와 원본데이터의 성능을 비교해보는 식으로 진행했습니다.

 

머신러닝과 딥러닝에 들어가는 data셋의 형태가 달라서 구분이 필요했습니다.

 

이번 머신러닝은 pycaret이라는 라이브러리를 사용했는데 여기서는 전처리를 자동으로 해주기 때문에

따로 scaling 이나 one-hot encoding 과정을 제외하였고 파라미터로 target data를 feature 중에서 선택을 하기 때문에 분리하는 과정도 불필요합니다.

 

pycaret을 이용한 Traditional Machine Learning

 

사이킷런과 파이캐럿이 버전이 호환이 되어야 합니다.

 

model setup

from pycaret.classification import *
model = setup(data=train_data_ML, 
              target='output', 
              train_size=0.7,
              session_id=123,
              )

 

모델을 셋업해줍니다.

 

정말 간단하게 머신러닝 모델을 돌릴 수 있습니다.

 

또한, pycaret의 compare_models 함수를 사용하면 많은 모델들의 성능을 한 번에 볼 수 있습니다.

 

top = compare_models(n_select = 15)

 

 

왼쪽이 원본데이터고 오른쪽이 oversampling 을 거친 데이터 입니다.

 

오른쪽의 성능이 비교불가할 정도로 잘나오는 것 같지만 실상은 그렇지 않습니다.

 

비슷한 데이터들의 반복학습으로 오버피팅 되었을 확률이 높기 때문이죠.

 

성능을 바로 확인해주려면 학습과 성능시험에 전혀 사용되지 않은 test data를 사용해보면 됩니다.

 

 

마찬가지로 왼쪽이 원본, 오른쪽이 oversampling data 입니다.

 

모델기준은 시험성능이 가장 높은 top5를 뽑았습니다.

 

원본데이터의 accuracy가 높은 것을 확인할 수 있습니다.

 

그리고 pycaret은 앙상블 기법도 편리하게 사용할 수 있습니다.

 

stack 모델을 만들어서 사용해보도록 합시다.

 

 

저장한 top model 중 상위 3개로 스택모델을 만들고 교차검증까지 자동으로 진행합니다.

 

성능지표의 시각화도 간편하게 확인할 수 있습니다.

 

 

evaluate_model(model) 함수를 사용하면 ROC curve 뿐만 아니라 10개 정도 되는 시각화 지표들이 생성되고 클릭으로 돌아가면서 볼 수 있습니다.

 

딥러닝 예측 모델

 

딥러닝 모델을 구축하는데 앞서 가장 중요하게 생각해야할 요소들이 무엇일까요?

 

바로 데이터 입니다.

 

양질의 데이터 갯수가 많아야 합니다.

 

정해진 숫자는 물론 없지만 딥러닝에 필요한 데이터 갯수가 몇 개냐고 누가 물어본다면 최소 10만개라고 말할 것 같습니다.

 

알맞게 결측치를 메우거나 전처리를 하는 과정도 여기에 포함될 것입니다.

 

적절한 데이터셋을 만들었다고 가정했을 때 또 중요한 요소는 Hyper Parameter (이하 HP) 입니다.

 

딥러닝은 블랙박스 모델이라고 놀림받는 만큼 모델학습에서 사람이 손쓸 수 있는 부분이 한정적입니다.

 

최고의 아웃풋 도출을 위해 모델 내부에서 학습이 계속해서 이루어지는데 우리는 그 안을 들여다 볼 수 없습니다.

 

그 전에 모델을 셋업 할 때 히든레이어의 갯수라던지 퍼셉트론의 갯수, 활성화 함수 설정 같은 결과를 위한 HP 설정부분이 유일하게 제어할 수 있는 부분이기도 합니다.

 

이 HP는 결과를 보고 판단할 수 밖에 없습니다.

 

여러가지 조합을 시도해보면서 최적의 HP를 도출해 내는 것입니다.

 

사람이 불편함을 느끼면 도구가 탄생하듯이 이 최적의 HP를 찾아주는 도구도 당연히 존재합니다.

 

 

Keras Tuner 소개  |  TensorFlow Core

개요 Keras Tuner는 TensorFlow 프로그램에 대한 최적의 하이퍼파라미터 세트를 선택하는 데 도움을 주는 라이브러리입니다. 머신러닝(ML) 애플리케이션에 대한 올바른 하이퍼파라미터 세트를 선택하

www.tensorflow.org

 

 

def build_hyper_model(hp):
    
    model = keras.Sequential()
    model.add(layers.Dense(input_dim=13, units=16, activation='relu', kernel_initializer=initializers.he_normal(), kernel_regularizer=regularizers.l2(0.001))) 
    
    for i in range(hp.Int('num_layers', min_value=1, max_value=3)): 
        
        hp_units = hp.Int('units_' + str(i), min_value=8, max_value=256, step=32)
        hp_activations = hp.Choice('activation_' + str(i), values=['relu', 'elu'])
        
        model.add(layers.Dense(units=hp_units, activation=hp_activations, 
                               kernel_initializer=initializers.he_normal()))

    model.add(layers.Dense(2, activation='softmax'))
    
    hp_learning_rate = hp.Choice('learning_rate', values = [1e-2, 1e-3, 1e-4]) 
    
    model.compile(optimizer = keras.optimizers.Adam(learning_rate = hp_learning_rate),
                loss = keras.losses.CategoricalCrossentropy(),
                metrics = ['accuracy']) # tf.keras.metrics.CategoricalAccuracy()
    
    return model

 

Bayesian Optimization 을 사용했습니다.

 

tuner = kt.BayesianOptimization(build_hyper_model,
                                objective = 'val_accuracy', 
                                max_trials = 10, 
                                directory = 'test_prac_dir', 
                                project_name = 'heart_hyper_1')
tuner.search_space_summary()
tuner.search(train_data_scaled, 
             train_label, 
             batch_size=100, 
             epochs=20, 
            validation_split=0.2)
tuner.results_summary(num_trials=3)

 

최적 HP를 확인하고 저장합니다.

 

top3_models = tuner.get_best_hyperparameters(num_trials=3)

for idx, model in enumerate(top3_models):
    print('Model performance rank :', idx)
    print(model.values)
    print()


# Check the best trial's hyper-params

best_hps = top3_models[0]

print("""
The hyperparameter search is complete. 
* Optimal # of layers : {}
* Optimal value of the learning-rate : {}""".format(best_hps.get('num_layers'), best_hps.get('learning_rate')))

for layer_num in range(best_hps.get('num_layers')):
    print('Layer {} - # of Perceptrons :'.format(layer_num), best_hps.get('units_' + str(layer_num)))
    print('Layer {} - Applied activation function :'.format(layer_num), best_hps.get('activation_' + str(layer_num)))

결과값

 

models = tuner.get_best_models(num_models=3)
top_model = models[0]
top_model.summary()
print()

results = top_model.evaluate(test_data_scaled, test_label)
print('Cross-entropy :', results[0])
print('Accuracy :', results[1])

 

best model 을 저장하고 바로 불러와서 test data로 성능을 시험합니다.

 

 

78퍼센트 확률을 보이고 있습니다.

 

이번 모델에서 이런 성능 지표는 별로 관심은 두지 않았습니다.

 

데이터 숫자가 모델의 성능적인 부분을 테스트하기에 너무나도 부족하기에..

 

그리고 한가지 더 신경써야 할 부분이 있는데 바로 batch size와 epoch입니다.

 

 

배치(batch)와 에포크(epoch)란?

CNN과 같은 딥러닝 모델을 훈련시키다보면 꼭 만나게 되는 것이 배치(batch), 에포크(epoch)라는 단어입니다. 이 두 단어가 무엇을 지칭하는 것인지를 알아야 모델을 제대로 훈련시킬 수 있습니다.

bskyvision.com

 

좋은 batch size 고르기

Engineering for the better world 🌱

nyanye.com

 

 

이전은 베스트 모델을 바로 불러온 것입니다.

 

그래서 epoch나 batch size는 tuner를 돌릴 때 그대로의 모델입니다.

 

반면, 최적의 HP만을 저장하고 모델을 새로 학습시킬 수도 있습니다.

 

이때, 사용해준 도구가 또 하나 있는데 keras callback.ModelCheckpoint 입니다.

 

만약, epoch를 100으로 두고 모델을 학습킨다고 가정해보도록 하죠.

 

50까지 val_acc가 잘올라가고 성능이 점점 좋아지는것이 보이고 있는데 갑자기 그 뒤부터 점점 성능이 떨어진다면?

 

모델은 마지막 학습을 기준으로 성능이 나오기 때문에 이전에 잘나온 모델을 놔두고 성능이 떨어지는 모델이 저장됩니다.

 

이렇게 반복되는 학습속에서 하나를 기준으로 (나는 val_acc) 잡고 기준에서 가장 성능이 잘나온 모델을 자동으로 저장합니다.

 

checkpoint_path = '/content/saved_model/my_model.h5'

callback_checkpoint = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path, 
                                                         monitor='val_accuracy', 
                                                         save_best_only=True, 
                                                         verbose=0)

 

경로를 지정해주고 콜백함수 객체를 생성합니다.

 

model = tuner.hypermodel.build(best_hps)
model.fit(train_data_scaled, 
          train_label, 
          batch_size = 100, 
          epochs = 20, 
          validation_split=0.2,
          verbose = 1,
          callbacks=[ callback_checkpoint ]
          )

 

그런 다음 모델을 다시 학습시킵니다.

 

best_hps 에는 아까 튜너를 돌려서 나온 최적의 하이퍼파라미터가 들어가 있습니다.

 

 

확실히 best epoch를 기준으로 저장을 하다보니 test data에서도 acc가 조금 잘나오는 모습이지만
이것도 데이터 숫자가 워낙 작아서 여기서만큼은 의미있는 차이는 아닙니다.

'인공지능' 카테고리의 다른 글

네이버기반 맛집 분석  (2) 2021.07.14
타이타닉 생존자 예측, 머신러닝(feat.sklearn)  (0) 2021.07.05
profile

인생마커

@Cottonwood__

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!