%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%22scikit-learn%22%2C%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%20Decomposition%20Variations%0A%0A%20%20%20%20%5B%60DecompositionPipeline%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.compose.decomposition_pipeline.DecompositionPipeline%2F)%20fits%20sequential%20forecasters%20where%20each%0A%20%20%20%20subsequent%20forecaster%20models%20the%20residual%20of%20the%20previous%20one.%0A%20%20%20%20Final%20predictions%20are%20**summed**%20across%20all%20components.%0A%0A%20%20%20%20%23%23%201.%20Prepare%20Univariate%20Data%0A%0A%20%20%20%20We%20load%20the%20Sunspot%20Numbers%20dataset%20and%20resample%20to%20monthly%20frequency.%0A%20%20%20%20This%20long%20series%20(200%2B%20years)%20provides%20a%20good%20test%20case%20for%20decomposition%0A%20%20%20%20into%20trend%2C%20seasonality%2C%20and%20residual%20components.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_()%3A%0A%20%20%20%20from%20copy%20import%20deepcopy%0A%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.compose%20import%20DecompositionPipeline%0A%20%20%20%20from%20yohou.datasets%20import%20fetch_sunspot%2C%20fetch_tourism_quarterly%0A%20%20%20%20from%20yohou.metrics%20import%20MeanAbsoluteError%0A%20%20%20%20from%20yohou.model_selection%20import%20train_test_split%0A%20%20%20%20from%20yohou.plotting%20import%20(%0A%20%20%20%20%20%20%20%20plot_decomposition%2C%0A%20%20%20%20%20%20%20%20plot_forecast%2C%0A%20%20%20%20%20%20%20%20plot_score_per_step%2C%0A%20%20%20%20%20%20%20%20plot_score_summary%2C%0A%20%20%20%20%20%20%20%20plot_time_series%2C%0A%20%20%20%20)%0A%20%20%20%20from%20yohou.point%20import%20PointReductionForecaster%0A%20%20%20%20from%20yohou.preprocessing%20import%20LagTransformer%0A%20%20%20%20from%20yohou.stationarity%20import%20LogTransformer%0A%20%20%20%20from%20yohou.stationarity.seasonality%20import%20PatternSeasonalityForecaster%0A%20%20%20%20from%20yohou.stationarity.trend%20import%20PolynomialTrendForecaster%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20DecompositionPipeline%2C%0A%20%20%20%20%20%20%20%20LagTransformer%2C%0A%20%20%20%20%20%20%20%20LogTransformer%2C%0A%20%20%20%20%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20%20%20%20%20PatternSeasonalityForecaster%2C%0A%20%20%20%20%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20%20%20%20%20PolynomialTrendForecaster%2C%0A%20%20%20%20%20%20%20%20Ridge%2C%0A%20%20%20%20%20%20%20%20deepcopy%2C%0A%20%20%20%20%20%20%20%20fetch_sunspot%2C%0A%20%20%20%20%20%20%20%20fetch_tourism_quarterly%2C%0A%20%20%20%20%20%20%20%20pl%2C%0A%20%20%20%20%20%20%20%20plot_decomposition%2C%0A%20%20%20%20%20%20%20%20plot_forecast%2C%0A%20%20%20%20%20%20%20%20plot_score_per_step%2C%0A%20%20%20%20%20%20%20%20plot_score_summary%2C%0A%20%20%20%20%20%20%20%20plot_time_series%2C%0A%20%20%20%20%20%20%20%20train_test_split%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell%0Adef%20_(fetch_sunspot%2C%20mo%2C%20pl%2C%20train_test_split)%3A%0A%20%20%20%20_raw%20%3D%20fetch_sunspot().frame%0A%20%20%20%20sunspots%20%3D%20_raw.group_by_dynamic(%22time%22%2C%20every%3D%221mo%22).agg(pl.col(%22sunspot_number%22).mean())%0A%20%20%20%20y_train%2C%20y_test%20%3D%20train_test_split(sunspots%2C%20test_size%3D0.15)%0A%20%20%20%20horizon%20%3D%20len(y_test)%0A%20%20%20%20mo.md(f%22**Sunspots**%3A%20Train%3D%7Blen(y_train)%7D%2C%20Test%3D%7Blen(y_test)%7D%22)%0A%20%20%20%20return%20horizon%2C%20sunspots%2C%20y_test%2C%20y_train%0A%0A%0A%40app.cell%0Adef%20_(plot_time_series%2C%20sunspots)%3A%0A%20%20%20%20plot_time_series(sunspots%2C%20title%3D%22Monthly%20Sunspot%20Numbers%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%202.%20Two-Component%3A%20Trend%20%2B%20Residual%0A%0A%20%20%20%20%5B%60DecompositionPipeline%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.compose.decomposition_pipeline.DecompositionPipeline%2F)%20fits%20a%20%5B%60PolynomialTrendForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.stationarity.trend.PolynomialTrendForecaster%2F)%20first%2C%20then%0A%20%20%20%20a%20%5B%60PointReductionForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.point.reduction.PointReductionForecaster%2F)%20on%20the%20residual.%20Final%20predictions%20are%20the%0A%20%20%20%20sum%20of%20both%20components.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DecompositionPipeline%2C%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20PolynomialTrendForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20horizon%2C%0A%20%20%20%20plot_forecast%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fc_two%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%3D2))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22residual%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20estimator%3DRidge(alpha%3D1.0)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%2012%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20store_residuals%3DTrue%2C%0A%20%20%20%20)%0A%20%20%20%20fc_two.fit(y_train%2C%20forecasting_horizon%3Dhorizon)%0A%20%20%20%20y_pred_two%20%3D%20fc_two.predict(forecasting_horizon%3Dhorizon)%0A%0A%20%20%20%20plot_forecast(%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20y_pred_two%2C%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20n_history%3D600%2C%0A%20%20%20%20%20%20%20%20title%3D%22Two-Component%3A%20Quadratic%20Trend%20%2B%20Residual%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20fc_two%2C%20y_pred_two%0A%0A%0A%40app.cell%0Adef%20_(fc_two%2C%20horizon%2C%20plot_decomposition%2C%20y_test)%3A%0A%20%20%20%20_components%20%3D%20%7B%7D%0A%20%20%20%20for%20_name%2C%20_forecaster%20in%20fc_two.forecasters_%3A%0A%20%20%20%20%20%20%20%20_pred%20%3D%20_forecaster.predict(forecasting_horizon%3Dhorizon)%0A%20%20%20%20%20%20%20%20_components%5B_name%5D%20%3D%20_pred.drop(%22vintage_time%22)%0A%20%20%20%20plot_decomposition(y_test%2C%20_components%2C%20title%3D%22Two-Component%20Decomposition%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%203.%20Three-Component%3A%20Trend%20%2B%20Seasonality%20%2B%20Residual%0A%0A%20%20%20%20Adding%20a%20%5B%60PatternSeasonalityForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.stationarity.seasonality.PatternSeasonalityForecaster%2F)%20between%20trend%20and%20residual%0A%20%20%20%20captures%20the%20~11-year%20solar%20cycle%20explicitly.%20The%20residual%20model%20then%0A%20%20%20%20only%20needs%20to%20handle%20irregular%20fluctuations.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DecompositionPipeline%2C%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20PatternSeasonalityForecaster%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20PolynomialTrendForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20horizon%2C%0A%20%20%20%20plot_forecast%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fc_three%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(%22season%22%2C%20PatternSeasonalityForecaster(seasonality%3D132))%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22residual%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20estimator%3DRidge(alpha%3D1.0)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%2012%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%20%20%20%20fc_three.fit(y_train%2C%20forecasting_horizon%3Dhorizon)%0A%20%20%20%20y_pred_three%20%3D%20fc_three.predict(forecasting_horizon%3Dhorizon)%0A%0A%20%20%20%20plot_forecast(%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20y_pred_three%2C%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20n_history%3D600%2C%0A%20%20%20%20%20%20%20%20title%3D%22Three-Component%3A%20Trend%20%2B%20Season%20%2B%20Residual%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20fc_three%2C%20y_pred_three%0A%0A%0A%40app.cell%0Adef%20_(fc_three%2C%20horizon%2C%20plot_decomposition%2C%20y_test)%3A%0A%20%20%20%20_components%20%3D%20%7B%7D%0A%20%20%20%20for%20_name%2C%20_forecaster%20in%20fc_three.forecasters_%3A%0A%20%20%20%20%20%20%20%20_pred%20%3D%20_forecaster.predict(forecasting_horizon%3Dhorizon)%0A%20%20%20%20%20%20%20%20_components%5B_name%5D%20%3D%20_pred.drop(%22vintage_time%22)%0A%20%20%20%20plot_decomposition(y_test%2C%20_components%2C%20title%3D%22Three-Component%20Decomposition%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%204.%20With%20target_transformer%20(Log%20Scale)%0A%0A%20%20%20%20Apply%20a%20log%20transformation%20before%20decomposition%2C%20then%20invert%20after%0A%20%20%20%20prediction.%20Useful%20for%20data%20with%20multiplicative%20trends.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20DecompositionPipeline%2C%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20LogTransformer%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20PolynomialTrendForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20horizon%2C%0A%20%20%20%20plot_forecast%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fc_log%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(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22residual%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20estimator%3DRidge(alpha%3D1.0)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%2012%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20target_transformer%3DLogTransformer(offset%3D1.0)%2C%0A%20%20%20%20)%0A%20%20%20%20fc_log.fit(y_train%2C%20forecasting_horizon%3Dhorizon)%0A%20%20%20%20y_pred_log%20%3D%20fc_log.predict(forecasting_horizon%3Dhorizon)%0A%0A%20%20%20%20plot_forecast(%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20y_pred_log%2C%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20n_history%3D600%2C%0A%20%20%20%20%20%20%20%20title%3D%22Decomposition%20with%20Log%20Target%20Transformer%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%20(y_pred_log%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%205.%20Compare%20All%20Variations%0A%0A%20%20%20%20%5B%60MeanAbsoluteError%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.metrics.point.MeanAbsoluteError%2F)%20scores%20each%20decomposition%20configuration%20on%20the%0A%20%20%20%20held-out%20test%20data%2C%20showing%20which%20combination%20best%20captures%20the%0A%20%20%20%20sunspot%20dynamics.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20y_pred_log%2C%0A%20%20%20%20y_pred_three%2C%0A%20%20%20%20y_pred_two%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20_scorer%20%3D%20MeanAbsoluteError()%0A%20%20%20%20_scorer.fit(y_train)%0A%20%20%20%20_mae_two%20%3D%20float(_scorer.score(y_test%2C%20y_pred_two))%0A%20%20%20%20_mae_three%20%3D%20float(_scorer.score(y_test%2C%20y_pred_three))%0A%20%20%20%20_mae_log%20%3D%20float(_scorer.score(y_test%2C%20y_pred_log))%0A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%7C%20Variation%20%7C%20MAE%20%7C%5Cn%22%0A%20%20%20%20%20%20%20%20f%22%7C-----------%7C-----%7C%5Cn%22%0A%20%20%20%20%20%20%20%20f%22%7C%20Trend%20%2B%20Residual%20%7C%20%7B_mae_two%3A.2f%7D%20%7C%5Cn%22%0A%20%20%20%20%20%20%20%20f%22%7C%20Trend%20%2B%20Season%20%2B%20Residual%20%7C%20%7B_mae_three%3A.2f%7D%20%7C%5Cn%22%0A%20%20%20%20%20%20%20%20f%22%7C%20Log%20%2B%20Trend%20%2B%20Residual%20%7C%20%7B_mae_log%3A.2f%7D%20%7C%22%0A%20%20%20%20)%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%206.%20Panel%20Data%20Decomposition%0A%0A%20%20%20%20Apply%20the%20same%20pipeline%20to%20panel%20data%3A%20each%20group%20gets%20its%20own%0A%20%20%20%20trend%20and%20residual%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%20DecompositionPipeline%2C%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20PolynomialTrendForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20fetch_tourism_quarterly%2C%0A%20%20%20%20plot_forecast%2C%0A%20%20%20%20train_test_split%2C%0A)%3A%0A%20%20%20%20_tourism%20%3D%20fetch_tourism_quarterly().frame%0A%20%20%20%20%23%20Select%208%20series%20with%20uniform%20length%20for%20a%20manageable%20panel%20demo%0A%20%20%20%20_tourist_cols%20%3D%20%5Bf%22T%7Bi%7D__tourists%22%20for%20i%20in%20range(3%2C%2011)%5D%0A%20%20%20%20_tourism%20%3D%20_tourism.select(%22time%22%2C%20*_tourist_cols).drop_nulls()%0A%20%20%20%20_y_train_p%2C%20_y_test_p%20%3D%20train_test_split(_tourism%2C%20test_size%3D0.2)%0A%20%20%20%20_horizon_p%20%3D%20len(_y_test_p)%0A%0A%20%20%20%20_fc_panel%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(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22residual%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20estimator%3DRidge(alpha%3D1.0)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%204%5D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20)%0A%20%20%20%20_fc_panel.fit(_y_train_p%2C%20forecasting_horizon%3D_horizon_p)%0A%20%20%20%20_y_pred_panel%20%3D%20_fc_panel.predict(forecasting_horizon%3D_horizon_p)%0A%0A%20%20%20%20plot_forecast(%0A%20%20%20%20%20%20%20%20_y_test_p%2C%0A%20%20%20%20%20%20%20%20_y_pred_panel%2C%0A%20%20%20%20%20%20%20%20y_train%3D_y_train_p%2C%0A%20%20%20%20%20%20%20%20n_history%3D8%2C%0A%20%20%20%20%20%20%20%20groups%3D%5B%22T3%22%2C%20%22T4%22%2C%20%22T5%22%5D%2C%0A%20%20%20%20%20%20%20%20title%3D%22Panel%20Decomposition%3A%20Trend%20%2B%20Residual%22%2C%0A%20%20%20%20)%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%20Multi-vintage%20Scoring%0A%0A%20%20%20%20The%20%60observe_predict%60%20method%20with%20%60stride%3D1%60%20produces%20one%20forecast%20per%0A%20%20%20%20observation%20point%2C%20creating%20multiple%20*vintages*.%20Each%20vintage%20represents%0A%20%20%20%20a%20different%20forecast%20origin%2C%20so%20you%20can%20analyse%20how%20accuracy%20evolves%20as%0A%20%20%20%20the%20model%20absorbs%20more%20data.%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%20deepcopy%2C%0A%20%20%20%20horizon%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20_fc_v%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRidge(alpha%3D1.0)%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%2012%5D)%2C%0A%20%20%20%20)%0A%20%20%20%20_fc_v.fit(y_train%2C%20forecasting_horizon%3Dhorizon)%0A%20%20%20%20_vintage_model%20%3D%20deepcopy(_fc_v)%0A%20%20%20%20y_pred_vintages%20%3D%20_vintage_model.observe_predict(%0A%20%20%20%20%20%20%20%20y%3Dy_test%2C%0A%20%20%20%20%20%20%20%20stride%3D1%2C%0A%20%20%20%20%20%20%20%20forecasting_horizon%3Dhorizon%2C%0A%20%20%20%20)%0A%20%20%20%20print(f%22Vintages%3A%20%7By_pred_vintages%5B'vintage_time'%5D.n_unique()%7D%22)%0A%20%20%20%20y_pred_vintages.head(10)%0A%20%20%20%20return%20(y_pred_vintages%2C)%0A%0A%0A%40app.cell%0Adef%20_(MeanAbsoluteError%2C%20y_train)%3A%0A%20%20%20%20vintage_scorer%20%3D%20MeanAbsoluteError()%0A%20%20%20%20vintage_scorer.fit(y_train)%0A%20%20%20%20return%20(vintage_scorer%2C)%0A%0A%0A%40app.cell%0Adef%20_(plot_score_per_step%2C%20vintage_scorer%2C%20y_pred_vintages%2C%20y_test)%3A%0A%20%20%20%20plot_score_per_step(%0A%20%20%20%20%20%20%20%20vintage_scorer%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20y_pred_vintages%2C%0A%20%20%20%20%20%20%20%20title%3D%22MAE%20per%20Forecast%20Step%22%2C%0A%20%20%20%20%20%20%20%20y_label%3D%22MAE%22%2C%0A%20%20%20%20%20%20%20%20height%3D380%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(plot_score_summary%2C%20vintage_scorer%2C%20y_pred_vintages%2C%20y_test)%3A%0A%20%20%20%20plot_score_summary(%0A%20%20%20%20%20%20%20%20vintage_scorer%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20y_pred_vintages%2C%0A%20%20%20%20%20%20%20%20title%3D%22Model%20Score%20Summary%22%2C%0A%20%20%20%20)%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**Pipeline%20composition**%3A%20See%20%5B%60examples%2Fcompose%2Fpipeline_composition.py%60%5D(%2Fexamples%2Fdata-features%2Fpipeline_composition%2F)%0A%20%20%20%20-%20**Stationarity%20transforms**%3A%20See%20%5B%60examples%2Fstationarity%2Fstationarity_transforms.py%60%5D(%2Fexamples%2Fdata-features%2Fstationarity_transforms%2F)%0A%20%20%20%20-%20**Panel%20stationarity**%3A%20See%20%5B%60examples%2Fstationarity%2Fpanel_stationarity.py%60%5D(%2Fexamples%2Fpanel-data%2Fpanel_stationarity%2F)%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
e94b1b215614989ace09b195e86ee983