일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- 정보처리기사실기
- SQL
- 데이터분석
- 혼공머신
- 중학수학
- 연습문제
- c언어
- JDBC
- 데이터베이스
- 중학1-1
- 파이썬
- 자바스크립트심화
- 자바
- JSP/Servlet
- 컴퓨터구조
- CSS
- 디버깅
- 컴퓨터비전
- ChatGPT
- 개발일기
- 자바 실습
- 정보처리기사필기
- 자바스크립트
- 상속
- 순환신경망
- 딥러닝
- 머신러닝
- html/css
- JSP
- rnn
- Today
- Total
클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지
트리 알고리즘 3 - 교차 검증과 그리드 서치 1 : 교차 검증 및 그리스 서치와 랜덤 서치의 차이를 알고 최적의 성능을 내는 방법 본문
트리 알고리즘 3 - 교차 검증과 그리드 서치 1 : 교차 검증 및 그리스 서치와 랜덤 서치의 차이를 알고 최적의 성능을 내는 방법
huenuri 2024. 9. 30. 05:33오늘 새벽에 4시간 동안 두 단원의 학습을 모두 마칠 수 있을까? 최선을 다해 어제 저녁에 하지 못했던 공부를 만회하기로 했다. 오늘은 새벽에 운동을 하지 못할 것 같다.
학습 목표
검증 세트가 필요한 이유를 이해하고 교차 검증에 대해 배운다. 그리드 서치와 랜덤 서치를 이용해 최적의 성능을 내는 하이퍼라라미터를 찾는다.
시작하기 전에
지금까지 우리는 훈련 세트에서 모델을 훈련하고 테스트 세트에서 모델을 평가했다. 그런데 테스트 세트를 사용해 자꾸 성능을 검증하다 보면 점점 테스트 세트에 맞춰지게 된다. 이전까지는 문제를 간단히 하려고 테스트 세트를 사용했다. 하지만 테스트 세트로 일반화 성능을 올바르게 예측하려면 가능한 한 테스트 세트를 사용하지 말아야 한다. 모델을 만들고 나서 마지막에 딱 한 번만 사용하는 것이 좋다. 그렇다면 max_depth 매개변수를 사용한 하이퍼파라미터 튜닝을 어떻게 할 수 있을까? 게다가 결정 트리는 테스트해 볼 매개변수가 많다.
검증 세트
테스트 세트를 사용하지 않으면 모델이 과대적합인지 과소적합인지 판다하기 어렵다. 검증 세트는 테스트 세트를 사용하지 않고 이를 측정하는 훈련 세트를 또 나누는 것을 말한다. 앞에서 우리는 전체 데이터 중 20%를 테스트 세트로 만들고 나머지 80%를 훈련 세트로 만들었다. 이 훈련 세트 중에서 다시 20%를 떼어 내어 검증 세트로 만든다.
훈련 세트에서 모델을 훈련하고 검증 세트로 모델을 평가한다. 이런 식으로 테스트하고 싶은 매개변수를 바꿔가며 가장 좋은 모델을 고른다. 그다음 이 매개변수를 사용해 훈련 세트와 검증 세트를 합쳐 전체 훈련 데이터에서 모델을 다시 훈련한다. 그리고 마지막에 테스트 세트에서 최종 점수를 평가한다. 이제 테스트 세트의 점수와 비슷한 성능을 기대할 수 있을 것이다.
먼저 판다스로 CSV 데이터를 읽는다. 그다음 class 열을 타기으로 사용하고 나머지 열은 특성 배열에 저장한다. 이제 훈련 세트와 테스트 세트를 나누는데, 훈련 세트의 입력 테이터와 타깃 데이터를 train_input과 train_target에 저장한다.
그다음 이들을 train_test_split() 함수에 넣어 훈련 세트(sub)와 검증 세트(val)를 만든다.
훈련 세트와 검증 세트의 크기를 확인해보면 원래 5197개였던 훈련 세트가 4157개로 줄어들고, 검증 세트는 1040개가 되었다. 모델을 평가해 보면 확실히 훈련 세트에 과대적합되었음을 알 수 있다.
교차 검증
검증 세트를 만드느라 훈련 세트가 줄었다. 보통 많은 데이터를 훈련에 사용할수록 좋은 모델이 만들어진다. 그렇다고 검증 세트를 너무 조금 떼어 놓으면 검증 점수가 들쭉날쭉하고 불안정할 것이다. 이럴 때 교차 검증을 사용하면 안정적인 검증 점수를 얻고 훈련에 더 많은 데이터를 사용할 수 있다.
교차 검증은 검증 세트를 떼어 내어 평가하는 과정을 여러 번 반복한다. 그다음 이 점수를 평균하여 최종 검증 점수를 얻는다. 이 그림은 3-폴드 교차 검증이다. 훈련 세트를 세 부분으로 나눠서 교차 검증을 수행하는 것을 말한다.
보통 5-폴드 교차 검증이나 10-폴드 교차 검증을 많이 사용한다. 이렇게 하면 데이터의 80~90%까지 훈련에 사용할 수 있다. 검증 세트가 줄어들지만 각 폴드에서 계산한 검증 점수를 평균하기 때문에 안정된 점수로 생각할 수 있다.
사이킷런에는 cross_validate()라는 교차 검증 함수가 있다. 먼저 평가할 모델 객체를 첫 번째 매개변수로 전달한다. 그다음 앞에서 직접 검증 세트를 떼어내지 않고 훈련 세트 전체를 cross_validate() 함수에 전달한다. 이 함수는 fit_time, score_time, test_score 키를 가진 딕셔너리를 반환한다. 처음 2개의 키는 각각 모델을 훈련하는 시간과 검증하는 시간을 의미한다. 각 키마다 5개의 숫자가 담겨있다. cross_validate() 함수는 기본적으로 5-폴드 교차 검증을 수행한다.
교차 검증의 최종 점수는 test_score 키에 담긴 5개의 점수를 평균하여 얻을 수 있다. 이름은 test_score지만 검증 폴드의 점수이다.
교차 검증을 수행하면 입력한 모델에서 얻을 수 있는 최상의 점수를 가늠해 볼 수 있다. 한 가지 주의할 점은 cross_validate()는 훈련 세트를 섞어 폴드를 나누지 않는다. 앞서 우리는 train_test_split() 함수로 전체 데이터를 섞은 후 훈련 세트를 준비했기 때문에 따로 섞을 필요가 없다. 만약 교차 검증을 할 때 훈련 세트를 섞으면 분할기를 지정해야 한다.
사이킷런의 분할기는 교차 검증에서 폴드를 어떻게 나눌지 결정해 준다.
cross_validate() 함수는 기본적으로 회귀모델일 경우 KFold 분할기를 사용하고 분류 모델일 경우 타깃 클래스를 골고루 나누기 위해 StratifiedKFold를 사용한다.
이어서 결정 트리의 매개변수 값을 바꿔가며 가장 좋은 성능이 나오는 모델을 찾아보겠다. 이때 테스트 세트를 사용하지 않고 교차 검증을 통해서 좋은 모델을 고르면 된다.
하이퍼파라미터 튜닝
하이퍼파라미터를 튜닝하는 작업은 어떻게 진행할까? 먼저 라이브러리가 제공하는 기본값을 그대로 사용해 모델을 훈련한다. 그다음 검증 세트의 점수나 교차 검증을 통해서 매개변수를 조금씩 바꿔본다. 모델마다 적게는 1~2개에서 많게는 5~6개의 매개변수를 제공한다. 이 매개변수를 바꿔가면서 모델을 훈련하고 교차 검증을 수행한다.
여기서 중요한 점이 있다. 가령 결정 트리 모델에서 최적의 max_depth 값을 찾았다고 가정해 보자. 그다음 max_depth를 최적의 값으로 고정하고 min_sample_split을 바꿔가며 최적의 값을 찾는다. 이렇게 한 매개변수의 최적값을 찾고 다른 매개변수의 최적값을 찾아도 될까?
max_depth의 최적값은 min_sample_split 매개변수의 값이 바뀌면 함께 달라진다. 즉 이 두 매개변수를 동시에 바꿔가며 최적의 값을 찾아야 한다.
게다가 매개변수가 많아지면 문제는 더 복잡해진다. 사이킷런에서는 그리드 서치를 사용해 이 방법을 좀 더 편리하게 한다. 사이킷런의 GridSearchCV 클래스는 하이퍼파라미터 탐색과 교차 검증을 한 번에 수행한다. 별도로 cross_validate() 함수를 호출할 필요가 없다. 사용방법은 다음과 같다. 먼저 GridSearchCV 클래스를 임포트하고 탐색할 매개변수와 탐색할 값의 리스트를 딕셔너리로 만든다.
GridSearchCV 클래스에 탐색 대상 모델과 params 변수를 전달하여 그리드 서치 객체를 만든다. 갤정 트리 클래스의 객체를 생성하자마자 바로 전달했다. 그다음 일반 모델을 훈련하는 것처럼 gs 객체에 fit() 메서드를 호출한다. 이 메서드를 호출하면 그리드 서치 객체는 결정 트리 모델 min_imurity_decrese 값을 바꿔가며 총 5번 실행한다.
GridSearchCV의 cv 매개변수 기본값은 5이다. 따라서 min_imurity_decrese 값마다 5-폴드 교차 검증을 수행한다. 결국 5 x 5 = 25개의 모델을 훈련한다. 많은 모델을 훈련하기 때문에 GridSearchCV 클래스의 n_jobs 매개변수에서 병렬 실행에 사용할 CPU 코어 수를 지정하는 것이 좋다.
사이킷런의 그리드 서치는 훈련이 끝나면 25개의 모델 중에서 검증 점수가 가장 높은 모델의 매개변수 조합으로 전체 훈련 세트에서 자동으로 다시 모델을 훈련한다. 이 모델은 gs 객체의 best_estimator_ 속성에 저장되어 있다.
여기서는 0.0001이 가장 좋은 값으로 선택되었다. 5번 교차검증으로 얻은 점수를 출력해 보았다. 수동으로 고르는 것보다 넘파이 argmax() 함수를 사용하면 가장 큰 값의 인덱스를 추출할 수 있다. 그다음 이 인덱스를 사용해 params 키에 저장된 매개변수를 출력할 수 있다. 이 과정을 정리해 보면 다음과 같다.
- 먼저 탐색할 매개변수를 지정한다.
- 훈련 세트에서 그리드 서치를 수행하여 최상의 평균 검증 점수가 나오는 매개변수 조합을 찾는다. 이 조합은 그리드 서치 객체에 저장된다.
- 그리드 서치는 최상의 매개변수(교차 검증에 사용한 훈련 세트가 아니라) 전체 훈련 세트를 사용해 최종 모델을 훈련한다. 이 모델도 그리드 서치 객체에 저장된다.
마지막 코드는 결정 트리에서 min_impurity_decrease로 노드를 분할하기 위한 불순도 감소 최소량을 지정한다. 이 부분은 너무 어려워서 건너뛰려고 한다.
랜덤 서치
매개변수의 값이 수치일 때 값의 범위나 간격을 미리 정하기 어려울 수도 있다. 또 너무 많은 매개 변수 조건이 있어 그리드 서치 수행 시간이 오래 걸릴 수 있다. 이럴 때 랜덤 서치를 사용하면 좋다.
랜덤 서치에는 매개변수 값의 목록을 전달하는 것이 아니라 매개변수를 샘플링할 수 있는 확률 분포 객체를 전달한다. 먼저 싸이파이의 stats 서프 패키지에 있는 uniform과 randint 클래스는 주어진 범위에서 고르도록 값을 뽑는다. 이를 '균등 분포에서 샘플링한다'라고 말한다. randint는 정수값을 뽑고, uniform은 실수값을 뽑는다.
이런저런 설명이 있지만 너무 복잡한 관계로 생략하고 샘플링 횟수를 사이킷런의 랜덤 서치 클래스인 RandomizedSearchCV의 n_iter 매개변수에 저장한다. 그리고 params에 정의된 매개변수 범위에서 총 100번을 샘플링하여 교차 검증을 수행하고 최적의 매개변수 조합을 찾는다. 그리드 서치보다 훨씬 교차 검증수를 줄이면서 넓은 영역을 효과적으로 탐색할 수 있다.
결과를 확인해보면 최적의 모델은 이미 훈련 세트로 훈련되어 best_estimator_ 속성에 저장되어 있다. 이 모델을 최종 모델로 결정하고 테스트 세트의 성능을 확인해 보자.
테스트 세트 점수는 검증 세트에 대한 점수보다 조금 작은 것이 일반적이다.
학습을 마치고
이것으로 교차 검증에 대한 학습을 마친다. 정말 중요한 내용 위주로 초고속으로 학습을 진행했다. 이렇게 학습을 해도 어느 정도 이해가 되고, 자세히 모든 내용을 다 알 필요가 없다는 것도 알게 되었다. 그래야 나중에 다 잊어버리니 지금은 개관을 익힌다 생각하고 가볍게 학습을 진행하기로 했다.
'인공지능 > 머신러닝' 카테고리의 다른 글
트리 알고리즘 5 - 트리의 앙상블 1 : 트리 앙상블의 한 종류인 랜덤 포레스트, 엑스트라 트리, 그라이디언트 부스팅 등에 대하여 (0) | 2024.09.30 |
---|---|
트리 알고리즘 4 - 교차 검증과 그리드 서치 2 : 스스로 실습하고 문제를 풀어보는 시간 (0) | 2024.09.30 |
트리 알고리즘 2 - 결정 트리 2 : 스스로 실습하고 문제 풀어보는 시간 (0) | 2024.09.29 |
트리 알고리즘 1 - 결정 트리 1 : 결정 트리 알고리즘으로 레드 와인과 화이트 와인 분류하기 (0) | 2024.09.29 |
다양한 분류 알고리즘 4 - 확률적 경사 하강법 2 : 스스로 실습하고 문제 풀어보는 시간 (0) | 2024.09.29 |