본문 바로가기
인공지능 AI/회귀 분석

[머신러닝 machine learning] 학습 모델 검증validation 및 테스트test - 파이썬 코드

by ggyongi 2021. 5. 15.
반응형

나중에 잘 재활용하기 위해서 쓰는 글이다. 

직접 실행한 프로젝트 위주로 잘 정리해서 써보겠다.

 

내가 시행한 회귀분석 프로젝트는 다음과 같이 5개의 회귀모델을 사용하였다.

각각의 자세한 설명은 생략한다. 

from sklearn.linear_model import LinearRegression
from sklearn.linear_model import Lasso
from sklearn.svm import SVR
from sklearn.neighbors import KNeighborsRegressor
from sklearn.ensemble import RandomForestRegressor
# set regression models
model_names = ['Linear Regression','Lasso','Support Vector','K-Neighbor','Random Forest']
models = []
models.append(LinearRegression())
models.append(Lasso())
models.append(SVR(kernel = 'rbf',gamma='scale'))
models.append(KNeighborsRegressor(n_neighbors = 7, weights = "distance"))
models.append(RandomForestRegressor(max_depth = 20, n_estimators=10, random_state= 10))

 

이제 각 모델을 검증해봐서 제일 우수한 모델을 선정할 것이다. 

우선 전체 데이터를 train데이터와 test데이터로 분리한다. 아래와 같이 모듈을 이용하면 쉽게 할 수 있다.

features와 label을 잘 선정하고 train_test_split의 인자로 잘 넣어주면 된다.

- test_size : 테스트로 사용할 데이터의 비율

- random_state : 코드를 돌릴 때마다 학습데이터, 테스트 데이터가 달라진다면 정확한 성능 분석이 어려울 수 있다. 그래서 학습, 테스트 데이터가 분리된 경우의 수 하나를 고정시켜놓고 다양한 모델에 적용해봄으로써 어떤 모델이 가장 좋은지 살펴보는 것이다. 따라서 이 값은 0이든 100이든 아무 값이 와도 상관없다.  경우의 수 번호..?쯤이라 생각하면된다.

from sklearn.model_selection import train_test_split

features = df.loc[:,:'높이(H)']
label = df.loc[:, label_name] 
x_train, x_test, y_train, y_test = train_test_split(features, label, test_size=0.2, random_state=0)

 

아래 코드는 다양한 모델을 사용하면서 모델 검증을 해보는 과정이다. 

K-Fold 교차검증이 가장 널리 알려진 검증 방법이다. 이 역시 이미 만들어진 모듈로 쉽게 구현해볼 수 있다.

cross_val_score의 parameter 중 cv 값이 있는데 아래 코드에선 cv=5로 설정되어있다.

이 뜻은 넘겨받은 데이터를 5개로 나누어서 4개는 학습, 1개는 검증 데이터로 써서 학습성과를 내보겠다는 뜻이다.

즉 cv=5는 총 다섯 번의 검증이 가능하다. 이러한 방법은 데이터 총 개수가 적은 상황에서 유용하게 쓰일 수 있다.

이 다섯 번의 검증 결과를 return값으로 반환해준다.

이때 scoring을 무엇으로 설정하냐에 따라 반환값의 종류가 달라진다.

from sklearn.model_selection import cross_val_score
rmse_list = []
for i in range(len(models)):
        model_name = model_names[i]
        model = models[i]
        # K-fold cross validation
        nmse = cross_val_score(model, x_train, y_train, scoring = 'neg_mean_squared_error', cv=5)
        rmse = np.sqrt(-1 * nmse)
        avg_rmse = (sum(rmse) - max(rmse) - min(rmse)) / (len(rmse)-2)
        rmse_list.append(avg_rmse)

위의 코드에선 scoring = 'neg_mean_squared_error'을 사용했다. mse의 negative값을 반환해주기때문에 -1을 한번 곱해야 mse가 되고 여기에 루트를 씌우면 rmse가 된다.

 

아래와 같이 다양한 scoring 방법이 존재한다.

회귀 분석에 쓰일 수 있는 대표적 방법은 MAE, MSE, MAPE, RMSE 정도가 있다. 

각각의 설명은 생략..!

# valid options of scoring
[
'accuracy', 
'adjusted_rand_score',
'average_precision',
'f1',
'log_loss',
'mean_absolute_error',
'mean_squared_error',
'precision',
'r2',
'recall',
'roc_auc'
]

참고: scoring을 커스터마이징 할 수도 있다.

다음 코드는 검증 결과를 MAPE로 받는 과정이다. 

def MAPE(clf, x, y):# mean absolute percentage error
    pred = clf.predict(x)
    y += 0.1 # to avoid dividing by 0
    return 100*np.mean(np.abs((y-pred) / y))

mape = cross_val_score(model, x_train, y_train, scoring = MAPE, cv=5)

 

검증이 끝나면, 검증 결과를 살펴서 테스트를 시행할 모델을 선정한다.

여기서는 RMSE값이 가장 작은 모델을 선택하여 쓰기로 하였다.

def MAPE(clf, x, y):# mean absolute percentage error
    pred = clf.predict(x)
    y += 0.1 # to avoid dividing by 0
    return 100*np.mean(np.abs((y-pred) / y))

def RMSE(clf, x, y): # root mean square error
    pred = clf.predict(x)
    return np.sqrt(np.mean(np.square(y-pred)))


# select model and test
model_idx = np.argmin(rmse_list)
model = models[model_idx]
model.fit(x_train,y_train)
mape = MAPE(model, x_test, y_test)
rmse = RMSE(model, x_test, y_test)

model 인자에 내가 사용할 모델을 넘겨주고 fit() 함수로 학습을 하게 된다.

그리고 predict()로 test 데이터에 대한 예측을 하는 것이다. 그리고 그에 대한 지표로 rmse값과 mape값을 구해본다.

만약 실제값을 어떻게 예측했는지 보고싶다면 다음과 같은 코드를 써주면 된다.

comparison = pd.DataFrame({'prediction': y_pred, 'ground_truth':y_test.values.ravel()}) 
print(comparison)

 

나머지 과정은 이 값들을 잘 살펴보며 학습이 제대로 잘 되는지, 테스트 성능이 괜찮은지를 잘 살펴보는 것이다.

조금 더 모델들에 대해 공부한다면 parameter 튜닝 같은 것도 시도해볼 수 있다.

그러면 더 높은 정확도를 얻을 수 있을 것이다. 

 

비전공자 네카라 신입 취업 노하우

시행착오 끝에 얻어낸 취업 노하우가 모두 담긴 전자책!

kmong.com

댓글