-
[IMLP] Chapter 5. 모델 평가와 성능 향상Machine Learning/Intro to Machine Learning with Python 2022. 5. 23. 14:35
- 데이터를 훈련 세트와 테스트 세트로 나누는 이유는 새로운 데이터에 모델이 얼마나 잘 일반화되는지 측정하기 위함
[교차 검증]
- cross-validation
- 일반화 성능 재기 위해 훈련 세트/테스트 세트로 나누는 것보다 더 안정적이고 뛰어난 통계적 평가 방법
- 데이터를 여러 번 반복해서 나누고 여러 모델을 학습하며 가장 널리 사용되는 방법은 k-겹 교차 검증
#. scikit-learn의 교차 검증
from sklearn.model_selection import cross_val_score form sklearn.datasets import load_iris from sklearn.linear_model import LogisticRegression iris = load_iris() logreg = LogisticRegression() scores = cross_val_score(logreg, iris.data, iris.target)
- cross_val_sore 함수로 교차 검증 구현 가능하며 기본값은 3-겹 교차 검증
- 보통 교차 검증의 정확도를 간단하게 나타내려면 평균 사용함
#. 교차 검증의 장점
- 테스트 세트에 각 샘플이 정확하게 한 번씩 들어감
- 단점은 연산 비용 증가
#. 계층별 k-겹 교차 검증과 그외 전략들
- 단순한 k-겹 교차 검증은 나열 순서대로 k개의 폴드로 나눔
- 계층별 교차 검증은 폴드 안의 클래스 비율이 전체 데이터셋의 클래스 비율과 같도록 데이터를 나눔
- scikit-learn은 회귀에서 기본 k-겹 교차 검증 사용함.. 회귀에서도 폴드가 서로 다른 타깃값 포함하도록 만들 수 있지만 보통 생소한 일이고 일반적으로 사용하는 방법은 아님
<교차 검증 상세 옵션>
- scikit-learn에서 사용 시 cv 매개변수에 교차 검증 분할기 전달함
from sklearn.model_selection import KFold # 5-겹 교차 검증 kfold = KFold(n_splits=5) cross_val_score(logreg, iris.data, iris.target, cv=kfold) # 3-겹 교차 검증 kfold = KFold(n_splits=3) cross_val_score(logreg, iris.data, iris.target, cv=kfold) # 샘플의 순서 바꾸기 kfold = KFold(n_splits=3, shuffle=True, random_state=0) cross_val_score(logreg, iris.data, iris.target, cv=kfold)
<LOOCV>
- Leave-one-out cross-validation
- 각 반복에서 하나의 데이터 포인트를 선택해 테스트 세트로 사용함
from sklearn.model_selection import LeaveOneOut loo = LeaveOneOut() scores = cross_val_score(logreg, iris.data, iris.target, cv=loo)
<임의 분할 교차 검증>
- shuffle-split cross-validation
- train_size만큼의 포인트로 훈련 세트를, test_size만큼의 포인트로 테스트 세트를 만들어 분할하는데 n_splits 횟수만큼 반복함 (정수 입력 시 포인트 절대 개수, 실수 입력 시 전체 데이터에서의 비율)
<그룹별 교차 검증>
- GroupKFold 사용
- groups 배열 사용하는데 훈련/테스트 세트 만들 때 분리되지 않아야 할 그룹 지정
- 예시: 의료 애플리케이션.. 같은 환자로부터 얻은 여러 샘플로 새로운 환자에게 일반화하는 것
scores = cross_val_score(logreg, X, y, groups, cv=GroupKFold(n_splits=3))
[그리드 서치]
- 관심 있는 매개변수들을 대상으로 가능한 모든 조합 시도
#. 간단한 그리드 서치
from sklearn.svm import SVC X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0) best_score = 0 for gamma in [0.001, 0.01, 0.1, 1, 10, 100]: for C in [0.001, 0.01, 0.1, 1, 10, 100]: svm = SVC(gamma=gamma, C=C) svm.fit(X_train, y_train) score = svm.score(X_test, y_test) if score> best_score: best_score = score best_parameters = {'C':C, 'gamma':gamma}
#. 매개변수 과대적합과 검증 세트
- 매개변수 조정을 위해 이미 테스트 세트 이용한 위의 예제!
from sklearn.svm import SVC X_trainval, X_test, y_trainval, y_test = train_test_split(iris.data, iris.target, random_state=0) X_train, Xvalid, y_train, y_valid = train_test_split(X_trainval, y_trainval, random_state=1) best_score = 0 for gamma in [0.001, 0.01, 0.1, 1, 10, 100]: for C in [0.001, 0.01, 0.1, 1, 10, 100]: svm = SVC(gamma=gamma, C=C) svm.fit(X_train, y_train) score = svm.score(X_valid, y_valid) if score> best_score: best_score = score best_parameters = {'C':C, 'gamma':gamma} svm = SVC(**best_parameters) svm.fit(X_trainval, y_trainval) terst_score = svm.score(X_test, y_test)
#. 교차 검증을 사용한 그리드 서치
best_score = 0 for gamma in [0.001, 0.01, 0.1, 1, 10, 100]: for C in [0.001, 0.01, 0.1, 1, 10, 100]: svm = SVC(gamma=gamma, C=C) scores = cross_val_score(svm, X_trainval, y_trainval, cv=5) score = np.mean(scores) if score> best_score: best_score = score best_parameters = {'C':C, 'gamma':gamma} svm = SVC(**best_parameters) svm.fit(X_trainval, y_trainval) terst_score = svm.score(X_test, y_test)
- 일반화 성능을 더 잘 평가하려면 훈련/검증 세트를 한 번만 나누지 않고 교차 검증 사용해서 각 매개변수 조합의 성능 평가할 수 있음
- scikit-larn은 추정기 형태로 구현된 GridSearchCV 제공함
param_grid = {'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]} from sklearn.model_selection import GridSearchCV from sklearn.svm import SVC grid_search = GridSearchCV(SVC(), param_grid, cv=5) # 매개변수 과대적합되는 것을 피하기 위해 데이터를 훈련/테스트 세트로 나누기 X_train, X_test, y_train, y_test = train_test_split(iris.data, iris.target, random_state=0) grid_search.fit(X_train,y_train) grid_search.best_params_ #최적 매개변수 grid_search.best_score_ #최상 교차 검증 점수 pd.DataFrame(grid_search.cv_result) #cv results을 DataFrame으로 변환
<비대칭 매개변수 그리드 탐색>
param_grid = [{'kernel': ['rbf'], 'C': [0.001, 0.01, 0.1, 1, 10, 100], 'gamma': [0.001, 0.01, 0.1, 1, 10, 100]}, {'kernl': [linear'], 'C': [0.001, 0.01, 0.1, 1, 10, 100]}] grid_search = GridSearchCV(SVC(), param_grid, cv=5) grid_search.fit(X_train, y_train) grid_search.best_params_ grid_search.best_score_ results = pd.DataFrame(grid_search.cv_results_)
<그리드 서치에 다양한 교차 검증 적용>
- 훈련 세트와 검증 세트를 한 번만 분할하려며 n_splits = 1, ShuffleSplit나 StratifiedShuffleSplit 사용
<중첩 교차 검증>
- 원본 데이터를 훈련 세트와 테스트 세트로 한 번만 나누느 방식 대신 더 나아가 교차 검증 분할 방식 사용 가능
- nested cross-validation
- 바깥쪽 루프에서 훈련/테스트 세트로 나누고 각 훈련 세트에 대해 그리드 서치를 실행
- 미래의 데이터에 적용하기 위한 예측 모델을 찾는 데에 거의 사용하지 않음
- 특정 데이터셋에서 주어진 모델이 얼마나 잘 일반화되는지 평가하는 데 유용한 방법
[평가 지표와 측정]
- 분류 성능 평가에는 정화가도, 회귀 성능 평가에는 R^2 사용했음
#. 최종 목표를 기억하라
- 머신러닝 애플리케이션에서 특정 알고리즘을 선택하여 나타난 결과를 비즈니스 임팩트라고 함
#. 이진 분류의 평가 지표
- 거짓 양성 (FP, False Positive, 타입 1 에러): 건강한 사람을 양성이라 분류
- 거짓 음성 (FN, False Negative, 타입 2 에러): 암에 걸린 사람을 음성으로 분류
#. 불균형 데이터셋
- imbalanced datasets
#. 오차 행렬
- confusion matrix
from sklearn.metrics import confusion_matrix confusion = confusion_matrix(y_test, pred_logreg)
#. 정확도와의 관계
- 정확도 = (TP+TN)/ (TP+TN+EP+FN) : 정확히 예측한 수 / 전체 샘플 수
#. 정밀도, 재현율, f-점수
- 정밀도 = TP/(TP+FP) (혹은 양성 예측도)
- 재현율 = TP/(TP+FN) (혹은 민감도, 적중률, 진짜 양성 비율)
- (f-score) F = 2*(정밀도 x 재현율) / (정밀도+재현율)
- classification_report 함수는 정밀도, 재현율, f1-점수 모두 계산하여 출력함
<불확실성 고려>
- decision_function 혹은 predict_proba
<정밀도-재현율 곡선과 ROC 곡선>
- 정밀도-재현율 곡선
from sklearn.metrics import precision_recall_curve precision, recall, thresholds = precision_recall_curve(y_test, svc.decision_function(X_test))
- 정밀도-재현율 아랫부분 면적 계산할 수 잇는데 이를 평균 정밀도 (average precisions)
<ROC와 AUC>
- ROC 곡선은 여러 임계값에서 분류기 특성 분석하는 데 널리 사용하는 도구
- 정밀도와 재현율 대신 진짜 양성 비율(TPR)에 대한 거짓 양성 비율(FPR)을 나타냄 : 진짜 양성 비율은 재현율, 거짓 양성 비율은전체 음성 샘플 중 거짓 양성으로 잘못 분류한 비율
from sklearn.metrics import roc_curve fpr, tpr, thresholds = roc_curve(y_test, svc.decision_function(X_test)) plt.plot(fpr, trp, label ="ROC Curve") plt.xlabel("FPR") plt.ylabel("TPR (재현율)")
- 곡선 아래의 면적값 하나로 ROC 곡선 요약하기도 하는데 이 면적을 보통 AUC(Area Under the Curve)라고 함
from sklearn.metrics import roc_auc_core rf_auc = roc_auc_score(y_test, rf.predict_proba(X_test)[:,1]) # random forest의 AUC svc_aud = roc_auc_score(y_test, svc.decision_+function(X_test)) # SVM의 AUC
- 불균형한 데이터셋에서 모델 평가 시 AUC 사용하라고 강력히 권고됨
#. 다중 분류의 평가 지표
- 다중 클래스용 f1-점수는 한 클래스를 양성 클래스로 두고 나머지 클래스들을 음성 클래스로 간주하여 클래스마다 f1-점수 계산함.. macro, weighted, micro 전략 중 하나 사용
#. 회귀의 평가 지표
- R^2 만으로 충분함
'Machine Learning > Intro to Machine Learning with Python' 카테고리의 다른 글
[IMLP] Chapter 7. 텍스트 데이터 다루기 (0) 2022.05.23 [IMLP] Chapter 6. 알고리즘 체인과 파이프라인 (0) 2022.05.23 [IMLP] Chapter 4. 데이터 표현과 특성 공학 (0) 2022.05.23 [IMLP] Chapter 3. 비지도 학습과 데이터 전처리 (2) (0) 2022.05.23 [IMLP] Chapter 3. 비지도 학습과 데이터 전처리 (1) (0) 2022.05.23