%23%20%2F%2F%2F%20script%0A%23%20requires-python%20%3D%20%22%3E%3D3.11%22%0A%23%20dependencies%20%3D%20%5B%0A%23%20%20%20%20%20%22yohou%5Bplotting%5D%22%2C%0A%23%20%5D%0A%23%20%2F%2F%2F%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.8%22%0Aapp%20%3D%20marimo.App(width%3D%22medium%22)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20How%20to%20Choose%20a%20Forecasting%20Method%0A%0A%20%20%20%20This%20notebook%20walks%20through%20the%20decision%20steps%20for%20choosing%20a%20forecasting%0A%20%20%20%20method%2C%20starting%20from%20a%20baseline%20and%20progressively%20adding%20complexity%20only%0A%20%20%20%20when%20scores%20improve.%0A%0A%20%20%20%20**Prerequisites%3A**%20Familiarity%20with%20fit%2Fpredict%2Fscore%0A%20%20%20%20(%5BGetting%20Started%5D(%2Fpages%2Ftutorials%2Fgetting-started%2F)).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Setup%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20polars%20as%20pl%0A%20%20%20%20from%20sklearn.linear_model%20import%20Ridge%0A%0A%20%20%20%20from%20yohou.datasets%20import%20fetch_tourism_monthly%0A%20%20%20%20from%20yohou.metrics%20import%20MeanAbsoluteError%0A%20%20%20%20from%20yohou.model_selection%20import%20ExpandingWindowSplitter%2C%20GridSearchCV%2C%20train_test_split%0A%20%20%20%20from%20yohou.point%20import%20PointReductionForecaster%2C%20SeasonalNaive%0A%0A%20%20%20%20y%20%3D%20(%0A%20%20%20%20%20%20%20%20fetch_tourism_monthly()%0A%20%20%20%20%20%20%20%20.frame.select(%22time%22%2C%20%22T1__tourists%22)%0A%20%20%20%20%20%20%20%20.drop_nulls()%0A%20%20%20%20%20%20%20%20.rename(%7B%22T1__tourists%22%3A%20%22total%22%7D)%0A%20%20%20%20)%0A%0A%20%20%20%20forecasting_horizon%20%3D%2012%0A%20%20%20%20y_train%2C%20y_test%20%3D%20train_test_split(y%2C%20test_size%3Dforecasting_horizon)%0A%0A%20%20%20%20scorer%20%3D%20MeanAbsoluteError()%0A%20%20%20%20scorer.fit(y_train)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20%20%20%20%20Ridge%2C%0A%20%20%20%20%20%20%20%20SeasonalNaive%2C%0A%20%20%20%20%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20%20%20%20%20scorer%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20y_train%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%201.%20Establish%20a%20Baseline%20with%20SeasonalNaive%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(SeasonalNaive%2C%20forecasting_horizon%2C%20scorer%2C%20y_test%2C%20y_train)%3A%0A%20%20%20%20baseline%20%3D%20SeasonalNaive(seasonality%3D12)%0A%20%20%20%20baseline.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_baseline%20%3D%20baseline.predict(forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20score_baseline%20%3D%20scorer.score(y_test%2C%20y_pred_baseline)%0A%20%20%20%20print(f%22SeasonalNaive%20MAE%3A%20%7Bscore_baseline%3A.2f%7D%22)%0A%20%20%20%20return%20score_baseline%2C%20y_pred_baseline%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%202.%20Add%20a%20Linear%20Model%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20scorer%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20from%20yohou.preprocessing%20import%20LagTransformer%0A%0A%20%20%20%20linear%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRidge()%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%206%2C%2012%5D)%2C%0A%20%20%20%20)%0A%20%20%20%20linear.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_linear%20%3D%20linear.predict(forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20score_linear%20%3D%20scorer.score(y_test%2C%20y_pred_linear)%0A%20%20%20%20print(f%22Ridge%20%2B%20Lags%20MAE%3A%20%7Bscore_linear%3A.2f%7D%22)%0A%20%20%20%20return%20LagTransformer%2C%20score_linear%2C%20y_pred_linear%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%203.%20Stabilize%20Non-stationary%20Series%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20scorer%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20from%20yohou.stationarity%20import%20SeasonalDifferencing%0A%0A%20%20%20%20stationary%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRidge()%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%206%2C%2012%5D)%2C%0A%20%20%20%20%20%20%20%20target_transformer%3DSeasonalDifferencing(seasonality%3D12)%2C%0A%20%20%20%20)%0A%20%20%20%20stationary.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_stationary%20%3D%20stationary.predict(forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20score_stationary%20%3D%20scorer.score(y_test%2C%20y_pred_stationary)%0A%20%20%20%20print(f%22Ridge%20%2B%20Lags%20%2B%20SeasonalDiff%20MAE%3A%20%7Bscore_stationary%3A.2f%7D%22)%0A%20%20%20%20return%20SeasonalDifferencing%2C%20score_stationary%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%204.%20Enrich%20Features%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20SeasonalDifferencing%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20scorer%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20from%20yohou.compose%20import%20FeatureUnion%0A%20%20%20%20from%20yohou.preprocessing%20import%20RollingStatisticsTransformer%0A%0A%20%20%20%20feature_transformer%20%3D%20FeatureUnion(%0A%20%20%20%20%20%20%20%20transformer_list%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22lags%22%2C%20LagTransformer(lag%3D%5B1%2C%203%2C%206%2C%2012%5D))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22rolling%22%2C%20RollingStatisticsTransformer(window_size%3D6))%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%0A%20%20%20%20enriched%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRidge()%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3Dfeature_transformer%2C%0A%20%20%20%20%20%20%20%20target_transformer%3DSeasonalDifferencing(seasonality%3D12)%2C%0A%20%20%20%20)%0A%20%20%20%20enriched.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_enriched%20%3D%20enriched.predict(forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20score_enriched%20%3D%20scorer.score(y_test%2C%20y_pred_enriched)%0A%20%20%20%20print(f%22Ridge%20%2B%20Features%20%2B%20SeasonalDiff%20MAE%3A%20%7Bscore_enriched%3A.2f%7D%22)%0A%20%20%20%20return%20feature_transformer%2C%20score_enriched%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%205.%20Switch%20to%20a%20Nonlinear%20Estimator%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20SeasonalDifferencing%2C%0A%20%20%20%20feature_transformer%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20scorer%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20from%20sklearn.ensemble%20import%20HistGradientBoostingRegressor%0A%0A%20%20%20%20nonlinear%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DHistGradientBoostingRegressor(max_iter%3D100%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3Dfeature_transformer%2C%0A%20%20%20%20%20%20%20%20target_transformer%3DSeasonalDifferencing(seasonality%3D12)%2C%0A%20%20%20%20%20%20%20%20reduction_strategy%3D%22direct%22%2C%0A%20%20%20%20)%0A%20%20%20%20nonlinear.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_nonlinear%20%3D%20nonlinear.predict(forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20score_nonlinear%20%3D%20scorer.score(y_test%2C%20y_pred_nonlinear)%0A%20%20%20%20print(f%22HGBR%20%2B%20Features%20%2B%20SeasonalDiff%20MAE%3A%20%7Bscore_nonlinear%3A.2f%7D%22)%0A%20%20%20%20return%20nonlinear%2C%20score_nonlinear%2C%20y_pred_nonlinear%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%206.%20Decomposition%20for%20Complex%20Seasonality%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20scorer%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20from%20yohou.compose%20import%20DecompositionPipeline%0A%20%20%20%20from%20yohou.stationarity%20import%20FourierSeasonalityForecaster%2C%20PolynomialTrendForecaster%0A%0A%20%20%20%20decomp%20%3D%20DecompositionPipeline(%0A%20%20%20%20%20%20%20%20forecasters%3D%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22trend%22%2C%20PolynomialTrendForecaster(degree%3D1))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22seasonality%22%2C%20FourierSeasonalityForecaster(seasonality%3D12%2C%20harmonics%3D%5B1%2C%202%2C%203%5D))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%22residual%22%2C%20PointReductionForecaster(estimator%3DRidge()%2C%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%202%2C%203%5D)))%2C%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20decomp.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_decomp%20%3D%20decomp.predict(forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20score_decomp%20%3D%20scorer.score(y_test%2C%20y_pred_decomp)%0A%20%20%20%20print(f%22DecompositionPipeline%20MAE%3A%20%7Bscore_decomp%3A.2f%7D%22)%0A%20%20%20%20return%20(score_decomp%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%207.%20Add%20Prediction%20Intervals%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(forecasting_horizon%2C%20nonlinear%2C%20y_train)%3A%0A%20%20%20%20from%20yohou.interval%20import%20SplitConformalForecaster%0A%0A%20%20%20%20interval_forecaster%20%3D%20SplitConformalForecaster(%0A%20%20%20%20%20%20%20%20point_forecaster%3Dnonlinear%2C%0A%20%20%20%20%20%20%20%20calibration_size%3D48%2C%0A%20%20%20%20)%0A%20%20%20%20interval_forecaster.fit(%0A%20%20%20%20%20%20%20%20y_train%2C%20forecasting_horizon%3Dforecasting_horizon%2C%20coverage_rates%3D%5B0.9%5D%0A%20%20%20%20)%0A%20%20%20%20intervals%20%3D%20interval_forecaster.predict_interval(coverage_rates%3D%5B0.9%5D)%0A%20%20%20%20intervals.head()%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%208.%20Compare%20All%20Methods%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20score_baseline%2C%0A%20%20%20%20score_decomp%2C%0A%20%20%20%20score_enriched%2C%0A%20%20%20%20score_linear%2C%0A%20%20%20%20score_nonlinear%2C%0A%20%20%20%20score_stationary%2C%0A%20%20%20%20y_pred_baseline%2C%0A%20%20%20%20y_pred_linear%2C%0A%20%20%20%20y_pred_nonlinear%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20from%20yohou.plotting%20import%20plot_forecast%0A%0A%20%20%20%20print(%22MAE%20Summary%3A%22)%0A%20%20%20%20print(f%22%20%20SeasonalNaive%3A%20%20%20%20%20%20%20%20%20%20%20%20%7Bscore_baseline%3A.2f%7D%22)%0A%20%20%20%20print(f%22%20%20Ridge%20%2B%20Lags%3A%20%20%20%20%20%20%20%20%20%20%20%20%20%7Bscore_linear%3A.2f%7D%22)%0A%20%20%20%20print(f%22%20%20Ridge%20%2B%20Lags%20%2B%20Diff%3A%20%20%20%20%20%20%7Bscore_stationary%3A.2f%7D%22)%0A%20%20%20%20print(f%22%20%20Ridge%20%2B%20Features%20%2B%20Diff%3A%20%20%7Bscore_enriched%3A.2f%7D%22)%0A%20%20%20%20print(f%22%20%20HGBR%20%2B%20Features%20%2B%20Diff%3A%20%20%20%7Bscore_nonlinear%3A.2f%7D%22)%0A%20%20%20%20print(f%22%20%20DecompositionPipeline%3A%20%20%20%20%7Bscore_decomp%3A.2f%7D%22)%0A%0A%20%20%20%20fig%20%3D%20plot_forecast(%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20y_test%3Dy_test%2C%0A%20%20%20%20%20%20%20%20y_pred%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22SeasonalNaive%22%3A%20y_pred_baseline%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Ridge%22%3A%20y_pred_linear%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22HGBR%22%3A%20y_pred_nonlinear%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20)%0A%20%20%20%20fig%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%20Next%20Steps%0A%0A%20%20%20%20-%20%5BHow%20to%20Choose%20a%20Forecasting%20Method%5D(%2Fpages%2Fhow-to%2Fchoose-forecasting-method%2F)%20for%20the%20full%20decision%20guide%0A%20%20%20%20-%20%5BTune%20Forecaster%20Hyperparameters%5D(%2Fpages%2Fhow-to%2Ftune-hyperparameters%2F)%20to%20optimize%20the%20chosen%20method%0A%20%20%20%20-%20%5BEvaluate%20Forecast%20Accuracy%5D(%2Fpages%2Fhow-to%2Fevaluate-forecast-accuracy%2F)%20for%20cross-validation%20and%20metric%20selection%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
4691734622ef470adf87b0b3a45fc8ae