과적합(Overfitting)은 머신 러닝에서 모델이 훈련 데이터에 너무 맞춰져서, 새로운 데이터에 대한 일반화 성능이 떨어지는 현상을 의미한다. 이는 모델이 훈련 데이터에는 매우 높은 성능을 보이지만, 새로운 데이터에 대해서는 제대로 작동하지 않는 경우를 말한다.
실제 데이터에서 결정계수가 1인 경우는 드문 경우인데, 결정계수가 1이라고 해서 너무 잘만든 모델이라고 하기보다는 과적합이라고 판단할 수 있다.
test, train split 코드 예제
from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(iris.data, iris.target, test_size=0.3, random_state=121) dt_clf.fit(x_train, y_train) # train으로 학습 pred2 = dt_clf.predict(x_test) # test로 검증 print('예측값 : ',pred2[:10]) print('실제값 : ',y_test[:10]) print('분류 정확도 : ', accuracy_score(y_test, pred2))
코드 리뷰
sklearn 라이브러리의train_test_split
를 사용해 데이터를 나눌 수 있다.test_size=0.3
은 test를 30%f로 나눈다는 뜻이다. train_size로 적어도 상관없다. random_state는 seed 넘버처럼 값을 고정해서 항상 똑같이 나누기 위해 사용한다. 보통 아직 모델을 만드는 단계일 때 많이 사용한다.
그렇게 하면 정확도가 1이었던 과적합 모델을 정확도가 0.9555555555555556인 포용성이 있는 모델로 만들 수 있다.
교차검증은 한 번의 모델 학습에만 의존하는 것보다 데이터를 여러 번 반복해서 나누고 여러 모델을 학습하여 평균 성능을 확인함으로써 모델의 성능을 더 정확하게 예측할 수 있다. 언뜻 보면 test, train split과 비슷해 보이지만 명백한 차이점이 존재한다. test, train split은 test와 train 데이터, 두 가지 데이터로 나누지만, 교차검증은 설정한 K개 만큼 데이터를 나눈다. 보통 test, train split을 수행한후 그래도 과적합이라면 교차검증을 사용한다.
교차검증 중 하나인 K-Fold는 다음과 같은 방법으로 수행된다.
K-Fold 코드 예제
from sklearn.model_selection import cross_val_score data = iris.data label = iris.target score = cross_val_score(dt_clf, data, label, scoring='accuracy', cv=5) print('교차 검증별 정확도 : ',np.round(score, 3)) print('모델 생성 도중 평균 검증 정확도 : ', np.round(np.mean(score),3)) # 0.96
코드 리뷰
sklearn이 KFold를 내부적으로 지원하기 때문에 이것을 사용하면 된다.
1.cross_val_score
함수를 사용하여 교차 검증을 수행하고 있다.
2.cross_val_score
함수에 사용되는 인자들:
dt_clf
: 결정 트리 모델data
: 입력 데이터 (iris 데이터셋의 특성)label
: 출력 데이터 (iris 데이터셋의 타겟)scoring='accuracy'
: 평가 지표로 정확도를 사용함을 지정cv=5
: 반복 횟수
cross_val_score
는 각 폴드에 대한 정확도를 리스트 형태로 반환하며, 이를score
변수에 저장한다.np.mean(score)
를 사용하여 모든 폴드에서 얻은 정확도의 평균을 계산하고, 모델의 최종 평균 검증 정확도를 출력한다.
참고로 StratifiedKFold는 불균형한 분포를 가진 레이블 데이터인 경우에 사용된다. 예를 들면 대출사기는 대부분 정상이고 극히 일부만 사기를 당하기 때문에 사기를 당하는 쪽의 데이터가 압도적으로 적기 때문에 불균형한 분포를 이룰 것이다. 이럴 때 사용하는 것이바로 StratifiedKFold이다.
GridSearchCV
는 scikit-learn 라이브러리에서 제공하는 기능 중 하나이다. 이는 모델의 하이퍼파라미터를 최적화하기 위해 사용되는 도구 중 하나로, 가능한 모든 하이퍼파라미터 조합을 시도해보고 가장 좋은 조합을 찾는 데에 쓰인다.
일반적으로 머신 러닝 모델에는 여러 가지 하이퍼파라미터(예: 트리의 깊이, 학습 속도 등)가 있다. 이들 하이퍼파라미터는 모델의 학습 및 성능에 영향을 미친다. GridSearchCV는 사용자가 지정한 하이퍼파라미터의 모든 가능한 조합을 탐색하고, 이를 통해 가장 우수한 성능을 보이는 하이퍼파라미터 조합을 찾을 수 있도록 도와준다.
GridSearchCV 코드 예제
from sklearn.model_selection import GridSearchCV from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import make_classification # 데이터 생성 (임의의 데이터) X, y = make_classification(n_samples=1000, n_features=10) # 모델 정의 model = RandomForestClassifier() # 탐색할 하이퍼파라미터 설정 param_grid = { 'n_estimators': [100, 200, 300], 'max_depth': [None, 5, 10, 15] } # GridSearchCV를 사용하여 최적의 하이퍼파라미터 찾기 grid_search = GridSearchCV(estimator=model, param_grid=param_grid, cv=5) grid_search.fit(X, y) # 최적의 하이퍼파라미터 출력 print(grid_search.best_params_)
이 예제에서는 RandomForestClassifier 모델을 사용하며,
n_estimators
와max_depth
두 개의 하이퍼파라미터를 대상으로 GridSearchCV를 실행한다. 이를 통해 데이터에 가장 적합한 하이퍼파라미터 조합을 찾아낸다.
과적합을 방지하는 방법은 위에서 언급한 방법만 있는 것말고도 많다. 또한, 꼭 하나의 과적합 방지 방법을 쓰는 것이 아니라 여러가지 같이 사용도 가능하다. 예를 들면, 각 값에 L1이나 L2 규제를 사용하고 교차검증을 하는 등 여러가지의 방법이 있다. 정답이 있는 수학문제 같은 것이 아니라 최적의 방법을 찾아가는 길이라고 생각하면 좋을 것 같다.
과적합은 머신 러닝 모델에서 흔히 발생하는 문제 중 하나이며, 데이터의 특성과 모델의 구조를 고려하여 이를 방지하는 것이 중요하다.