데이터 한 그릇

머신러닝(4)_교차검증 본문

머신러닝/머신러닝기초

머신러닝(4)_교차검증

장사이언스 2021. 7. 23. 14:52

교차검증은 과적합을 방지하기 위해서 사용되며

 

 

`cross_val_score(<모델> ,data, target, cv=5)`

 

 

 

=> data를 5등분한 이후에 4개는 train 1개는 test로 사용한다.

 

 

 

5등분이 번갈아가면서 자신의 역할을 바꾼다. 5개의 학습된 경우의 모델이 나오고 target으로 성능평가한다. => 5개의 성능평과 결과가 나온다.

 

1.cross_val_score

 

from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score, train_test_split

 

 

필요한 모듈들을 모두 import 해준다.

 

data_iris = load_iris()
X =data_iris.data
y = data_iris.target
X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.3)

 

데이터를 불러오고 학습을 위해서 데이터를 나누어준다.

 

lr = LogisticRegression(max_iter = 4000)
cross_val_score(lr, X_train, y_train, cv=10)

 

하이퍼 파라미터 값을 지정해주고, 중간 성능평가를 예측해본다.

 

2.KFold

 

KFold 는 폴드 교차 검증 방법.

몇 개의 폴드를 만들지 설정할 때, 파라미터 값으로 `n_splits =5` 를 설정한다.

이는 5개의 폴드를 만든다는걸 의미한다.

5개의 폴드에서 4개는 학습용 데이터로 1개는 test 데이터로 활용한다.

학습용 데이터의 역할과 테스트 데이터의 역할을 바꾼다.

총 5개의 검증평가가 도출된다.

 

iris = load_iris()
kfold = KFold(n_splits = 5)
cv_accuracy = []
features = iris.data
label = iris.target
print('붓꽃 데이터 세트 크기 :', features.shape[0])

 

5개의 세트를 만들었다.

 

n_iter = 0
for train_index, test_index in kfold.split(data_iris.data):
    X_train, X_test = data_iris.data[train_index], data_iris.data[test_index]
    y_train, y_test = data_iris.target[train_index], data_iris.target[test_index]
    #학습 및 예측
    lr.fit(X_train,y_train)
    pred = lr.predict(X_test)
    accuracy = accuracy_score(pred, y_test)
    print(np.round(accuracy,4))
#     print(np.round(lr.score(X_test,y_test),4))

    
    cv_accuracy.append(accuracy)
    
    n_iter = n_iter+1
    

print('평균 검증 정확도 : ', np.mean(cv_accuracy))

 

데이터 세트를 5개로 split 으로 나누면 5개의 폴드로 생서이 되면서, 학습용과 테스트용 데이터의 index정보를 얻을 수 있다.

(5개의 폴드가 train과 test로 데이터가 나뉨)

인덱싱을 통해서 각 행들을 가져와서 x_train, y_train, x_test, y_test 에 집어넣는다.

그리고 학습을 시키고 정확도를 얻는다.

for문으로 이를 반복한다. 5개로 나누었으니 총 5개의 accuracy 값이 도출된다.

3. Stratified K 폴드

Stratified K 폴드 같은 경우에는 불균형한 분포도를 가진 레이블 데이터 집합을 위한 K 폴드 방식.

특정 레이블 값이 특이하게 많거나 매우 적어서 값의 분포가 한쪽으로 치우치는 것을 말한다.

그때 사용하는 교차검증 방식이 바로 Stratified K폴드 방식이다.

Stratified 는 원본 데이터의 레이블 분포를 먼저 고려한 뒤, 이 분포와 동일하게 학습과 검증 데이터 세트를 분배한다.

 

dt_clf = LogisticRegression(max_iter=4000)

kfold = KFold(n_splits=3)
n_iter=0
cv_accuracy=[]

# StratifiedKFold의 split( ) 호출시 반드시 레이블 데이터 셋도 추가 입력 필요  
for train_index, test_index  in kfold.split(iris.data):
    # split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
    X_train, X_test = iris.data[train_index], iris.data[test_index]
    y_train, y_test = iris.target[train_index], iris.target[test_index]
    #학습 및 예측 
    dt_clf.fit(X_train , y_train)    
    pred = dt_clf.predict(X_test)

    # 반복 시 마다 정확도 측정 
    n_iter += 1
    accuracy = np.round(accuracy_score(y_test,pred), 4)
    train_size = X_train.shape[0]
    test_size = X_test.shape[0]
    print('\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2},검증 데이터 크기: {3}' 
          .format(n_iter, accuracy, train_size, test_size))
    print('#{0} 검증 세트 인덱스:{1}'.format(n_iter,test_index))
    cv_accuracy.append(accuracy)
    
# 교차 검증별 정확도 및 평균 정확도 계산 
print('\n## 교차 검증별 정확도:', np.round(cv_accuracy, 4))
print('## 평균 검증 정확도:', np.mean(cv_accuracy))

 

위의 식은 kfold 를 통해서 사용한 것.

 

로직 : data 를 n_splits 의 개수로 나눔 -> 나눈 것 중에서 1개는 test, 나머지는 train으로 설정

-> train 인 것중에서 data와 target을 뽑아내고 test인 것 중에서 data와 target인 것 뽑아내기

 

-> 그걸 통해서 모델 학습하고 모델 평가하기.

 

 

하지만 실제 현실세계의 데이터 값은 일정한 비율로 target 데이터의 label 들이 설정되어 있지 않다.

보통 label 들의 비율이 한쪽으로 쏠려있다.

따라서 StratifiedKFold 를 사용해야만 한다.

 

dt_clf = LogisticRegression(max_iter=4000)

skfold = StratifiedKFold(n_splits=3)
n_iter=0
cv_accuracy=[]

# StratifiedKFold의 split( ) 호출시 반드시 레이블 데이터 셋도 추가 입력 필요  
for train_index, test_index  in skfold.split(iris.data, iris.target):
    # split( )으로 반환된 인덱스를 이용하여 학습용, 검증용 테스트 데이터 추출
    X_train, X_test = iris.data[train_index], iris.data[test_index]
    y_train, y_test = iris.target[train_index], iris.target[test_index]
    #학습 및 예측 
    dt_clf.fit(X_train , y_train)    
    pred = dt_clf.predict(X_test)

    # 반복 시 마다 정확도 측정 
    n_iter += 1
    accuracy = np.round(accuracy_score(y_test,pred), 4)
    train_size = X_train.shape[0]
    test_size = X_test.shape[0]
    print('\n#{0} 교차 검증 정확도 :{1}, 학습 데이터 크기: {2},검증 데이터 크기: {3}' 
          .format(n_iter, accuracy, train_size, test_size))
    print('#{0} 검증 세트 인덱스:{1}'.format(n_iter,test_index))
    cv_accuracy.append(accuracy)
    
# 교차 검증별 정확도 및 평균 정확도 계산 
print('\n## 교차 검증별 정확도:', np.round(cv_accuracy, 4))
print('## 평균 검증 정확도:', np.mean(cv_accuracy))

 

StratifiedKFold 는 불균형적으로 있는 label 비율일 때 사용하는 교차검증 방식이다.

StratifiedKFold 같은 경우에는 label 이 분류인 경우에만 사용할 수 있는 교차검증이다.

=> target 이 분류 데이터일 경우에만 사용이 가능하다.

4. cross_val_score

kfold 나 StratifiedKFold 처럼 데이터를 학습하고 예측하는 코드에서 하는 작업들을 간단하게 교차 검증할 수 있게 도와준다.

corss_val_score 같은 경우에는 최적의 파라미터 값을 찾을 때 주로 사용한다.

 

cross_val_score(lr, x_train, y_train, cv= 3)

 

 

모델을 집어넣고 data와 target 데이터를 넣어준다.

 

그러면 각 폴더마다의 accuracy가 자동으로 계산이 된다.

 

 

Comments