6.5.3 ROC 곡선 그리기

    ROC(Receiver Operating Characteristic) 그래프는 분류기의 임계 값을 바꾸어 가며 계산된 FPR과 TPR 점수를 기반으로 분류 모델을 선택하는 유용한 도구입니다. ROC 그래프의 대각선은 랜덤 추측으로 해석할 수 있고 대각선 아래에 위치한 분류 모델은 랜덤 추측보다 나쁜 셈입니다. 완벽한 분류기의 그래프는 TPR이 1이고 FPR이 0인 왼쪽 위 구석에 위치합니다. ROC 곡선의 아래 면적인 ROC AUC(ROC Area Under the Curve)를 계산하여 분류 모델의 성능을 종합할 수 있습니다.

    ROC 곡선과 비슷하게 분류 모델의 확률 임계 값을 바꾸어 가며 정밀도-재현율 곡선을 그릴 수 있습니다. 정밀도-재현율 곡선을 그리는 함수도 사이킷런에 구현되어 있습니다(http://scikit-learn.org/stable/modules/generated/sklearn.metrics.precision_recall_curve.html).

    다음 코드를 실행하여 위스콘신 유방암 데이터셋에서 두 개의 특성을 추출하여 종양의 악성 여부를 예측하는 분류 모델의 ROC 곡선을 그려 보겠습니다. 앞서 정의한 같은 로지스틱 회귀 파이프라인을 사용하지만 이번에는 두 개의 특성만 사용합니다. 다른 특성에 있는 유용한 정보를 사용하지 않기 때문에 분류 작업이 더 어려워지므로 만들어진 ROC 곡선이 시각적으로 잘 표현됩니다. 비슷한 이유로 StratifiedKFold의 폴드 개수를 세 개로 줄입니다. 코드는 다음과 같습니다.

    >>> from sklearn.metrics import roc_curve, auc
    >>> from numpy import interp
    
    >>> pipe_lr = make_pipeline(StandardScaler(),
    ...                         PCA(n_components=2),
    ...                         LogisticRegression(penalty='12',
    ...                                            random_state=1,
    ...                                            C=100.0))
    
    >>> X_train2 = X_train[:, [4, 14]]
    
    >>> cv = list(StratifiedKFold(n_splits=3, shuffle=True
    ...                           random_state=1).split(X_train,
    ...                                                 y_train))
    >>> fig = plt.figure(figsize=(7, 5))
    
    >>> mean_tpr = 0.0
    >>> mean_fpr = np.linspace(0, 1, 100)
    
    >>> for i, (train, test) in enumerate(cv):
    ...     probas = pipe_lr.fit(X_train2[train],
    ...                  y_train[train]).predict_proba(X_train2[test])
    ...     fpr, tpr, thresholds = roc_curve(y_train[test],
    ...                                      probas[:, 1],
    ...                                      pos_label=1)
    >>>     mean_tpr += interp(mean_fpr, fpr, tpr)
    >>>     mean_tpr[0] = 0.0
    >>>     roc_auc = auc(fpr, tpr)
    >>>     plt.plot(fpr,
    ...              tpr,
    ...              label='ROC fold %d (area = %0.2f)'
    ...              % (i+1, roc_auc))
    >>> plt.plot([0, 1],
    ...          [0, 1],
    ...          linestyle='--',
    ...          color=(0.6, 0.6, 0.6),
    ...          label='Random guessing')
    
    >>> mean_tpr /= len(cv)
    >>> mean_tpr[-1] = 1.0
    >>> mean_auc = auc(mean_fpr, mean_tpr)
    >>> plt.plot(mean_fpr, mean_tpr, 'k--',
    ...          label='Mean ROC (area = %0.2f)' % mean_auc, lw=2)
    >>> plt.plot([0, 0, 1],
    ...          [0, 1, 1],
    ...          linestyle=':',
    ...          color='black',
    ...          label='Perfect performance')
    >>> plt.xlim([-0.05, 1.05])
    >>> plt.ylim([-0.05, 1.05])
    >>> plt.xlabel('False positive rate')
    >>> plt.ylabel('True positive rate')
    >>> plt.legend(loc='lower right')
    >>> plt.tight_layout()
    >>> plt.show()
    신간 소식 구독하기
    뉴스레터에 가입하시고 이메일로 신간 소식을 받아 보세요.