パラメータチューニング方法であるグリッドサーチ、
確かに自動で実行してくれて、すごく便利なのですが問題点があります。
めっちゃ時間がかかる
もし、下記のパラメータ設定のモノを全てグリッドサーチしようとすれば、ゲーミングPCでも余裕で24時間を超えます。
・・・特に時間制限のあるColaboratoryでは安易に使えない。
ただ、パラメータ1つ1つグリッドサーチすると
それはそれで「そのパラメータでしかモデルを捉えられない」という問題をはらみます。
そこで、今回は下記の方法の実装を行いました。
グリッドサーチしてパラメータ1を「A」に決める
↓
パラメータ1は「A」として、
グリッドサーチしてパラメータ2を「B」に決める
↓
パラメータ1は「A」、パラメータ2は「B」として、
グリッドサーチしてパラメータ3を「C」に決める
↓
なぜこんなことをしたいのかというと、
適当にパラメータを投入すれば勝手に上手くやってくれるし、時間もかからない機能が欲しかっただけです。
モジュールのインポート
モジュールを必要最低限呼び出します。
scalerはお好きなものをご使用ください。
from sklearn.pipeline import Pipeline from sklearn.model_selection import GridSearchCV from sklearn.preprocessing import MinMaxScaler, StandardScaler, RobustScaler, Normalizer scaler = MinMaxScaler() #scaler = StandardScaler() #scaler = RobustScaler() #scaler = Normalizer(copy=True, norm='l2')
学習器のインポート
今回は回帰の問題だったのでSVRや回帰型XGBを使用しましたが、分類も対応可能です。
from sklearn.svm import SVR # サポートベクター回帰 import xgboost as xgb # XGB
データのインポート
pandasで読み込まれており、前処理は終わっているX、yを仮定します。
ただし、正規化(または標準化等)はまだ実施していないものとします。
X = ... y = ...
パラメータ設定
設定できる項目はまだまだありますが、一つの例として記載します。
cv_list = {
'XGB':
{
'discriminator': xgb.XGBRegressor(objective='reg:linear'),
'random_state': [0],
'booster': ['gbtree', 'gblinear'],
'n_estimators': [1, 3, 5, 10, 20, 30, 50, 100, 200],
'max_depth': [3, 4, 5, 6, 7, 8, 9, 10],
'subsample': 1.1 - 10 ** np.linspace(-1, -0.8, 20), # ~1
'learning_rate': 10 ** np.linspace(-1.2, -0.9, 20),
'gamma': np.linspace(0, 1.0, 20), # 0~
'reg_lambda': 1.1 - 10 ** np.linspace(-1, -0.3, 20), # ~1
'reg_alpha': -0.1 + 10 ** np.linspace(-1, -0.3, 20) # 0~
},
'SVR':
{
'discriminator': SVR(),
'kernel': ['poly', 'rbf', 'sigmoid', 'linear'],
'degree': np.arange(1, 10, 1),
'C': 10 ** np.linspace(-5, 3, 5),
'gamma': 10 ** np.linspace(-5, 0, 5),
'epsilon': 10 ** np.linspace(-5, 0, 5)
}
}
あるパラメータが必要だと思えば追加すれば良いと思います。
グリッドサーチ実行
複数個のモデルのグリッドサーチに対応しています。
パイプラインを使ってデータ分割→scaler実施→model.fit→判定を自動で行います。
パイプラインを使用すると、param_gridをモデル名__パラメータ名にしなければならないことにも対応しています。
最後に一番良いパラメータを表示します。
for model in cv_list:
# model作成
print("#---------------------------------------------------------#")
print("#", model, "loaded")
print("#---------------------------------------------------------#")
model_test = cv_list[model]['discriminator']
model_name = "model"
pipe_model = Pipeline([("scaler", scaler), (model_name, model_test)])
model_param = cv_list[model].copy()
del model_param['discriminator']
# paramごとにCV
best_param = {}
for param in model_param:
# make
param_one = model_name + "__" + param
param_grid = {}
param_grid[param_one] = model_param[param]
param_grid.update(best_param) # 以前のチューニング結果を反映
print(">> Tuning '%s' is..." % (param))
model_cv = GridSearchCV(pipe_model, param_grid=param_grid, cv=3,
return_train_score=False, n_jobs=-1, verbose=0)
model_cv.fit(X, y)
# Best
best_param[param_one] = [getattr(model_cv.best_estimator_.steps[1][1], param)]
print('Best Params:', best_param[param_one])
# last
print(">> All Best Params is...")
print(best_param)
GridSearchCVに自作評価関数を入れることも可能です。
scoring=make_scorer(func_scoring, greater_is_better=True)
最後に
10分もかからずにグリッドサーチが終わると思います。
すべてのパラメータを総当りで行うのはコスト(時間)がかかりすぎるのでおすすめはしません。
お役に立てたのであれば嬉しい限りです。
