k fold cross validation으로 하이퍼 파라미터 찾기
※ Train set / Test set
- Test set을 통해 모델의 성능을 검증하고, 하이퍼 파라미터를 설정하게 되면 구축된 모델이 test set에 overfitting 될 수 있다. 일반적으로 하이퍼 파라미터를 탐색하기 위해서 따로 에러 값을 찾는 검증용 데이터셋(validation set)을 사용하게 된다.

※ Train set / Validation set / Test set > K-fold cross validation
- 모든 데이터셋을 Train에 활용할 수 있다.
- 정확도를 향상시킬 수 있다.
- 데이터 부족으로 인한 underfitting을 방지할 수 있다.
- 모든 데이터셋을 Validation에 활용할 수 있다.
- 평가에 사용되는 데이터 편중을 막을 수 있다.
- 평가 결과에 따라 좀 더 일반화된 모델을 구축할 수 있다.
cv = 5max_iter = 5000n_trials = 50def myrange(start, end, step): r = start while(r < end): yield r r += step alpha_list = list(reversed([round(i,2) for i in myrange(0.01, 10, 0.1)]))
model_Lasso = LassoCV(alphas = alpha_list, cv = cv, n_jobs = -1, random_state = 1, max_iter = max_iter)model_Lasso.fit(X_train, y_train)
model_Lasso.alpha_


라쏘 모델에 적용을 하게 되면 최적의 알파 값 9.91을 도출하게 된다.
최적의 알파값으로 예측을 수행할 수 있다.
pred_train_LR = model_LR.predict(X_train)pred_test_LR = model_LR.predict(X_test)pred_train_Lasso = model_Lasso.predict(X_train)pred_test_Lasso = model_Lasso.predict(X_test)
train_rmse_LR = np.sqrt(mean_squared_error(y_train, pred_train_LR))train_mae_LR = mean_absolute_error(y_train, pred_train_LR)train_r2_LR = r2_score(y_train, pred_train_LR)test_rmse_LR = np.sqrt(mean_squared_error(y_test, pred_test_LR))test_mae_LR = mean_absolute_error(y_test, pred_test_LR)test_r2_LR = r2_score(y_test, pred_test_LR)train_rmse_Lasso = np.sqrt(mean_squared_error(y_train, pred_train_Lasso))train_mae_Lasso = mean_absolute_error(y_train, pred_train_Lasso)train_r2_Lasso = r2_score(y_train, pred_train_Lasso)test_rmse_Lasso = np.sqrt(mean_squared_error(y_test, pred_test_Lasso))test_mae_Lasso = mean_absolute_error(y_test, pred_test_Lasso)test_r2_Lasso = r2_score(y_test, pred_test_Lasso)
results = pd.DataFrame(index = ['rmse', 'mae', 'r2'], columns = ['LR train', 'LR test', 'Lasso train', 'Lasso test'])
results.loc['rmse', 'LR train'] = train_rmse_LRresults.loc['mae', 'LR train'] = train_mae_LRresults.loc['r2', 'LR train'] = train_r2_LRresults.loc['rmse', 'LR test'] = test_rmse_LRresults.loc['mae', 'LR test'] = test_mae_LRresults.loc['r2', 'LR test'] = test_r2_LRresults.loc['rmse', 'Lasso train'] = train_rmse_Lassoresults.loc['mae', 'Lasso train'] = train_mae_Lassoresults.loc['r2', 'Lasso train'] = train_r2_Lassoresults.loc['rmse', 'Lasso test'] = test_rmse_Lassoresults.loc['mae', 'Lasso test'] = test_mae_Lassoresults.loc['r2', 'Lasso test'] = test_r2_Lasso
results

최적의 알파값으로 도출된 라쏘의 테스트값이 LR값보다 훨씬 좋은 성능을 가지고 있는 것을 확인할 수 있다.
k fold cross validation으로 하이퍼 파라미터 찾기 + 모델 비교 선택
models = {}n_trials = 20alpha_list = 10 ** np.linspace(-3, 3, n_trials)cv = 5alpha_list = list(reversed([round(i, 2) for i in myrange(0.01, 10, 0.1)]))l1_list = list(reversed([round(i, 2) for i in myrange(0, 1, 0.1)]))max_iter = 5000
model = LassoCV(alphas = alpha_list, cv = cv, n_jobs = -1, random_state = 1, max_iter = max_iter)model.fit(X_train, y_train)models['Lasso'] = Lasso(alpha = model.alpha_, max_iter = max_iter)
model = RidgeCV(alphas = alpha_list, cv = cv)model.fit(X_train, y_train)models['Ridge'] = Ridge(alpha = model.alpha_)
model = ElasticNetCV(alphas = alpha_list, l1_ratio = l1_list, cv = cv, random_state = 1, n_jobs = -1, max_iter = max_iter)model.fit(X_train, y_train)models['ElasticNet'] = ElasticNet(alpha = model.alpha_, l1_ratio = model.l1_ratio_, max_iter = max_iter)
for name in models.keys(): print(models[name]) print('-'*100)

최적의 하이퍼 파라미터 값이 도출되었다.
모델 비교 선택
kf = KFold(cv, shuffle = True, random_state = 1)kf
score = {}for name in models.keys(): # save score for each model if name not in score: score[name] = [] # 모델 reg = models[name] for i_train, i_valid in kf.split(X_train): # 학습 reg.fit(X_train[i_train], y_train[i_train]) # 예측 y_pred = reg.predict(X_train[i_valid]) RMSE = np.sqrt(mean_squared_error(y_train[i_valid], y_pred)) score[name].append(RMSE)
score

score 값을 보면 5개의 폴드를 사용했기 때문에 5개의 rmse가 도출이 되는 것을 확인할 수 있다.
results = pd.DataFrame(score)results

ax = results.plot.bar()pd.concat([results.mean(), results.std()], axis = 1, keys = ['mean', 'std'])
최종적인 예측은 평균값, 표준편차를 사용하게 된다.

ElasticNet이 가장 좋은 성능을 보이는 것을 확인할 수 있다.
가장 성능이 좋았던 ElasticNet을 기준으로 성능을 확인해볼 수 있다.
model = models['ElasticNet'].fit(X_train, y_train)pred_train = model.predict(X_train)pred_test = model.predict(X_test)
rmse_train = np.sqrt(mean_squared_error(y_train, pred_train))rmse_test = np.sqrt(mean_squared_error(y_test, pred_test))print(f'train rmse : {rmse_train:.4f}')print(f'test rmse : {rmse_test:.4f}')

r2_train = r2_score(y_train, pred_train)r2_test = r2_score(y_test, pred_test)print(f'train r2 : {r2_train:.4f}')print(f'test r2 : {r2_test:.4f}')

약 88%의 성능값을 확인할 수 있다.
예측결과 plotting
plt.figure(figsize = (8, 8))plt.title('실제값 vs 모델 출력값', fontsize = 16)plt.scatter(y_train, pred_train, c = 'red', alpha = 0.5)plt.scatter(y_test, pred_test, c = 'blue', alpha = 0.5)plt.plot(y_test, y_test, c = 'gray')plt.plot(y_train, y_train, c = 'gray')plt.xlabel('실제값', size = 10)plt.ylabel('모델 출력 값', size = 10)plt.show()

X축은 실제값, Y값은 출력 값이기 때문에 일직선을 따라가야 가장 정확한 예측을 했다고 볼 수 있다. 위 그래프를 보면 예측을 잘했다고 확인할 수 있다.
계수값을 변수 중요도로 생각하기
model = models['ElasticNet'].fit(X_train, y_train)coef_df = pd.DataFrame(model.coef_.reshape(-1, 1), index = X_test_final.columns, columns = ['coefficients'])coef_df.to_csv('coef.csv')coef_df

각 변수에 대한 베타값들이 산출된 것을 확인할 수 있다.
이를 중요도로 생각하기 위해 절댓값을 취할 것이다.
절댓값을 취하는 이유는 음의 방향이든 양의 방향이든 영향을 미치는 정도를 파악할 것이기 때문이다.
coefficents = np.abs(coef_df.coefficients)index = np.argsort(coefficents)[::-1]print(index)
importance = coefficents[index]columns = [list(coef_df.index)[i] for i in index]importance = importance[importance > 0]
num_print = 20plt.figure(figsize = (10, 3))plt.title('Feature Importances= ABS(coefficients)')plt.bar(range(num_print), importance[:num_print], align = 'center')plt.xticks(range(num_print), columns[:num_print], rotation = 90, fontsize = 11)plt.show()

상위 20개의 기여도가 큰 정도를 파악해보았다. OverallQual=9가 가장 중요도가 큰 변수라고 확인할 수 있다.
'파이썬' 카테고리의 다른 글
파이썬 데이터 분석 실무 테크닉 100 -최적화(2) (0) | 2021.09.14 |
---|---|
파이썬 데이터 분석 실무 테크닉 100 -최적화(1) (1) | 2021.09.13 |
[파이썬 실습] 정규화 모델 실습(1) (0) | 2021.06.05 |
[빅데이터분석기사 실기] - 작업형 1유형 (0) | 2021.06.04 |
파이썬 데이터 분석 실무 테크닉 100 -머신러닝(3) (0) | 2021.06.02 |