%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%20Handle%20Short%20Series%0A%0A%20%20%20%20Short%20series%20lack%20enough%20data%20for%20reliable%20seasonal%20estimation%2C%0A%20%20%20%20multi-split%20cross%20validation%2C%20or%20scaled%20metrics.%20This%20notebook%0A%20%20%20%20demonstrates%20fallback%20strategies%20for%20each%20problem.%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%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.plotting%20import%20plot_time_series%0A%0A%20%20%20%20return%20Ridge%2C%20fetch_tourism_monthly%2C%20plot_time_series%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.%20Create%20a%20Short%20Series%0A%0A%20%20%20%20Extract%20a%20single%20short%20series%20from%20the%20tourism%20dataset%20to%20simulate%0A%20%20%20%20a%20scenario%20with%20limited%20history.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fetch_tourism_monthly%2C%20plot_time_series)%3A%0A%20%20%20%20full%20%3D%20fetch_tourism_monthly().frame%0A%20%20%20%20%23%20Take%20only%20the%20first%2030%20months%20of%20a%20single%20series%0A%20%20%20%20short_series%20%3D%20(%0A%20%20%20%20%20%20%20%20full.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%22tourists%22%7D)%0A%20%20%20%20%20%20%20%20.head(30)%0A%20%20%20%20)%0A%20%20%20%20print(f%22Series%20length%3A%20%7Blen(short_series)%7D%20observations%22)%0A%20%20%20%20plot_time_series(short_series%2C%20title%3D%22Short%20Tourism%20Series%20(30%20months)%22)%0A%20%20%20%20return%20(short_series%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%202.%20Use%20Fourier%20Seasonality%20Instead%20of%20Pattern%20Decomposition%0A%0A%20%20%20%20With%20fewer%20than%202%20to%203%20complete%20seasonal%20cycles%2C%20pattern%20based%20decomposition%0A%20%20%20%20is%20unreliable.%20%5B%60FourierSeasonalityForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.stationarity.seasonality.FourierSeasonalityForecaster%2F)%20fits%20smooth%20harmonic%0A%20%20%20%20functions%20that%20converge%20with%20less%20data.%20Start%20with%20a%20low%20%60harmonics%60%0A%20%20%20%20order%20to%20avoid%20overfitting.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(short_series)%3A%0A%20%20%20%20from%20yohou.stationarity.seasonality%20import%20FourierSeasonalityForecaster%0A%0A%20%20%20%20forecaster%20%3D%20FourierSeasonalityForecaster(seasonality%3D12%2C%20harmonics%3D%5B1%2C%202%5D)%0A%20%20%20%20forecaster.fit(short_series%2C%20forecasting_horizon%3D6)%0A%20%20%20%20pred_fourier%20%3D%20forecaster.predict(forecasting_horizon%3D6)%0A%20%20%20%20pred_fourier%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.%20Use%20a%20Simple%20Train%2FTest%20Split%20Instead%20of%20Cross%20Validation%0A%0A%20%20%20%20When%20the%20series%20is%20too%20short%20for%20multi-split%20CV%2C%20use%0A%20%20%20%20%5B%60ExpandingWindowSplitter%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.model_selection.split.ExpandingWindowSplitter%2F)%20with%20%60n_splits%3D2%60%20for%20minimal%20splits.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(short_series)%3A%0A%20%20%20%20from%20yohou.model_selection%20import%20ExpandingWindowSplitter%0A%0A%20%20%20%20splitter%20%3D%20ExpandingWindowSplitter(n_splits%3D2%2C%20test_size%3D6)%0A%20%20%20%20splits%20%3D%20list(splitter.split(short_series))%0A%20%20%20%20print(f%22Number%20of%20splits%3A%20%7Blen(splits)%7D%22)%0A%20%20%20%20for%20i%2C%20(train_idx%2C%20test_idx)%20in%20enumerate(splits)%3A%0A%20%20%20%20%20%20%20%20print(f%22Split%20%7Bi%7D%3A%20Train%20size%3D%7Blen(train_idx)%7D%2C%20Test%20size%3D%7Blen(test_idx)%7D%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.%20Pool%20Short%20Series%20with%20panel_strategy%3D%22global%22%0A%0A%20%20%20%20When%20individual%20series%20are%20short%20but%20you%20have%20many%20of%20them%2C%20pool%0A%20%20%20%20information%20across%20groups.%20The%20global%20panel%20strategy%20trains%20a%0A%20%20%20%20single%20regressor%20on%20all%20series%20simultaneously.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Ridge%2C%20fetch_tourism_monthly)%3A%0A%20%20%20%20from%20yohou.compose%20import%20FeaturePipeline%0A%20%20%20%20from%20yohou.point%20import%20PointReductionForecaster%0A%20%20%20%20from%20yohou.preprocessing%20import%20LagTransformer%0A%0A%20%20%20%20%23%20Load%20a%20subset%20of%20panel%20series%20(drop%20rows%20with%20nulls)%0A%20%20%20%20panel%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(%0A%20%20%20%20%20%20%20%20%20%20%20%20%22time%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T1__tourists%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T2__tourists%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T3__tourists%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T4__tourists%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%22T5__tourists%22%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20.drop_nulls()%0A%20%20%20%20)%0A%0A%20%20%20%20forecaster_global%20%3D%20PointReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRidge()%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DFeaturePipeline(%5B(%22lags%22%2C%20LagTransformer(lag%3D%5B1%2C%202%2C%203%5D))%5D)%2C%0A%20%20%20%20%20%20%20%20panel_strategy%3D%22global%22%2C%0A%20%20%20%20)%0A%20%20%20%20forecaster_global.fit(panel%2C%20forecasting_horizon%3D6)%0A%20%20%20%20pred_panel%20%3D%20forecaster_global.predict(forecasting_horizon%3D6)%0A%20%20%20%20pred_panel%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%205.%20Choose%20Scale%20Independent%20Metrics%0A%0A%20%20%20%20MASE%20and%20RMSSE%20require%20at%20least%20one%20full%20seasonal%20cycle%20to%20compute%0A%20%20%20%20the%20naive%20baseline.%20For%20short%20series%2C%20use%20MAPE%20or%20WAPE%20instead.%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%20from%20yohou.metrics%20import%20MeanAbsolutePercentageError%0A%0A%20%20%20%20scorer%20%3D%20MeanAbsolutePercentageError()%0A%20%20%20%20print(f%22Scorer%3A%20%7Bscorer%7D%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%20Next%20Steps%0A%0A%20%20%20%20-%20%5BHandle%20Short%20Series%5D(%2Fpages%2Fhow-to%2Fhandle-short-series%2F)%20for%20the%20full%20guide%0A%20%20%20%20-%20%5BHandle%20Long%20Series%5D(%2Fpages%2Fhow-to%2Fhandle-long-series%2F)%20for%20related%20techniques%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
e5c4070f7dc7b877df7dcebc9769d9e8