TOP
class="layout-aside-left paging-number">
본문 바로가기
[파이썬 Projects]/<파이썬 머신 | 딥러닝 & AI>

[파이썬] 사이킷런의 model_selection 모듈

by 기록자_Recordian 2024. 6. 7.
728x90
반응형
시작에 앞서
해당 내용은 '<파이썬 머신러닝 완벽 가이드> 권철민 지음. 위키북스' 를 토대로 작성되었습니다. 보다 자세한 내용은 해당 서적에 상세히 나와있으니 서적을 참고해 주시기 바랍니다.

네이버 도서

책으로 만나는 새로운 세상

search.shopping.naver.com


 Model Selection 모듈 소개

 
사이킷런의 model_selection 모듈은 학습 데이터와 테스트 데이터 세트를 분리하거나 교차 검증 분할 및 평가, 그리고 Estimator의 하이퍼 파라미터 (초매개변수)를 튜닝하기 위한 다양한 함수와 클래스를 제공한다.
 
model_selection 모듈은 머신러닝 모델을 만들 때, 데이터를 효율적으로 나누고 평가하기 위해 사용되는 Python의 scikit-learn 라이브러리의 일부이며, 이 모듈은 다음과 같은 주요 기능을 제공한다.

1. 데이터 분할 (Train-Test Split): 데이터를 학습용(train)과 테스트용(test)으로 나누어 모델의 성능을 평가할 수 있게 한다.
2. 교차 검증 (Cross-Validation): 데이터를 여러 번 나누어 모델을 반복적으로 학습하고 평가하여, 모델의 일반화 성능을 높일 수 있다.
3. 하이퍼파라미터 튜닝 (Hyperparameter Tuning): GridSearchCV나 RandomizedSearchCV와 같은 방법을 사용하여 모델의 최적의 하이퍼파라미터를 찾을 수 있다.

 
이 모듈을 사용하면 데이터 과학자와 머신러닝 엔지니어가 모델의 성능을 더 정확하게 평가하고 개선할 수 있다.


train_test_split( ): 학습/테스트 데이터 세트 분리

 
사이킷런의 train_test_split( )를 통해 원본 데이터 세트에서 학습 및 테스트 데이터 세트를 쉽게 분리할 수 있다.
 
먼저 sklearn.model_selection 모듈에서 train_test_split을 로드하고,
train_test_split( )는 첫 번째 파라미터로 피처 데이터 세트, 두 번째 파라미터로 레이블 데이터 세트를 입력받는다.

 
그리고 선택적으로 아래와 같은 파라미터를 입력 받는다.

  • test_size: 전체 데이터에서 테스트 데이터 세트 크기를 얼마로 샘플링할 것인가를 결정. (디폴트는 0.25=25%)
  • train_size: 전체 데이터에서 학습용 데이터 세트 크기를 얼마로 샘플링할 것인가를 결정 (test_size parameter를 통상적으로 사용하기 때문에 잘 사용되지 않음)
  • shuffle: 데이터를 분리하기 전에 데이터를 미리 섞을지 결정. (디폴트는 True) 데이터를 분산시켜서 좀 더 효율적인 학습 및 테스트 데이터 세트를 만드는 데 사용
  • random_state: 호출할 때마다 동일한 학습/테스트 용 데이터 세트를 생성하기 위해 주어지는 난수 값. (지정하지 않을 시 수행 시마다 다른 학습/테스트 용 데이터 생성)
  • train_test_split( )의 반환값은 튜플 형태. (순차적으로 학습용 데이터 - 피처 데이터 세트, 테스트용 데이터 - 피처 데이터 세트, 학습용 데이터 - 레이블 데이터 세트, 테스트용 데이터 - 레이블 데이터 세트 반환)

붓꽃 데이터 세트를 train_test_split( )를 이용해 테스트 데이터 세트를 전체의 30%로, 학습 데이터 세트를 70%로 분리한 뒤,
학습 데이터를 기반으로 DecisionTreeClassifier 를 학습하고 이 모델을 이용해 예측 정확도를 측정하면

정확도가 약 95.56% 나온다. 
 
만약 테스트 데이터 세트를 이용하지 않고 학습 데이터 세트로만 학습하면

정확도가 100%가 나온다. 위는 이미 학습한 학습 데이터 세트를 기반으로 에측했기 때문인데, 즉 모의고사와 똑같은 기출문제로 본고사 문제가 출제됐다고 보면 된다.
따라서 예측을 수행하는 데이터 세트는 학습을 수행한 학습용 데이터 세트가 아닌 테스트 데이터 세트여야 한다.
하지만 이 방법은 과적합(Overfitting)에 취약한 약점을 가질 수 있다.
 
※ 과적합(Overfitting): 모델이 학습 데이터에만 과도하게 최적화되어, 실제 예측을 다른 데이터로 수행할 경우 예측 성능이 과도하게 떨어지는 것.


교차 검증

 
앞서 train_test_split( )를 통한 데이터 분할은 과적합에 취약할 수 있다고 했는데, 이는 고정된 학습 데이터와 테스트 데이터로 평가를 하다 보면 테스트 데이터에만 최적의 성능을 발휘할 수 있도록 편향되게 모델을 유도하는 경향이 생기게 되고, 결국엔 해당 테스트 데이터에만 과적합되는 학습 모델이 만들어지는 것을 말한다.
 
이러한 문제점을 개선하기 위해 교차 검증을 이용한 다양한 학습과 평가를 수행한다.
교차 검증이란,
데이터의 편중을 막기 위해서 별도의 여러 세트로 구성된 학습 데이터 세트와 검증 데이터 세트에서 학습과 평가를 수행하는 것이며, 각 세트에서 수행한 평가 결과에 따라 초매개변수 튜닝 등의 모델 최적화를 손쉽게 할 수 있다.
 
머신러닝에 사용되는 데이터 세트를 세분화하고 테스트 데이터 세트 외에 별도의 검증 데이터 세트를 둬서 최종 평가 이전에 학습된 모델을 다양하게 평가하는 데 사용한다.
 
◆ k 폴드 교차 검증
k개의 데이터 폴드 세트를 만들어서 k번만큼 각 폴드 세트에 학습과 검증 평가를 반복적으로 수행하는 방법을 말하는데, 이 기법은 가장 보편적으로 사용되는 교차 검증 기법이다.
사이킷런에서는 K폴드 교차 검증 프로세스를 구현하기 위해 KFold와 StratifiedKFold 클래스를 제공한다.
 
[KFold 클래스를 이용해 붓꽃 데이터 세트를 교차 검증하고 예측 정확도 알아보기]
1. 붓꽃 데이터 세트와 DecisionTreeClassifier를 생성하고 5개의 폴드 세트로 분리하는 KFold 객체 셍성

전체 붓꽃 데이터는 모두 150개

 
2. 생성된 KFold(n_splits=5) 객체의 split( )을 호출해 전체 붓꽃 데이터를 5개의 폴드 데이터 세트로 분리
(학습용; 4/5=120개, 검증용: 1/5=30개로 분할)

 
◆ Stratified K 폴드
Stratified K 폴드는 불균형한 분포도를 가진 레이블 데이터 집합을 위한 K 폴드 방식이다.
불균형한 분포도를 가진 레이블 데이터 집합은 특정 레이블 값이 특이하게 많거나 매우 적어서 값의 분포가 한쪽으로 치우치는 것을 말한다.
 
Stratified K 폴드는 K 폴드가 레이블 데이터 집합이 원본 데이터 집합의 레이블분포를 학습 및 테스트 세트에 제대로 분배하지 못하는 경우의 문제를 해결해 준다.
이를 위해 원본 데이터의 레이블 분포를 먼저 고려한 뒤 이 분포와 동일하게 학습과 검증 데이터 세트를 분배한다.
 
[K 폴드의 문제 확인]
1. 붓꽃 데이터 세트를 간단하게 DataFrame으로 생성하고 레이블 값의 분포도 확인

품종(레이블 값)이 모두 50개로 동일하다

2. 이슈가 발생하는 현상을 도출하기 위해 3개의 폴드 세트를 KFold로 생성하고, 각 교차 검증 시마다 생성되는 학습/검증 레이블 데이터 값의 분포도 확인

 
▶ 교차 검증 시마다 3개의 폴드 세트로 만들어지는 학습 레이블과 검증 레이블이 완전히 다른 값으로 추출.
▶ 학습 레이블은 1, 2 밖에 없으므로 0의 경우는 전혀 학습하지 못함
▶ 검증 레이블은 0 밖에 없으므로 학습 모델은 절대 0을 예측하지 못함
▶ 위의 유형으로 교차 검증 데이터 세트를 분할하면 검증 예측 정확도는 0이 됨
 
[Stratified K 폴드로 개선하기]
Stratified K 폴드는 KFold로 분할된 레이블 데이터 세트가 전체 레이블 값의 분포도를 반영하지 못하는 문제를 해결해준다.
Stratified K 폴드를 사용하는 방식은 KFold를 사용하는 방법과 비슷하나, 큰 차이는 Stratified K 폴드는 레이블 데이터 분포도에 따라 학습/검증 데이터를 나누기 때문에 split( ) 메서드에 인자로 피처 데이터 세트뿐만 아니라 레이블 데이터 세트도 반드시 필요하다. (KFold의 경우 레이블 데이터 세트는 split( ) 메서드의 인자로 입력하지 않아도 무방)

▶ 학습 레이블과 검증 레이블 데이터 값의 분포도가 거의 동일하게 할당되었다.
(전체 데이터 150개 - 학습: 100개 / 검증: 50개)
 
[StratifiedKFold 를 이용해 붓꽃 데이터 교차 검증하기]

▶ 3개의 Stratified K 폴드로 교차 검증한 결과 평균 검증 정확도가 약 96.67%로 측정

1. 왜곡된 레이블 데이터 세트에서는 반드시 Stratified K 폴드를 이용해 교차 검증
2. 분류(Classfication)에서의 교차 검증 시 Stratified K 폴드로 분할
3. 회귀(Regression) 에서는 Stratified K 폴드 미지원

cross_val_score( ): 교차 검증을 좀 더 편리하게 수행

 
KFold로 데이터를 학습하는 과정
폴드 세트 설정 → for 루프에서 반복으로 학습 및 테스트 데이터 인덱스 추출 → 반복적으로 학습과 에측 수행하고 예측 성능 반환
 
그러나 cross_val_score( )는 이런 일련의 과정을 한꺼번에 수행해준다.
 
[cross_val_score( ) API의 선언 형태]

cross_val_score(estimator, X, y=None, scoring=None, cv=None, n_jobs=1, verbose=0, fit_params=None, pre_dispatch='2*n_jobs')

▶ estimator: 사이킷런의 분류 알고리즘 클래스인 Classifier 또는 회귀 알고리즘 클래스인 Regressor
▶ X: 피처 데이터 세트
▶ y: 레이블 데이터 세트
▶ scoring: 에측 성능 평가 지표
▶ cv: 교차 검증 폴드 수
 
- 수행 후 반환 값은 scoring 파라미터로 지정된 성능 지표 측정값을 배열 형태로 반환.
- classfier가 입력되면 Stratified K 폴드 방식으로 레이블값의 분포에 따라 학습/테스트 세트 분할(회귀인 경우 K 폴드 방식)

※ cross_val_score( ) API는 내부에서 Estimator를 학습(fit), 예측(predict), 평가(evaluation) 시켜주므로 간단하게 교차 검증 수행 가능. (이는 Stratified K Fold를 내부적으로 이용하기 때문)
 
※ cross_validate( ): cross_val_score( )는 단 하나의 평가 지표만 가능하지만 cross_validate( )는 여러 개의 평가 지표를 반환할 수 있고, 학습 데이터에 대한 성능 평가 지표와 수행 시간도 같이 제공한다.


GridSearchCV: 교차 검증과 최적 하이퍼 파라미터 튜닝을 한 번에

 
하이퍼 파라미터는 머신러닝 알고리즘을 구성하는 주요 구성 요소 이며, 이 값을 조정해 알고리즘의 예측 성능을 개선.
사이킷런은 GridSearchCV API 를 이용해 분류나 회귀와 같은 알고리즘에 사용되는 하이퍼 파라미터를 순차적으로 입력하면서 편리하게 최적의 파라미터를 도출할 수 있는 방안을 제공한다.
 
GridSearchCV는 교차 검증을 기반으로 데이터 세트를 cross_validation을 위한 학습/테스트 세트로 자동으로 분할한 뒤에 하이퍼 파라미터 그리드에 기술된 모든 파라미터를 순차적으로 적용해 최적의 파라미터를 찾을 수 있게 해준다.
(수행시간이 상대적으로 오래 걸린다.)

[GridSearchCV 클래스의 주요 파라미터]
  • estimator: classfier, regressor, pipeline 사용 가능
  • param_grid: key + 리스트 값을 가지는 딕셔너리가 주어짐. estimator의 튜닝을 위해 파라미터명과 사용될 여러 파라미터 값 지정
  • scoring: 예측 성능을 측정한 평가 방법 지정. (보통은 성능 평가 지표를 지정하는 문자열로 지정)
  • cv: 교차 검증을 위해 분할되는 학습/테스트 세트의 개수 지정
  • refit: True로 생성 시 가장 최적의 하이퍼 파라미터를 찾은 뒤 입력된 estimator 객체를 해당 하이퍼 파라미터로 재학습 시킴 (디폴트는 True)

 
[GridSearchCV API 사용법 익히기]

  • train_test_split( )을 이용해 데이터 분할
  • 학습 데이터에서 GridSearchCV를 이용해 최적 하이퍼 파라미터 추출
  • 결정 트리 알고리즘을 구현한 DecisionTreeClassifier의 중요 하이퍼 파라미터인 max_depth와 min_samples_split의 값을 변화시키면서 최적화 진행
  • 테스트 할 하이퍼 파라미터 세트는 딕셔너리 형태로 하이퍼 파라미터의 명칭은 문자열 key 값으로, 하이퍼 파라미터 값은 리스트 형으로 설정

 
[학습 데이터 세트를 GridSearchCV 객체의 fit 메서드 수행]

  • GridSearchCV 객체의 fit(학습 데이터 세트) 메서드를 수행하면 학습 데이터를 cv에 기술된 폴딩 세트로 분할해 param_grid에 기술된 하이퍼 파라미터를 순차적으로 변경하면서 학습/평가를 수행하고 그 결과를 cv_results_속성에 기록
  • cv_results_는 gridsearchcv의 결과 세트로서 딕셔너리 형태로 key 값과 리스트 형태의 value 값을 가짐
  • cv_results_를 DataFrame으로 변환
max_depth와 min_samples_split을 순차적으로 총 6번 변경하면서 학습 및 평가 수행

 
<칼럼별 설명>
▶ params: 수행할 때마다 적용된 개별 하이퍼 파라미터 값
▶ rank_test_score: 하이퍼 파라미터별로 성능이 좋은 score 순위 (1위 가장 뛰어난 순위 - 이때의 파리미터가 최적의 파라미터)
▶ mean_test_score: 개별 하이퍼 파라미터별로 CV의 폴딩 테스트 세트에 대해 총 수행한 평가 평균값
 
[최적 하이퍼 파라미터 값과 정확도 알아보기]
GridSearchCV 객체의 fit( )을 수행하면 최고 성능을 나타낸 하이퍼 파라미터의 값과 그때의 평가 결과 값이 각각 best_params_, best_score_ 속성에 기록된다. (=cv_results_의 rank_test_score가 1)

▶ max_depth가 3, min_samples_split이 2일 때 검증용 폴드 세트에서 평균 최고 정확도가 97.5%로 측정되었다.
▶ refit=Ture 이면 GridSearchCV가 최적 성능을 나타내는 하이퍼 파리미터로 Estimator를 학습해 best_estimator_로 저장
 
[학습된 best_estimator_를 이용한 예측 및 성능 평가]
이미 학습된 best_estimator_를 이용, 앞에서 train_test_split( )으로 분리한 테스트 데이터 세트에 대해 예측 및 성능 평가 수행

※ 일반적으로 학습 데이터를 GridSearchCV를 이용해 최적 파라미터 튜닝을 수행한 뒤에 별도의 테스트 세트에서 이를 평가하는 것이 일반적인 머신러닝 모델 적용 방법이다.

728x90
반응형