%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%20Reduction%20Strategies%0A%0A%20%20%20%20%5B%60PointReductionForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.point.reduction.PointReductionForecaster%2F)%20converts%20time%20series%20forecasting%20into%20tabular%0A%20%20%20%20regression.%20The%20%60reduction_strategy%60%20parameter%20controls%20**how**%20multi-step%0A%20%20%20%20forecasts%20are%20produced%20from%20the%20tabularized%20data.%0A%0A%20%20%20%20%23%23%20Prerequisites%0A%0A%20%20%20%20Basic%20familiarity%20with%20%5B%60PointReductionForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.point.reduction.PointReductionForecaster%2F)%20-%0A%20%20%20%20see%20%5B%60reduction_forecaster.py%60%5D(%2Fexamples%2Fgetting-started%2Freduction_forecaster%2F)%20for%20an%20introduction.%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.ensemble%20import%20RandomForestRegressor%0A%0A%20%20%20%20from%20yohou.datasets%20import%20fetch_sunspot%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_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_per_vintage%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%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20LagTransformer%2C%0A%20%20%20%20%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20%20%20%20%20RandomForestRegressor%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%20plot_forecast%2C%0A%20%20%20%20%20%20%20%20plot_score_per_vintage%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(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.%20Load%20and%20Prepare%20Data%0A%0A%20%20%20%20We%20use%20the%20Sunspot%20dataset%20resampled%20to%20monthly%20frequency%20-%0A%20%20%20%20over%20200%20years%20of%20solar%20activity%20with%20a%20strong%20~11-year%20cycle.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fetch_sunspot%2C%20train_test_split)%3A%0A%20%20%20%20from%20yohou.preprocessing%20import%20Downsampler%0A%0A%20%20%20%20y%20%3D%20Downsampler(interval%3D%221mo%22%2C%20aggregation%3D%22mean%22).fit_transform(fetch_sunspot().frame)%0A%0A%20%20%20%20y_train%2C%20y_test%20%3D%20train_test_split(y%2C%20test_size%3D0.05)%0A%20%20%20%20forecasting_horizon%20%3D%2024%0A%0A%20%20%20%20print(f%22Training%3A%20%7Blen(y_train)%7D%20obs%2C%20Test%3A%20%7Blen(y_test)%7D%20obs%22)%0A%20%20%20%20print(f%22Forecasting%20horizon%3A%20%7Bforecasting_horizon%7D%20months%22)%0A%20%20%20%20return%20forecasting_horizon%2C%20y%2C%20y_test%2C%20y_train%0A%0A%0A%40app.cell%0Adef%20_(plot_time_series%2C%20y)%3A%0A%20%20%20%20plot_time_series(y%2C%20title%3D%22Monthly%20Sunspot%20Numbers%20(1818-2020)%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.%20Multi-Output%20Strategy%20(Default)%0A%0A%20%20%20%20A%20**single%20model**%20predicts%20all%20H%20horizon%20steps%20simultaneously.%0A%20%20%20%20The%20sklearn%20estimator%20is%20wrapped%20in%20%60MultiOutputRegressor%60%20(if%20needed)%0A%20%20%20%20to%20output%20H%20values%20at%20once.%0A%0A%20%20%20%20-%20Simple%20and%20fast%3A%20one%20model%20to%20train%0A%20%20%20%20-%20Assumes%20the%20same%20model%20structure%20suits%20every%20step%0A%20%20%20%20-%20%60estimator_%60%20is%20a%20**single**%20%60BaseEstimator%60%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%20RandomForestRegressor%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fc_multi%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRandomForestRegressor(n_estimators%3D20)%2C%0A%20%20%20%20%20%20%20%20reduction_strategy%3D%22multi-output%22%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3Dlist(range(1%2C%2025)))%2C%0A%20%20%20%20)%0A%20%20%20%20fc_multi.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_multi%20%3D%20fc_multi.predict(forecasting_horizon%3Dlen(y_test))%0A%0A%20%20%20%20print(f%22estimator_%20type%3A%20%7Btype(fc_multi.estimator_).__name__%7D%22)%0A%20%20%20%20y_pred_multi.head()%0A%20%20%20%20return%20fc_multi%2C%20y_pred_multi%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.%20Direct%20Strategy%0A%0A%20%20%20%20**H%20independent%20models**%2C%20one%20per%20horizon%20step.%20Each%20model%20specialises%0A%20%20%20%20in%20predicting%20a%20single%20step%20ahead%2C%20avoiding%20the%20error%20accumulation%0A%20%20%20%20that%20recursive%20prediction%20can%20suffer%20from.%0A%0A%20%20%20%20-%20No%20error%20propagation%20between%20steps%0A%20%20%20%20-%20Ignores%20inter-step%20dependencies%0A%20%20%20%20-%20%60estimator_%60%20is%20a%20**list**%20of%20H%20%60BaseEstimator%60%20objects%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%20RandomForestRegressor%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fc_direct%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRandomForestRegressor(n_estimators%3D20)%2C%0A%20%20%20%20%20%20%20%20reduction_strategy%3D%22direct%22%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3Dlist(range(1%2C%2025)))%2C%0A%20%20%20%20)%0A%20%20%20%20fc_direct.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_direct%20%3D%20fc_direct.predict(forecasting_horizon%3Dlen(y_test))%0A%0A%20%20%20%20print(f%22estimator_%20type%3A%20%7Btype(fc_direct.estimator_).__name__%7D%22)%0A%20%20%20%20print(f%22Number%20of%20fitted%20models%3A%20%7Blen(fc_direct.estimator_)%7D%22)%0A%20%20%20%20y_pred_direct.head()%0A%20%20%20%20return%20(y_pred_direct%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%204.%20Dir-Rec%20Strategy%20(Direct-Recursive%20Hybrid)%0A%0A%20%20%20%20**H%20models%20fitted%20sequentially**.%20Model%20h%20predicts%20step%20h%20using%20the%20original%0A%20%20%20%20features%20**augmented**%20with%20in-sample%20predictions%20from%20models%201%20to%20h-1.%0A%20%20%20%20This%20combines%20per-step%20specialisation%20with%20inter-step%20information%20flow.%0A%0A%20%20%20%20-%20Each%20model%20sees%20progressively%20more%20features%0A%20%20%20%20-%20Captures%20dependencies%20between%20horizon%20steps%0A%20%20%20%20-%20%60estimator_%60%20is%20a%20**list**%20of%20H%20%60BaseEstimator%60%20objects%20(like%20direct)%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%20RandomForestRegressor%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fc_dirrec%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRandomForestRegressor(n_estimators%3D20)%2C%0A%20%20%20%20%20%20%20%20reduction_strategy%3D%22dir-rec%22%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3Dlist(range(1%2C%2025)))%2C%0A%20%20%20%20)%0A%20%20%20%20fc_dirrec.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_dirrec%20%3D%20fc_dirrec.predict(forecasting_horizon%3Dlen(y_test))%0A%0A%20%20%20%20print(f%22estimator_%20type%3A%20%7Btype(fc_dirrec.estimator_).__name__%7D%22)%0A%20%20%20%20print(f%22Number%20of%20fitted%20models%3A%20%7Blen(fc_dirrec.estimator_)%7D%22)%0A%20%20%20%20print(f%22Original%20features%3A%20%7Bfc_dirrec._dir_rec_n_original_features_%7D%22)%0A%20%20%20%20y_pred_dirrec.head()%0A%20%20%20%20return%20(y_pred_dirrec%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.%20Visual%20Comparison%0A%0A%20%20%20%20%5B%60plot_forecast%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.plotting.forecasting.plot_forecast%2F)%20accepts%20a%20%60dict%5Bstr%2C%20pl.DataFrame%5D%60%20to%20overlay%0A%20%20%20%20multiple%20models%20on%20the%20same%20chart.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20plot_forecast%2C%0A%20%20%20%20y_pred_direct%2C%0A%20%20%20%20y_pred_dirrec%2C%0A%20%20%20%20y_pred_multi%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%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%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Multi-Output%22%3A%20y_pred_multi%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Direct%22%3A%20y_pred_direct%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Dir-Rec%22%3A%20y_pred_dirrec%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20n_history%3D120%2C%0A%20%20%20%20%20%20%20%20title%3D%22Reduction%20Strategy%20Comparison%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%206.%20MAE%20Comparison%0A%0A%20%20%20%20We%20score%20each%20strategy%20with%20%5B%60MeanAbsoluteError%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.metrics.point.MeanAbsoluteError%2F)%0A%20%20%20%20and%20compare%20them%20in%20a%20bar%20chart.%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%20plot_score_summary%2C%0A%20%20%20%20y_pred_direct%2C%0A%20%20%20%20y_pred_dirrec%2C%0A%20%20%20%20y_pred_multi%2C%0A%20%20%20%20y_test%2C%0A)%3A%0A%20%20%20%20_n%20%3D%20min(len(y_pred_multi)%2C%20len(y_pred_direct)%2C%20len(y_pred_dirrec))%0A%20%20%20%20_y_test_trimmed%20%3D%20y_test.head(_n)%0A%0A%20%20%20%20plot_score_summary(%0A%20%20%20%20%20%20%20%20MeanAbsoluteError()%2C%0A%20%20%20%20%20%20%20%20_y_test_trimmed%2C%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Multi-Output%22%3A%20y_pred_multi.head(_n)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Direct%22%3A%20y_pred_direct.head(_n)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22Dir-Rec%22%3A%20y_pred_dirrec.head(_n)%2C%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20title%3D%22MAE%20by%20Reduction%20Strategy%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%207.%20Feature%20Construction%20with%20%60target_as_feature%60%0A%0A%20%20%20%20The%20%60target_as_feature%60%20parameter%20controls%20what%20enters%20the%20feature%20matrix%0A%20%20%20%20before%20%60feature_transformer%60%20generates%20lags%3A%0A%0A%20%20%20%20%7C%20Value%20%7C%20Features%20built%20from%20%7C%20Use%20case%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%20%60%22transformed%22%60%20(default)%20%7C%20Target%20after%20%60target_transformer%60%20%7C%20Lag%20features%20see%20the%20transformed%20scale%20%7C%0A%20%20%20%20%7C%20%60%22raw%22%60%20%7C%20Original%20untransformed%20target%20%7C%20Lag%20features%20on%20raw%20scale%20even%20when%20target%20is%20transformed%20%7C%0A%20%20%20%20%7C%20%60None%60%20%7C%20Exogenous%20X_actual%20only%20(no%20target)%20%7C%20Purely%20exogenous-driven%20forecasting%20(requires%20X_actual)%20%7C%0A%0A%20%20%20%20We%20compare%20%60%22transformed%22%60%20vs%20%60%22raw%22%60%20with%20the%20direct%20strategy.%0A%20%20%20%20Setting%20%60target_as_feature%3DNone%60%20is%20useful%20when%20exogenous%20features%20(X_actual)%20are%0A%20%20%20%20available%20and%20you%20want%20to%20exclude%20the%20target%20from%20the%20feature%20matrix%20entirely.%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%20MeanAbsoluteError%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20RandomForestRegressor%2C%0A%20%20%20%20forecasting_horizon%2C%0A%20%20%20%20mo%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20taf_scores%20%3D%20%7B%7D%0A%20%20%20%20for%20_taf%20in%20%5B%22transformed%22%2C%20%22raw%22%5D%3A%0A%20%20%20%20%20%20%20%20_fc%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20%20%20%20%20estimator%3DRandomForestRegressor(n_estimators%3D20)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20reduction_strategy%3D%22direct%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20target_as_feature%3D_taf%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3Dlist(range(1%2C%2025)))%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20_fc.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20%20%20%20%20_pred%20%3D%20_fc.predict(forecasting_horizon%3Dlen(y_test))%0A%20%20%20%20%20%20%20%20_mae%20%3D%20MeanAbsoluteError()%0A%20%20%20%20%20%20%20%20_mae.fit(y_train)%0A%20%20%20%20%20%20%20%20taf_scores%5B_taf%5D%20%3D%20_mae.score(y_test.head(len(_pred))%2C%20_pred)%0A%0A%20%20%20%20mo.ui.table(%0A%20%20%20%20%20%20%20%20%5B%7B%22target_as_feature%22%3A%20k%2C%20%22MAE%22%3A%20f%22%7Bv%3A.2f%7D%22%7D%20for%20k%2C%20v%20in%20taf_scores.items()%5D%2C%0A%20%20%20%20%20%20%20%20label%3D%22MAE%20by%20target_as_feature%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%208.%20When%20to%20Use%20Each%20Strategy%0A%0A%20%20%20%20%7C%20Strategy%20%7C%20Models%20fitted%20%7C%20Error%20accumulation%20%7C%20Inter-step%20dependencies%20%7C%20Best%20for%20%7C%0A%20%20%20%20%7C---%7C---%7C---%7C---%7C---%7C%0A%20%20%20%20%7C%20**Multi-output**%20%7C%201%20%7C%20None%20(single%20model)%20%7C%20Implicit%20(joint%20prediction)%20%7C%20Fast%20baseline%2C%20short%20horizons%20%7C%0A%20%20%20%20%7C%20**Direct**%20%7C%20H%20%7C%20None%20(independent)%20%7C%20None%20%7C%20Long%20horizons%2C%20heterogeneous%20steps%20%7C%0A%20%20%20%20%7C%20**Dir-Rec**%20%7C%20H%20(sequential)%20%7C%20Partial%20(augmented%20features)%20%7C%20Explicit%20(feature%20augmentation)%20%7C%20When%20steps%20depend%20on%20prior%20predictions%20%7C%0A%0A%20%20%20%20All%20strategies%20can%20be%20**applied%20recursively**%20for%20horizons%20beyond%20the%20fit%20horizon%0A%20%20%20%20by%20passing%20a%20larger%20%60forecasting_horizon%60%20at%20predict%20time.%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%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_(deepcopy%2C%20fc_multi%2C%20forecasting_horizon%2C%20y_test)%3A%0A%20%20%20%20_vintage_model%20%3D%20deepcopy(fc_multi)%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%3Dforecasting_horizon%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_vintage%2C%20vintage_scorer%2C%20y_pred_vintages%2C%20y_test)%3A%0A%20%20%20%20plot_score_per_vintage(%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%20Vintage%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(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**Reduction%20basics**%3A%20See%20%5B%60reduction_forecaster.py%60%5D(%2Fexamples%2Fgetting-started%2Freduction_forecaster%2F)%20for%20transformers%20and%20GridSearchCV%0A%20%20%20%20-%20**Interval%20strategies**%3A%20See%20%5B%60interval_reduction.py%60%5D(%2Fexamples%2Fforecasting-models%2Finterval_reduction%2F)%20for%20quantile%20regression%20with%20reduction%20strategies%0A%20%20%20%20-%20**Panel%20data**%3A%20See%20%5B%60panel_reduction.py%60%5D(%2Fexamples%2Fpanel-data%2Fpanel_reduction%2F)%20for%20panel%20strategies%20(orthogonal%20to%20reduction%20strategies)%0A%20%20%20%20-%20**Time%20weighting**%3A%20See%20%5B%60time_weighted_reduction.py%60%5D(%2Fexamples%2Fforecasting-models%2Ftime_weighted_reduction%2F)%20for%20sample%20weight%20alignment%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
265df8b0e157f998c2b2ee854f8cc018