移動平均を選択しない理由
カルマンフィルタ・状態空間モデルに対して、移動平均を選択しないことの理由づけ。
下記、書籍を読みながら考えたことです。
そもそもなぜ移動平均を求めるのか(現状、使われているのか)?
測定値にはノイズ(観測誤差)が含まれており、過去(数日間)のデータを用いて平均化してノイズの影響を緩和するため。言い換えると、仮にノイズの生じない状態であれば移動平均値を使用する必要はない(例えば、全数測定によって誤差なく目的とする測定ができる場合など)。
移動平均とは(逐次計算の観点から)
移動平均では、前日の予測値と今日の実測値の差分に重みを付けて今日の実測値から補正した今日の真値を予測する。この時の重みの分母にはk日移動平均のkが含まれ、kが大きな程重みが小さくなる。ここでは、k日の数が大きな程ノイズの影響が緩和される一方、補正は緩慢となり真値の推定に対する精度低下が起きうる。 (なお、厳密には前日の予測値と今日の実測値の差分ではなく、k日前の予測値と今日の差分。詳しくは森平本のp.26。)
移動平均を利用しない理由
上記の理由から、k日の移動平均のkを決める方針はノイズの影響を小さくする(kを大きくする)ことと強く補正する(kを小さくする)ことのトレードオフを考え最適点を見つけることであり、数学的に合理的に決定できる。その合理的な決定方法がカルマンフィルタであり、状態空間モデル。
移動平均を利用する理由
- 計算が簡単
- よく使われてきたので受け入れやすい
- 簡単に理解できる気がする。
k日で事象が変わる場合にはk日移動平均が良いのでは?
例えば、1週間ごとに条件を変える製造工程では1週間内は同じものが作られ続けられるものであり、7日移動平均を選択することにある程度の合理性はあるという声もあるかもしれない。しかし、この考えには測定のノイズの大小の考えが欠落しており、何日の移動平均をとるかはノイズとの兼ね合いで考えるべきである(カルマンフィルタor状態空間モデルを使うことの合理性)。
【kaggle】pystanを始めたい
kaggleではpystanができない?
何も考えずに入れようとする。
import pystan
結果だめ
No module named 'pystan'
import stan
だめ。
バージョン指定で入れようとする
! pip install pystan==3.0.0
結果だめ。
昔のバージョンで入れようとする
! pip install pystan==2.19.1.1
結果だめ。
! python3 -m pip install pystan==3.3.0
import nest_asyncio nest_asyncio.apply() import stan schools_code = """ 略 """ schools_data = {"J": 8, "y": [28, 8, -3, 7, -1, 1, 18, 12], "sigma": [15, 10, 16, 11, 9, 11, 10, 18]} posterior = stan.build(schools_code, data=schools_data) fit = posterior.sample(num_chains=4, num_samples=1000) eta = fit["eta"] # array with shape (8, 4000) df = fit.to_frame() # pandas `DataFrame, requires pandas
warningがたくさん出た上で
ValueError: The JSON document has an improper structure: missing or superfluous commas, braces, missing keys, etc.
のエラーで終了。
pystan-jypyter+pre pystanでトライ
! pip install pystan-jupyter==0.2b1 ! pip install --pre pystan
結果、同じくエラー
ValueError: The JSON document has an improper structure: missing or superfluous commas, braces, missing keys, etc.
他の人がやった過去のnotebook見るとできているようで、どうやら現在のバージョンとの違いによるものと推察。
どうしたものかね。。
参考にしました
JupyterNotebookでPystanをインストールしてもうまくいかなかったら - えい夫のお気軽データサイエンス
Frustrating problems with Pystan (anaconda Python) - PyStan - The Stan Forums
時系列データ解析についてのページ
時系列データ分析全般
http://elsur.jpn.org/202004MMM/chap5.pdf
ランダムウォーク
Random Walks Have Never Been Funnier | by Vladimir Ilievski | Towards Data Science
【Python】株価をランダムウォークでシミュレートしてみる - turtlechanのブログ
市場データからボラティリティ・スマイルを確認してみた - Qiita
時系列分析の単位根過程、ランダムウォークとは? | AVILEN AI Trend
ARMA/ARIMA
【python+株価+statsmodel】ARIMAモデルでダウ平均株価を解析してみた - ころがる狸
【Python】ARMAモデルで時系列分析&予測をやってみる | ミナピピンの研究室
単位根検定
XGBoostingの最適化(Optuna)と特徴量
作成中ですが、暫定で投稿。
ちなみに、xgboostでは欠損値のnanはそのまま取り扱えるようです。
最適化
試行錯誤的に、動く条件を探索しました。
import xgboost as xgb def objective_xgb(trial): # if trial.number == 0 : learning_rate = trial.suggest_loguniform('learning_rate', 0.3, 0.3) gamma = trial.suggest_loguniform('gamma', 1e-8, 1e-8) max_depth = trial.suggest_int('max_depth', 6, 6) min_child_weight = trial.suggest_loguniform('min_child_weight', 1.0, 1.0) #max_delta_step = trial.suggest_uniform('max_delta_step', 1e-10, 1e-10) subsample = trial.suggest_uniform('subsample', 1.0, 1.0) reg_lambda = trial.suggest_uniform('reg_lambda', 1.0, 1.0) reg_alpha = trial.suggest_uniform('reg_alpha', 0.0, 0.0) else: learning_rate = trial.suggest_loguniform('learning_rate', 1e-8, 1.0) gamma = trial.suggest_loguniform('gamma', 1e-15, 1e-5) max_depth = trial.suggest_int('max_depth', 1, 20) min_child_weight = trial.suggest_loguniform('min_child_weight', 1e-8, 1e3) #max_delta_step = trial.suggest_uniform('max_delta_step', 0, 1.0) subsample = trial.suggest_uniform('subsample', 0.0, 1.0) reg_lambda = trial.suggest_uniform('reg_lambda', 0.0, 1000.0) reg_alpha = trial.suggest_uniform('reg_alpha', 0.0, 1000.0) #reg_alpha = trial.suggest_loguniform('reg_alpha', 1e-15, 1e4) # clf = xgb.XGBRegressor( learning_rate = learning_rate, subsample = subsample, max_depth = max_depth, min_child_weight = min_child_weight, max_delta_step = 0, # 1e-10で発散したため、0で固定 reg_lambda = reg_lambda, gamma = gamma, reg_alpha = reg_alpha, #objective='reg:squarederror' ) scores = [] for train_index, test_index in kf.split(X, y): # X_train = scaler.transform( X[train_index] ) y_train = y[train_index] # X_test = scaler.transform( X[test_index] ) y_test = y[test_index] # clf.fit(X_train,y_train) # y_pred = clf.predict(X_test) # scores.append((rmspe(y_test,y_pred))) # return np.mean(np.array(scores))
optuna.logging.disable_default_handler() # Optunaの出力を抑制する #optuna.logging.enable_default_handler() # Optunaで出力する n_trials = 5 # optuna study = optuna.create_study() study.optimize(objective_xgb, n_trials=n_trials)
特徴量評価
そのほか
WARNING: src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.
誤差設定に関するエラーがでてくる場合があるようで、objective='reg:squarederror'
の指定で解決できる場合があります。
regressor = XGBRegressor(tree_method='gpu_hist', random_state=0, objective='reg:squarederror')
参考にしました
最適化
特徴量
Feature Importanceって結局何なの?|Yotaro Katayama|note
pythonで回帰分析【xgb,lgbm,voting】
XGBoost、LightGBM、アンサンブル学習(Voting regressor)についての情報整理
kaggleはこちら。
XGBoost
Python: XGBoost を使ってみる - CUBE SUGAR CONTAINER
XGBoostハイパーパラメータチューニング
Optunaを使ったxgboostの設定方法 - Qiita
XGBoostをOptunaでチューニング(コード解説付き) - Qiita
XGBトピックス
WARNING対応です。
WARNING: /workspace/src/objective/regression_obj.cu:152: reg:linear is now deprecated in favor of reg:squarederror.
regressor = XGBRegressor(tree_method='gpu_hist', random_state=0, objective='reg:squarederror')
LightGBM
公式はこちら
lightgbm.LGBMRegressor — LightGBM 3.2.1.99 documentation
LightGBM 徹底入門 – LightGBMの使い方や仕組み、XGBoostとの違いについて
LightGBM ハンズオン - もう一つのGradient Boostingライブラリ - Qiita
Python: LightGBM を使ってみる - CUBE SUGAR CONTAINER
LightGBMのPythonパッケージ触ってみた - お勉強メモ
LightGBMのweightの使い方、weightは一体何を行っているのか - Qiita
ハイパーパラメータチューニング
LightGBMのハイパーパラメーターチューニングの仕方(optuna) | 獣医 x プログラミング
LightGBMをOptunaでパラメータチューニングする - Qiita
Optuna の拡張機能 LightGBM Tuner によるハイパーパラメータ自動最適化 | Preferred Networks Research & Development
LightGBMをOptunaでパラメータチューニングする - Qiita
OptunaでLightGBMのパラメータ調整 - Qiita
Python 3.x - lightgbm のverbose パラメータが機能しない|teratail
LightGBMトピック
パラメータを辞書型で設定するときは、渡し方に注意。
params = { 'num_class':5, 'max_depth':8, 'num_leaves':200, 'learning_rate': 0.05, 'n_estimators':500 } clf = LGBMClassifier(**params)
アンサンブル学習(Voting regressor)
その9 ボストンの住宅価格をアンサンブル学習(Voting regressor)で予測してみた - ヒノマルクのデータ分析ブログ
Python: アンサンブル学習の Voting を試す - CUBE SUGAR CONTAINER
最新アンサンブル学習SklearnStackingの性能調査(LBGM, RGF, ET, RF, LR, KNNモデル
Optuna【機械学習のパラメータ最適化】
Optunaを使ってハイパーパラメータを調整します。kaggleにまとめました。
Optunaの基本
公式のチュートリアルは下。
import ... # Define an objective function to be minimized. def objective(trial): # Invoke suggest methods of a Trial object to generate hyperparameters. regressor_name = trial.suggest_categorical('classifier', ['SVR', 'RandomForest']) if regressor_name == 'SVR': svr_c = trial.suggest_float('svr_c', 1e-10, 1e10, log=True) regressor_obj = sklearn.svm.SVR(C=svr_c) else: rf_max_depth = trial.suggest_int('rf_max_depth', 2, 32) regressor_obj = sklearn.ensemble.RandomForestRegressor(max_depth=rf_max_depth) X, y = sklearn.datasets.load_boston(return_X_y=True) X_train, X_val, y_train, y_val = sklearn.model_selection.train_test_split(X, y, random_state=0) regressor_obj.fit(X_train, y_train) y_pred = regressor_obj.predict(X_val) error = sklearn.metrics.mean_squared_error(y_val, y_pred) return error # An objective value linked with the Trial object. study = optuna.create_study() # Create a new study. study.optimize(objective, n_trials=100) # Invoke optimization of the objective function.
OptunaでXGBoost, LightGBM
そもそも、XGBoost,LightGBMにはパラメータチューニングの機能があるので、そちらの機能を使用してもよさそうです。
参考にしました
GridSearchCVはもう古い!Optunaでサポートベクターマシンもラクラクチューニング - Qiita
LightGBMをOptunaでパラメータチューニングする - Qiita