[파이썬 실습] 정규화 모델 실습(2)
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 = 5
max_iter = 5000
n_trials = 50
def 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_LR
results.loc['mae', 'LR train'] = train_mae_LR
results.loc['r2', 'LR train'] = train_r2_LR
results.loc['rmse', 'LR test'] = test_rmse_LR
results.loc['mae', 'LR test'] = test_mae_LR
results.loc['r2', 'LR test'] = test_r2_LR
results.loc['rmse', 'Lasso train'] = train_rmse_Lasso
results.loc['mae', 'Lasso train'] = train_mae_Lasso
results.loc['r2', 'Lasso train'] = train_r2_Lasso
results.loc['rmse', 'Lasso test'] = test_rmse_Lasso
results.loc['mae', 'Lasso test'] = test_mae_Lasso
results.loc['r2', 'Lasso test'] = test_r2_Lasso
results
최적의 알파값으로 도출된 라쏘의 테스트값이 LR값보다 훨씬 좋은 성능을 가지고 있는 것을 확인할 수 있다.
k fold cross validation으로 하이퍼 파라미터 찾기 + 모델 비교 선택
models = {}
n_trials = 20
alpha_list = 10 ** np.linspace(-3, 3, n_trials)
cv = 5
alpha_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 = 20
plt.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 |