ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Machine Learning] RandomForest 랜덤 포레스트 & Threshold, ROC Curve, AUC
    Data Science/Machine Learning & Deep Learning 2021. 2. 20. 00:08

     

     

     

     

    결정 트리모델(Decision tree)이 하나의 트리만 사용하는 모델입니다. 결정 트리모델은 상위 노드에서 에러가 생기면 하부 노드에도 계속해서 영향을 주고, 트리가 깊어지면 과적합이 될 수 있다는 단점이 있는데 이를 해결할 수 있는 모델이 랜덤 포레스트(Random forest)입니다.

     

     

     

     

    랜덤 포레스트는 앙상블(ensemble) 방법으로, 앙상블 방법은 하나의 데이터로 기본 모델을 여러개 만들어 여러 모델의 예측결과를 다수결 또는 평균으로 하여 예측을 내는 방법을 말합니다. 랜덤 포레스트는 기본 모델을 결정트리로 하는 앙상블 모델입니다.

     

     

     

     

    앙상블 방법에서 기본 모델은 부트스트랩(Bootstrap) 샘플링을 하여 얻은 샘플 데이터로 학습을 합니다. 원본 데이터에서 복원 추출 방법으로 샘플링을 하는 것인데, 이는 원본 데이터에서 샘플을 뽑아 다시 돌려놓고 다음 샘플을 뽑는 방식을 반복하는 것으로 중복으로 데이터가 뽑힐 수 있습니다. 이렇게 뽑힌 데이터는 학습에 사용하고, out of bag(oob)  샘플이라고 하는 뽑히지 않은 나머지 데이터를 검증에 사용합니다.

     

     

     

     

    부트스트랩으로 샘플링하고 만들어진 기본 모델들을 합치는 과정을 Aggregation이라고 합니다. 회귀 문제에서는 평균으로 결과를 내고, 분류 문제에서는 다수결로 예측을 합니다. 부트스트랩 샘플링을하고, 여러 기본 모델을 만들어 학습하고, out-of-bag으로 검증한 후 aggregation 하는 과정을 배깅(Bagging, Bootstrap Aggregating)이라고 합니다. 랜덤 포레스트에서 학습되는 트리 모델은 배깅을 통해 만들어지고, 각 트리들은 무작위로 선택된 특성들을 가지고 분기를 수행하기 때문에 결정트리모델보다 상대적으로 과적합을 피할 수 있습니다.

     

     

     

     

     

     

    모델을 만들기에 앞서 hold-out 검증 방법을 사용하기 위하여 

    scikit learn의 train_test_split을 이용하여 훈련 데이터를 훈련 데이터와 검증 데이터로 분리해주었습니다.

     

    from sklearn.model_selection import train_test_split
    train, val = train_test_split(train, test_size=0.20, 
                                  stratify=train[target], random_state=2)

     

     

     

     

     

    특성들을 ordinal encoder로 인코딩해주고 simple imputer로 결측치를 평균으로 대체해주는,

    랜덤 포레스트 분류 모델을 파이프라인으로 만들어 주었습니다.

     

    from sklearn.pipeline import make_pipeline
    from category_encoders import OrdinalEncoder
    from sklearn.impute import SimpleImputer 
    from sklearn.ensemble import RandomForestClassifier
    
    
    model = make_pipeline(
        OrdinalEncoder(),  
        SimpleImputer(),   # 결측치 평균으로 대체 
        RandomForestClassifier(random_state=10, n_jobs=-1, oob_score=True)
    )
    
    model.fit(X_train, y_train)  # 모델 학습 

     

     

     

     

     

    .oob_score_ 메소드를 활용하면 만들어진 랜덤 포레스트 모델의 성능을 체크할 수 있습니다.

     

    model.named_steps['randomforestclassifier'].oob_score_

     

     

     

     

     

    만들어진 모델에 검증 데이터로 예측하여 모델의 정확도를 확인해보았습니다.

     

    from sklearn.metrics import accuracy_score
    
    y_pred = model.predict(X_val)
    accuracy_score(y_val, y_pred)

     

     

     

     

     

    classification report 를 사용하면 정밀도(Precision)와 재현율(Recall)도 함께 확인할 수 있습니다.

     

    - 정밀도(Precision) : Positive로 예측한 것 중 실제 Positive인 비율, 올바르게 Positive 맞춘 비율 

    - 재현율(Recall) : 실제로 Positive인 것 중 올바르게 Positive라고 예측한 비율 

     

    from sklearn.metrics import classification_report
    classification_report(y_val, y_pred)

     

    classification report

     

    이와 같은 형태로 모델의 성능을 확인할 수 있는 리포트를 출력해줍니다.

     

     

     

     

     

    랜덤포레스트는 기본 임계값(threshold)을 0.5로 하고 있어 확률값을 0.5를 기준으로 하여 분류를 합니다.

     

    1에 속할 확률을 히스토그램으로 그린 그래프, threshold =  0.5

     

     

     

    임계값을 어떻게 설정하느냐에 따라서 분류기의 정밀도와 재현율이 달라지는데요

    분류 문제에서 필요에 따라 임계값을 잘 조정해주면 보다 효율적으로 분류를 할 수 있습니다.

     

     

     

    최적의 임계값은 재현율은 최대로 하고 위양성율은 최소화 하는 임계값인데,

    ROC(Receiver Operating Characteristic) curve와 AUC를 사용하면 최적의 임계값을 찾을 수 있습니다.

    AUC는 Area Under the Curve로 ROC curve 아래 면적을 의미합니다.

     

    from sklearn.metrics import roc_curve
    
    y_pred_proba = model.predict_proba(X_val)[:, 1]
    fpr, tpr, thresholds = roc_curve(y_val, y_pred_proba) # roc_curve(타겟값, prob of 1)

     

     

     

     

     

    ROC curve는 다음과 같은 방법으로 시각화할 수 있습니다.

     

    plt.scatter(fpr, tpr)
    plt.title('ROC curve')
    plt.xlabel('FPR(Fall-out)')
    plt.ylabel('TPR(Recall)');

     

    ROC curve

     

     

     

     

     

    Threshold의 최적값을 찾는 방법입니다. 

     

    optimal_idx = np.argmax(tpr - fpr)  # threshold 최대값 인덱스
    optimal_threshold = thresholds[optimal_idx]  # 최적 threshold

    최적의 임계값을 다음과 같이 알아보았습니다.

    임의로 설정된 임계값을 0.5로 하여 예측한 것보다 1로 예측되는 것들이 많아질 것 같습니다. 

     

     

     

     

     

    최적의 임계값을 적용해 예측해보고 classification report로 살펴보겠습니다.

     

    y_pred_optimal = y_pred_proba >= optimal_threshold
    classification_report(y_val, y_pred_optimal)

     

    임계값 최적화된 모델의 classification report

     

    미세한 차이이지만 1로 예측하는 recall이 증가했음을 알 수 있습니다. 

     

     

     

     

     

    마지막으로 ROC score를 계산하는 방법입니다.

     

    from sklearn.metrics import roc_auc_score
    auc_score = roc_auc_score(y_val, y_pred_proba)

     

    ROC score는 높을 수록 좋습니다!

     

     

     

     

     

Designed by Tistory.