前回の続きです。ハンガリーにおけるchikenpox(水疱瘡)のデータを使って、BUTAPESTにおける患者数の3か月分の予想を行っています。前回は、AUTOARIMAでMAE 36を叩き出しました。
今回は、LightGBMを使って予想したいと思います。ハイパーパラメーターチューニングにOptunaというパッケージを使用します。なお、調べた範囲ではRのlightGBMにはoptunaのようにチューニングしてくれるものはないようです。
まずは、feature engineeringを行います。time seriesなので、過去3レコード分のデータを説明変数に追加したいと思います。また、次の観測値(next)を目的変数にします。
next = now + past1 + past2 + past3
df = pd.read_csv("/content/drive/MyDrive/hungary_chickenpox.csv")
df3 = df >> select(X["Date"],X["BUDAPEST"])
df3 = (df3 >>
mutate(next = lead(X["BUDAPEST"],1)) >>
mutate(past1 = lag(X["BUDAPEST"],1)) >>
mutate(past2 = lag(X["BUDAPEST"],2)) >>
mutate(past3 = lag(X["BUDAPEST"],3))
)
df3.head()
過去データがないところがNaNになってしまいました。削除します。
df3 = df3 >> tail(-3)
df3.tail()
一番下にも、NaNがあります。このレコードも削除します。
df3 = df3 >> head(-1)
日付を直接変数として取り込むことができないので、日付を整数の連番とします。
df4 = df3 >> select(~X["Date"])
df4 = df4.reset_index(drop=True)
df4 = df4.reset_index()
df4
LightGBM
lightgbmパッケージとoptunaパッケージをインストールします。
!pip -q install lightgbm
import lightgbm as lgb
!pip -q install optuna
import optuna.integration.lightgbm as LGB_optuna
データフレームをlgb用のデータに変換する必要があります。前処理をしてからlgb.Dataset()にデータを渡します。
X_train_validation = (df4 >> select(~X["next"]))[:-13] # omit target and forecast period
y_train_validation = (df4 >> select(X["next"]))[:-13] # pick up target and omit forecast period
split = int(len(X_train_validation)*0.8)
X_train = X_train_validation.iloc[0:split,:]
X_validation = X_train_validation.iloc[split:,:]
y_train = y_train_validation.iloc[0:split,:]
y_validation = y_train_validation.iloc[split:,:]
lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_validation, y_validation)
paramに設定をして、チューニングします。
param = {
'objective': 'regression',
'metric': 'mae',
}
best = LGB_optuna.train(param,
lgb_train,
valid_sets=lgb_eval)
終わったらパラメーターを確認します。
best.params
{‘bagging_fraction’: 0.8788963832078169, ‘bagging_freq’: 1, ‘feature_fraction’: 1.0, ‘feature_pre_filter’: False, ‘lambda_l1’: 0.011069685334331, ‘lambda_l2’: 0.0004885866098954412, ‘metric’: ‘l1’, ‘min_child_samples’: 10, ‘num_leaves’: 31, ‘objective’: ‘regression’}
このパラメータがいいということなので、このパラメータを使ってモデルを訓練し、予想したいと思います。1レコードずつ予想します。time seriesのCVです。
result_LightGBM = pd.DataFrame(0,
index=np.arange(13),
columns=["pred", "true_value"])
split = len(df4) - 13
nrow = len(df4)
for i in range(split,nrow):
X_train = (df4 >> select(~X["next"])).iloc[0:i]
y_train = (df4 >> select(X["next"])).iloc[0:i]
X_test = (df4 >> select(~X["next"])).iloc[i] # omit target and train period
y_test = (df4 >> select(X["next"])).iloc[i] # pick up target and forecast period
lgb_train_data = lgb.Dataset(X_train, y_train)
# best parameter使用
model = lgb.train(best.params, lgb_train_data)
pred = model.predict(X_test)
result_LightGBM.iloc[i-(split),0] = pred
result_LightGBM.iloc[i-(split),1] = y_test.values
result_LightGBM["mae"] = abs(result_LightGBM["true_value"]-result_LightGBM["pred"])
result_LightGBM["mae"].mean()
38.28
AUTOARIMAでMAE36なので、autoarimaに負けています。。
optunaを使ったhyper parameterのチューニングについては以下の記事で研究しています。
次は、AutoKerasをやってみたいと思います。