%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%22optuna%22%2C%0A%23%20%20%20%20%20%22polars%22%2C%0A%23%20%20%20%20%20%22scikit-learn%22%2C%0A%23%20%20%20%20%20%22yohou%22%2C%0A%23%20%20%20%20%20%22yohou-optuna%22%2C%0A%23%20%5D%0A%23%20%2F%2F%2F%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.5%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%20Tune%20on%20Panel%20Data%0A%0A%20%20%20%20Run%20%60OptunaSearchCV%60%20on%20grouped%20time%20series%2C%20compare%20samplers%2C%20and%20use%20%60MaxTrialsCallback%60%20for%20early%20stopping.%0A%0A%20%20%20%20**Prerequisites**%3A%20familiarity%20with%20%5B%60OptunaSearchCV%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou_optuna.search.OptunaSearchCV%2F)%20(see%20%5BOptunaSearchCV%20Quickstart%5D(%2Fexamples%2Foptuna_search%2F))%20and%20panel%20data%20concepts.%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%20optuna%0A%20%20%20%20import%20polars%20as%20pl%0A%20%20%20%20from%20optuna.distributions%20import%20CategoricalDistribution%2C%20FloatDistribution%0A%20%20%20%20from%20sklearn.linear_model%20import%20Ridge%0A%0A%20%20%20%20from%20yohou.datasets%20import%20fetch_tourism_quarterly%0A%20%20%20%20from%20yohou.metrics%20import%20MeanAbsoluteError%0A%20%20%20%20from%20yohou.model_selection%20import%20ExpandingWindowSplitter%0A%20%20%20%20from%20yohou.plotting%20import%20plot_forecast%2C%20plot_splits%2C%20plot_time_series%0A%20%20%20%20from%20yohou.point%20import%20PointReductionForecaster%0A%0A%20%20%20%20from%20yohou_optuna%20import%20Callback%2C%20OptunaSearchCV%2C%20Sampler%0A%0A%20%20%20%20optuna.logging.set_verbosity(optuna.logging.WARNING)%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Callback%2C%0A%20%20%20%20%20%20%20%20CategoricalDistribution%2C%0A%20%20%20%20%20%20%20%20ExpandingWindowSplitter%2C%0A%20%20%20%20%20%20%20%20FloatDistribution%2C%0A%20%20%20%20%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20%20%20%20%20OptunaSearchCV%2C%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%20Sampler%2C%0A%20%20%20%20%20%20%20%20fetch_tourism_quarterly%2C%0A%20%20%20%20%20%20%20%20optuna%2C%0A%20%20%20%20%20%20%20%20plot_forecast%2C%0A%20%20%20%20%20%20%20%20plot_splits%2C%0A%20%20%20%20%20%20%20%20plot_time_series%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%20the%20Panel%20Data%0A%0A%20%20%20%20The%20Tourism%20Quarterly%20dataset%20contains%20quarterly%20tourist%20visit%20counts%20across%0A%20%20%20%20427%20regions.%20Each%20column%20follows%20the%20%60group__member%60%20naming%20convention%0A%20%20%20%20(e.g.%2C%20%60T1__tourists%60)%2C%20which%20yohou%20recognizes%20as%20panel%20data.%20We%20select%0A%20%20%20%208%20regions%20to%20keep%20the%20search%20manageable.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fetch_tourism_quarterly%2C%20plot_time_series)%3A%0A%20%20%20%20y%20%3D%20(%0A%20%20%20%20%20%20%20%20fetch_tourism_quarterly()%0A%20%20%20%20%20%20%20%20.frame.select(%5B%22time%22%5D%20%2B%20%5Bf%22T%7Bi%7D__tourists%22%20for%20i%20in%20range(3%2C%2011)%5D)%0A%20%20%20%20%20%20%20%20.drop_nulls()%0A%20%20%20%20)%0A%20%20%20%20plot_time_series(y%2C%20title%3D%22Tourism%20Quarterly%3A%20Visits%20by%20Region%22)%0A%20%20%20%20return%20(y%2C)%0A%0A%0A%40app.cell%0Adef%20_(y)%3A%0A%20%20%20%20y_train%20%3D%20y.head(60)%0A%20%20%20%20y_test%20%3D%20y.tail(20)%0A%20%20%20%20return%20y_test%2C%20y_train%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.%20Configure%20the%20Splitter%0A%0A%20%20%20%20Set%20up%20an%20%60ExpandingWindowSplitter%60%20and%20visualize%20the%20CV%20strategy%20with%20%60plot_splits%60.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(ExpandingWindowSplitter)%3A%0A%20%20%20%20cv%20%3D%20ExpandingWindowSplitter(n_splits%3D3%2C%20test_size%3D4)%0A%20%20%20%20return%20(cv%2C)%0A%0A%0A%40app.cell%0Adef%20_(cv%2C%20plot_splits%2C%20y_train)%3A%0A%20%20%20%20plot_splits(y_train%2C%20cv%2C%20title%3D%22Expanding%20Window%20CV%20Splits%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.%20Compare%20Samplers%3A%20Random%20vs%20TPE%0A%0A%20%20%20%20Run%20two%20searches%20with%20different%20samplers%20on%20the%20same%20task%20to%20compare%20convergence.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20CategoricalDistribution%2C%0A%20%20%20%20FloatDistribution%2C%0A%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20OptunaSearchCV%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20Sampler%2C%0A%20%20%20%20cv%2C%0A%20%20%20%20optuna%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20param_distributions%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%22estimator__alpha%22%3A%20FloatDistribution(0.001%2C%20100.0%2C%20log%3DTrue)%2C%0A%20%20%20%20%20%20%20%20%22estimator__fit_intercept%22%3A%20CategoricalDistribution(%5BTrue%2C%20False%5D)%2C%0A%20%20%20%20%7D%0A%0A%20%20%20%20random_search%20%3D%20OptunaSearchCV(%0A%20%20%20%20%20%20%20%20forecaster%3DPointReductionForecaster(estimator%3DRidge())%2C%0A%20%20%20%20%20%20%20%20param_distributions%3Dparam_distributions%2C%0A%20%20%20%20%20%20%20%20scoring%3DMeanAbsoluteError()%2C%0A%20%20%20%20%20%20%20%20sampler%3DSampler(sampler%3Doptuna.samplers.RandomSampler%2C%20seed%3D42)%2C%0A%20%20%20%20%20%20%20%20n_trials%3D15%2C%0A%20%20%20%20%20%20%20%20cv%3Dcv%2C%0A%20%20%20%20%20%20%20%20refit%3DTrue%2C%0A%20%20%20%20%20%20%20%20verbose%3D0%2C%0A%20%20%20%20)%0A%20%20%20%20random_search.fit(y_train%2C%20forecasting_horizon%3D4)%0A%20%20%20%20return%20param_distributions%2C%20random_search%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20OptunaSearchCV%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20Sampler%2C%0A%20%20%20%20cv%2C%0A%20%20%20%20optuna%2C%0A%20%20%20%20param_distributions%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20tpe_search%20%3D%20OptunaSearchCV(%0A%20%20%20%20%20%20%20%20forecaster%3DPointReductionForecaster(estimator%3DRidge())%2C%0A%20%20%20%20%20%20%20%20param_distributions%3Dparam_distributions%2C%0A%20%20%20%20%20%20%20%20scoring%3DMeanAbsoluteError()%2C%0A%20%20%20%20%20%20%20%20sampler%3DSampler(sampler%3Doptuna.samplers.TPESampler%2C%20seed%3D42)%2C%0A%20%20%20%20%20%20%20%20n_trials%3D15%2C%0A%20%20%20%20%20%20%20%20cv%3Dcv%2C%0A%20%20%20%20%20%20%20%20refit%3DTrue%2C%0A%20%20%20%20%20%20%20%20verbose%3D0%2C%0A%20%20%20%20)%0A%20%20%20%20tpe_search.fit(y_train%2C%20forecasting_horizon%3D4)%0A%20%20%20%20return%20(tpe_search%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20random_search%2C%20tpe_search)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20%7C%20Sampler%20%7C%20Best%20MAE%20%7C%20Best%20Parameters%20%7C%0A%20%20%20%20%20%20%20%20%7C---------%7C----------%7C-----------------%7C%0A%20%20%20%20%20%20%20%20%7C%20Random%20%20%7C%20%60%7Brandom_search.best_score_%3A.4f%7D%60%20%7C%20%60%7Brandom_search.best_params_%7D%60%20%7C%0A%20%20%20%20%20%20%20%20%7C%20TPE%20%20%20%20%20%7C%20%60%7Btpe_search.best_score_%3A.4f%7D%60%20%7C%20%60%7Btpe_search.best_params_%7D%60%20%7C%0A%20%20%20%20%20%20%20%20%22%22%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%204.%20Use%20Callbacks%20for%20Early%20Stopping%0A%0A%20%20%20%20Pass%20a%20%60MaxTrialsCallback%60%20to%20stop%20the%20search%20after%20a%20fixed%20number%20of%20trials%2C%0A%20%20%20%20regardless%20of%20%60n_trials%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%20Callback%2C%0A%20%20%20%20MeanAbsoluteError%2C%0A%20%20%20%20OptunaSearchCV%2C%0A%20%20%20%20PointReductionForecaster%2C%0A%20%20%20%20Ridge%2C%0A%20%20%20%20Sampler%2C%0A%20%20%20%20cv%2C%0A%20%20%20%20optuna%2C%0A%20%20%20%20param_distributions%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20callback_search%20%3D%20OptunaSearchCV(%0A%20%20%20%20%20%20%20%20forecaster%3DPointReductionForecaster(estimator%3DRidge())%2C%0A%20%20%20%20%20%20%20%20param_distributions%3Dparam_distributions%2C%0A%20%20%20%20%20%20%20%20scoring%3DMeanAbsoluteError()%2C%0A%20%20%20%20%20%20%20%20sampler%3DSampler(sampler%3Doptuna.samplers.TPESampler%2C%20seed%3D42)%2C%0A%20%20%20%20%20%20%20%20n_trials%3D100%2C%0A%20%20%20%20%20%20%20%20cv%3Dcv%2C%0A%20%20%20%20%20%20%20%20refit%3DTrue%2C%0A%20%20%20%20%20%20%20%20verbose%3D0%2C%0A%20%20%20%20%20%20%20%20callbacks%3D%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%22max_trials%22%3A%20Callback(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20callback%3Doptuna.study.MaxTrialsCallback%2C%20n_trials%3D8%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20)%0A%20%20%20%20callback_search.fit(y_train%2C%20forecasting_horizon%3D4)%0A%20%20%20%20return%20(callback_search%2C)%0A%0A%0A%40app.cell%0Adef%20_(callback_search%2C%20mo)%3A%0A%20%20%20%20mo.md(%0A%20%20%20%20%20%20%20%20f%22%22%22%0A%20%20%20%20%20%20%20%20**Completed%20trials%3A**%20%60%7Blen(callback_search.trials_)%7D%60%20(stopped%20early%20by%20MaxTrialsCallback)%0A%0A%20%20%20%20%20%20%20%20**Best%20score%3A**%20%60%7Bcallback_search.best_score_%3A.4f%7D%60%0A%20%20%20%20%20%20%20%20%22%22%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%205.%20Generate%20a%20Panel%20Forecast%0A%0A%20%20%20%20Predict%20with%20the%20best%20TPE%20model%20and%20compare%20against%20the%20held-out%20test%20set.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(tpe_search)%3A%0A%20%20%20%20y_pred%20%3D%20tpe_search.predict(forecasting_horizon%3D4)%0A%20%20%20%20y_pred%0A%20%20%20%20return%20(y_pred%2C)%0A%0A%0A%40app.cell%0Adef%20_(plot_forecast%2C%20y_pred%2C%20y_test%2C%20y_train)%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%20y_pred%2C%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20n_history%3D12%2C%0A%20%20%20%20%20%20%20%20title%3D%22Panel%20Forecast%3A%20Australian%20Tourism%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%5BOptunaSearchCV%20Quickstart%5D(%2Fexamples%2Foptuna_search%2F)%3A%20minimal%20end-to-end%20walkthrough%0A%20%20%20%20-%20%5BHow%20to%20Tune%20Composed%20Forecasters%5D(%2Fexamples%2Fcomposed_tuning%2F)%3A%20tune%20forecasters%20with%20feature%20transformers%0A%20%20%20%20-%20%5BHow%20to%20Visualize%20Search%20Results%5D(%2Fexamples%2Fsearch_visualization%2F)%3A%20Optuna's%20optimization%20plots%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
9e4a03f5598ba18130e2f80c82f9d23b