1 minute read

그리드 탐색(GridSearchCV)

  • 탐색하려는 하이퍼파라미터와 시도해볼 값 지정
  • 가능한 모든 하이퍼파라미터 조합에 대해 교차 검증을 사용해 평가
# 데이터 불러오기
import pandas as pd
import numpy as np
housing_prepared = pd.read_csv("housing_prepared.csv", index_col=0).reset_index(drop=True)
housing_labels = pd.read_csv("housing_labels.csv", index_col=0).reset_index(drop=True)
housing_labels = housing_labels.values.ravel()
housing = pd.read_csv("housing.csv", index_col=0).reset_index(drop=True)
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestRegressor

param_grid = [
  {
    'n_estimators': [3, 10, 30],
    'max_features': [2, 4, 6, 8]
  },
  {
    'bootstrap': [False],
    'n_estimators': [3, 10],
    'max_features': [2, 3, 4]
  }
]

forest_reg = RandomForestRegressor()

grid_search = GridSearchCV(
  forest_reg, param_grid, cv=5,
  scoring='neg_mean_squared_error',
  return_train_score=True
)

grid_search.fit(housing_prepared, housing_labels)

GridSearchCV(cv=5, estimator=RandomForestRegressor(), param_grid=[{'max_features': [2, 4, 6, 8], 'n_estimators': [3, 10, 30]}, {'bootstrap': [False], 'max_features': [2, 3, 4], 'n_estimators': [3, 10]}], return_train_score=True, scoring='neg_mean_squared_error')

해석

  • 첫번째 dict에 있는 조합을 시도함
  • 이어서 두 번째 dict에 있는 조합을 시도하되, bootstrap 하이퍼파라미터를 False로
  • 총 12 + 6 = 18개 조합을 탐색하고, 각각 5번 모델을 훈련시킴(5-fold)
# 최적의 조합
grid_search.best_params_
{'max_features': 6, 'n_estimators': 30}
# 최적의 추정기
grid_search.best_estimator_
RandomForestRegressor(max_features=6, n_estimators=30)
# 평가 점수 확인
grid_search.cv_results_

랜덤 탐색

  • 적은 수의 조합을 탐색할 때는 모든 조합을 다 시도해보는 GridSearch가 괜찮음
  • 하지만 탐색할 것이 많아진다면 RandomizedSearchCv를 사용하는 것이 좋음
# 특성 중요도 확인
feature_importances = grid_search.best_estimator_.feature_importances_
feature_importances
array([8.64292565e-02, 8.50441983e-02, 4.05437328e-02, 2.52969951e-02, 1.86938557e-02, 2.35435412e-02, 2.05627506e-02, 4.08425076e-01, 2.34638915e-02, 9.36833412e-02, 2.16456345e-02, 1.45090174e-02, 1.28755720e-01, 2.06302580e-05, 4.11047008e-03, 5.27188872e-03])
from functions.full_pipeline import FullPipeline
full_pipeline = FullPipeline()
housing_prepared = full_pipeline.fit_transform(housing)

num_attribs = ['longitude', 'latitude', 'housing_median_age', 'total_rooms', 'total_bedrooms', 'population', 'households', 'median_income']

# 특성 중요도 옆에 이름 표시
extra_attribs = ["rooms_per_hhold", "pop_per_hhold", "bedrooms_per_room"]
cat_encoder = full_pipeline.full_pipeline.named_transformers_["cat"]
cat_one_hot_attribs = list(cat_encoder.categories_[0])
attributes = num_attribs + extra_attribs + cat_one_hot_attribs
sorted(zip(feature_importances, attributes), reverse=True)

[(0.40842507569601877, 'median_income'), (0.12875572035073693, 'INLAND'), (0.09368334124118224, 'pop_per_hhold'), (0.08642925653641972, 'longitude'), (0.08504419827611975, 'latitude'), (0.0405437327993139, 'housing_median_age'), (0.025296995125728642, 'total_rooms'), (0.023543541249955495, 'population'), (0.023463891452147563, 'rooms_per_hhold'), (0.021645634457764098, 'bedrooms_per_room'), (0.020562750611053754, 'households'), (0.01869385572404301, 'total_bedrooms'), (0.014509017419666452, '<1H OCEAN'), (0.005271888719606761, 'NEAR OCEAN'), (0.004110470082200306, 'NEAR BAY'), (2.063025804264065e-05, 'ISLAND')]

시스템 평가

  • 테스트 세트에서 예측 변수와 레이블을 분리하고
  • full_pipeline의 transform()을 호출해 데이터 변환 (테스트 세트를 훈련하면 안 되므로 fit 호출금지)
  • 테스트 세트에서 최종 모델 평가

from sklearn.metrics import mean_squared_error
strat_test_set = pd.read_csv("../datasets/temp/strat_test_set.csv", index_col=0).reset_index(drop=True)

final_model = grid_search.best_estimator_

X_test = strat_test_set.drop("median_house_value", axis=1)
y_test = strat_test_set["median_house_value"].copy()

X_test_prepared = full_pipeline.transform(X_test)

final_predictions = final_model.predict(X_test_prepared)


final_mse = mean_squared_error(y_test, final_predictions)
final_rmse = np.sqrt(final_mse)
final_rmse
warnings.warn(
62756.60972413835

Leave a comment