일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 태블로
- lambda
- streamlit
- If
- 서브쿼리
- 데이터 분석
- 팀프로젝트
- 전처리
- data analyst
- pandas
- 시각화
- 히트맵
- 기초통계
- 프로젝트
- 기초프로젝트
- 크롤링
- 프롬프트 엔지니어링
- cross join
- 군집화
- Python
- SQL
- da
- 클러스터링
- Chat GPT
- 최종 프로젝트
- 머신러닝
- 데이터분석
- SQLD
- jd
- GA4
- Today
- Total
세조목
머신러닝 심화 복습(교차검증(K-Fold, StratifiedKFold))(24.05.10) 본문
머신러닝을 할 때 하나의 데이터셋을 train, test 데이터셋으로 나누는데
7:3 내지 8:2로 나누는 것이 일반적이다.
train 데이터셋으로 학습을 시키고 이 모델을 test 데이터셋에 적용시켜보는 것이다.
그런데 만약 train 데이터셋에 포함된 데이터의 개수가 충분하지 않다면 과적합이 발생하지 않을까?
이 때 필요한 것이 '교차 검증(Cross Validation)'이다.
교차 검증이란 train 데이터셋에 포함된 데이터셋을 n개로 split해서
모델을 학습시키고 모델을 최적화시키는 작업이다.
위 이미지에서의 경우 train dataset을 5개로 split 한 후 각각의 Fold를
학습용, 검증용으로 지정해서 모델을 학습시켜본다.
Fold1, 2, 3, 4, 5를 순서대로 검증용으로 지정하는 것이다.
학습 데이터와 검증 데이터 index를 나타낸건데
위 예시에서는 [0, 8, 13, ..., 876, 886, 887] index가 포함된 Fold가 검증용으로 지정된 경우다.
from sklearn.model_selection import KFold
import numpy as np
kfold = KFold(n_splits = 5, shuffle=True)
n_iter = 0
scores = []
X = train_df_2[['Age_mm_sc', 'Family_mm_sc', 'Fare_sd_sc', 'Pclass_le', 'Sex_le', 'Embarked_C', 'Embarked_Q', 'Embarked_S']]
y = train_df_2['Survived']
for i, (train_index, test_index) in enumerate(kfold.split(X)):
X_train, X_test = X.values[train_index], X.values[test_index]
y_train, y_test = y.values[train_index], y.values[test_index]
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
model_lor2 = LogisticRegression()
model_lor2.fit(X_train, y_train)
y_pred2 = model_lor2.predict(X_test)
accuracy = accuracy_score(y_test, y_pred2).round(3)
print(f'{i}번째 교차검증 정확도 : {accuracy}')
scores.append(accuracy)
print(f'평균 정확도 : {np.mean(scores)}')
이 코드는 KFold 교차검증 방식을 적용하는 코드인데
중간 부분을 보면 아래와 같은 코드가 있다.
X_train, X_test = X.values[train_index], X.values[test_index]
y_train, y_test = y.values[train_index], y.values[test_index]
for문으로 train_index와 test_index를 나누었으니
독립변수와 종속변수를 각각 train, test 데이터셋으로 나눠주는 것이다.
그래야 model을 학습시킬 수 있기 때문이다.
그런데 kfold=KFold(n_splits = 5, shuffle=True) 코드에서 shuffle이라는 파라미터가 있다.
이건 말 그대로 무작위로 섞는다는 말인데
무작위로 섞지 않을 경우 위에서부터 아래로 순서대로 split된다.
이게 왜 문제가 되냐하면
예를 들어 음성일 확률에 해당하는 레이블 0, 양성일 확률에 해당하는 레이블 1이 있을 때
1의 비중이 0.001%로 아주 적을 수 있는데
shuffle하지 않고 split할 경우 각 Fold가 0과 1의 비율을 제대로 반영할 수 없게된다.
그래서 shuffle 파라미터를 사용하는데 이 방법 외에도 StratifiedKFold 모델을 사용하면 불균형 문제를 해결할 수 있다.
from sklearn.model_selection import StratifiedKFold
S_kfold = StratifiedKFold(n_splits=5)
score=[]
X = train_df_2[['Age_mm_sc', 'Family_mm_sc', 'Fare_sd_sc', 'Pclass_le', 'Sex_le', 'Embarked_C', 'Embarked_Q', 'Embarked_S']]
y = train_df_2['Survived']
for i, (train_index, test_index) in enumerate(S_kfold.split(X, y)):
X_train, X_test = X.values[train_index], X.values[test_index]
y_train, y_test = y.values[train_index], y.values[test_index]
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score
model_lor2 = LogisticRegression()
model_lor2.fit(X_train, y_train)
y_pred2 = model_lor2.predict(X_test)
accuracy = accuracy_score(y_test, y_pred2).round(3)
print(f'{i}번째 교차검증 정확도 : {accuracy}')
scores.append(accuracy)
print(f'평균 정확도 : {np.mean(scores)}')
KFold 모델과 코드는 거의 대부분 동일한데
S_kfold.split( )의 소괄호에 독립변수 뿐만 아니라 종속변수도 함께 넣어준다는 부분이 다르다.
그래서 보통 LogisticRregression과 같은 분류 모델링을 할 때,
그리고 앞서 언급한 예시에서와 같이 레이블 데이터의 왜곡이 있을 때
StratifiedKFold 모델을 사용한다.
'데이터 분석 공부 > 머신러닝' 카테고리의 다른 글
머신러닝 심화 복습(과적합)(24.05.07) (0) | 2024.05.07 |
---|---|
머신러닝 심화 복습(결측치, 인코딩&스케일링)(24.05.07) (0) | 2024.05.07 |
머신러닝 심화 복습(데이터 구조, EDA 시각화, 기술 통계, 이상치)(24.05.06) (0) | 2024.05.06 |
머신러닝 기초 복습(로지스틱 회귀)(24.05.03) (0) | 2024.05.03 |
머신러닝 기초 복습(선형 회귀)(24.05.02) (1) | 2024.05.02 |