그리드 검색을 이용한 숫자 이미지 분류

Beginner

This tutorial is from open-source community. Access the source code

소개

이 실습에서는 scikit-learn 라이브러리를 사용하여 교차 검증을 통한 하이퍼파라미터 튜닝 방법을 보여줍니다. 이 예제는 손글씨 숫자 이미지를 이진 분류 (숫자가 8 인지 아닌지 식별) 하여 이해하기 쉽게 설계되었습니다. 사용된 데이터셋은 digits 데이터셋입니다. 선택된 하이퍼파라미터와 학습된 모델의 성능은 모델 선택 단계에서 사용되지 않은 전용 평가 데이터셋으로 측정됩니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단 모서리를 클릭하여 Notebook 탭으로 전환하여 연습을 위한 Jupyter Notebook에 접근합니다.

때때로 Jupyter Notebook 이 완전히 로드되기까지 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한으로 인해 작업 검증은 자동화될 수 없습니다.

학습 중 문제가 발생하면 Labby 에게 문의하십시오. 세션 후 피드백을 제공하면 문제를 신속하게 해결해 드리겠습니다.

데이터 로드

digits 데이터셋을 로드하고 이미지를 벡터로 평탄화합니다. 각 8x8 픽셀 이미지는 64 픽셀 벡터로 변환되어야 합니다. 따라서 최종 데이터 배열의 형태는 (n_images, n_pixels)가 됩니다. 또한 데이터를 동일한 크기의 학습 및 테스트 세트로 분할합니다.

from sklearn import datasets
from sklearn.model_selection import train_test_split

digits = datasets.load_digits()

n_samples = len(digits.images)
X = digits.images.reshape((n_samples, -1))
y = digits.target == 8

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.5, random_state=0)

그리드 검색 전략 정의

GridSearchCV 인스턴스의 refit 매개변수에 전달될 함수를 정의합니다. 이 함수는 GridSearchCVcv_results_ 속성에서 최상의 후보를 선택하는 사용자 정의 전략을 구현합니다. 후보가 선택되면 GridSearchCV 인스턴스가 자동으로 재학습합니다.

여기서 전략은 정밀도와 재현율 측면에서 최상의 모델을 짧은 목록으로 만드는 것입니다. 선택된 모델 중에서 예측 속도가 가장 빠른 모델을 최종적으로 선택합니다. 이러한 사용자 정의 선택은 완전히 임의적임을 유의하십시오.

import pandas as pd
from sklearn.metrics import classification_report

def print_dataframe(filtered_cv_results):
    """필터링된 데이터프레임을 보기 좋게 출력합니다."""
    for mean_precision, std_precision, mean_recall, std_recall, params in zip(
        filtered_cv_results["mean_test_precision"],
        filtered_cv_results["std_test_precision"],
        filtered_cv_results["mean_test_recall"],
        filtered_cv_results["std_test_recall"],
        filtered_cv_results["params"],
    ):
        print(
            f"정밀도: {mean_precision:0.3f} (±{std_precision:0.03f}),"
            f" 재현율: {mean_recall:0.3f} (±{std_recall:0.03f}),"
            f" 파라미터: {params}"
        )
    print()


def refit_strategy(cv_results):
    """최상의 추정자를 선택하는 전략을 정의합니다.

    여기서 정의된 전략은 정밀도 임계값 0.98 미만의 모든 결과를 필터링하고, 나머지를 재현율 기준으로 순위를 매기고, 최상의 재현율 모델의 표준 편차 내에 있는 모든 모델을 유지하는 것입니다. 이러한 모델이 선택되면 예측 속도가 가장 빠른 모델을 선택할 수 있습니다.

    매개변수
    ----------
    cv_results : numpy (마스크) ndarrays 의 사전
        `GridSearchCV` 에 의해 반환된 CV 결과.

    반환값
    -------
    best_index : int
        `cv_results` 에 나타나는 최상의 추정자의 인덱스.
    """
    ## 다양한 점수에 대한 그리드 검색 정보를 출력합니다.
    precision_threshold = 0.98

    cv_results_ = pd.DataFrame(cv_results)
    print("모든 그리드 검색 결과:")
    print_dataframe(cv_results_)

    ## 임계값 미만의 모든 결과를 필터링합니다.
    high_precision_cv_results = cv_results_[
        cv_results_["mean_test_precision"] > precision_threshold
    ]

    print(f"정밀도가 {precision_threshold}보다 높은 모델:")
    print_dataframe(high_precision_cv_results)

    ## 재현율 측면에서 가장 성능이 좋은 모델을 선택합니다.
    ## (최상의 모델로부터 1 시그마 내에 있는 모델)
    best_recall_std = high_precision_cv_results["mean_test_recall"].std()
    best_recall = high_precision_cv_results["mean_test_recall"].max()
    best_recall_threshold = best_recall - best_recall_std

    high_recall_cv_results = high_precision_cv_results[
        high_precision_cv_results["mean_test_recall"] > best_recall_threshold
    ]
    print(
        "이전에 선택된 높은 정밀도 모델 중에서,\n"
        "최고 재현율 모델의 표준 편차 내에 있는 모든 모델을 유지합니다:"
    )
    print_dataframe(high_recall_cv_results)

    ## 최상의 후보 중에서 예측 속도가 가장 빠른 모델을 선택합니다.
    fastest_top_recall_high_precision_index = high_recall_cv_results[
        "mean_score_time"
    ].idxmin()

    print(
        "\n선택된 최종 모델은 정밀도와 재현율 기준으로 이전에 선택된 최상의 모델 집합 중 예측 속도가 가장 빠른 모델입니다.\n"
        "그 실행 시간은 다음과 같습니다:\n\n"
        f"{high_recall_cv_results.loc[fastest_top_recall_high_precision_index]}"
    )

    return fastest_top_recall_high_precision_index

하이퍼파라미터 정의

하이퍼파라미터를 정의하고 GridSearchCV 인스턴스를 생성합니다.

from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC

tuned_parameters = [
    {"kernel": ["rbf"], "gamma": [1e-3, 1e-4], "C": [1, 10, 100, 1000]},
    {"kernel": ["linear"], "C": [1, 10, 100, 1000]},
]

grid_search = GridSearchCV(
    SVC(), tuned_parameters, scoring=["precision", "recall"], refit=refit_strategy
)

모델 학습 및 예측 수행

모델을 학습하고 평가 데이터 세트에 대한 예측을 수행합니다.

grid_search.fit(X_train, y_train)

## 사용자 정의 전략으로 그리드 검색에서 선택된 파라미터는 다음과 같습니다:
grid_search.best_params_

## 마지막으로, 미세 조정된 모델을 남겨진 평가 데이터 세트에서 평가합니다.
## `grid_search` 객체는 사용자 정의 재학습 전략으로 선택된 파라미터를 사용하여 **전체 학습 데이터 세트에서 자동으로 재학습되었습니다**.
y_pred = grid_search.predict(X_test)
print(classification_report(y_test, y_pred))

요약

이 실습에서는 scikit-learn 라이브러리를 사용하여 교차 검증을 통해 하이퍼파라미터 튜닝을 수행하는 방법을 배웠습니다. digits 데이터 세트를 사용했으며, GridSearchCV 인스턴스의 cv_results_ 속성에서 최상의 후보를 선택하기 위한 사용자 정의 재학습 전략을 정의했습니다. 마지막으로, 미세 조정된 모델을 남겨진 평가 데이터 세트에서 평가했습니다.