%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%20Class-Probability%20Metrics%0A%0A%20%20%20%20Yohou%20provides%20three%20dedicated%20metrics%20for%20evaluating%20categorical%0A%20%20%20%20probability%20forecasts.%20All%20follow%20sklearn's%20%60fit%60%20%2F%20%60score%60%20API%20and%0A%20%20%20%20support%20flexible%20aggregation%20across%20time%20steps%2C%20components%2C%20and%20panel%0A%20%20%20%20groups.%0A%0A%20%20%20%20**Prerequisites%3A**%20Basic%20understanding%20of%20classification%20metrics%20and%20probability%20calibration.%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%20from%20sklearn.ensemble%20import%20RandomForestClassifier%0A%20%20%20%20from%20sklearn.tree%20import%20DecisionTreeClassifier%0A%0A%20%20%20%20from%20yohou.class_proba%20import%20ClassProbaReductionForecaster%0A%20%20%20%20from%20yohou.datasets%20import%20fetch_air_quality_classification%0A%20%20%20%20from%20yohou.metrics%20import%20Accuracy%2C%20BrierScore%2C%20LogLoss%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_calibration%2C%0A%20%20%20%20%20%20%20%20plot_forecast%2C%0A%20%20%20%20%20%20%20%20plot_score_time_series%2C%0A%20%20%20%20%20%20%20%20plot_time_series%2C%0A%20%20%20%20)%0A%20%20%20%20from%20yohou.preprocessing%20import%20LagTransformer%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20Accuracy%2C%0A%20%20%20%20%20%20%20%20BrierScore%2C%0A%20%20%20%20%20%20%20%20ClassProbaReductionForecaster%2C%0A%20%20%20%20%20%20%20%20DecisionTreeClassifier%2C%0A%20%20%20%20%20%20%20%20LagTransformer%2C%0A%20%20%20%20%20%20%20%20LogLoss%2C%0A%20%20%20%20%20%20%20%20RandomForestClassifier%2C%0A%20%20%20%20%20%20%20%20deepcopy%2C%0A%20%20%20%20%20%20%20%20fetch_air_quality_classification%2C%0A%20%20%20%20%20%20%20%20plot_calibration%2C%0A%20%20%20%20%20%20%20%20plot_forecast%2C%0A%20%20%20%20%20%20%20%20plot_score_time_series%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.%20Generate%20Forecasts%0A%0A%20%20%20%20We%20use%20%5B%60fetch_air_quality_classification%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.datasets._fetchers.fetch_air_quality_classification%2F)%0A%20%20%20%20to%20derive%20a%204-class%20air%20quality%20target%20from%20the%20KDD%20Cup%202018%20PM2.5%20data%2C%0A%20%20%20%20then%20fit%20two%20models%20of%20differing%20capacity%3A%20a%20Decision%20Tree%20and%20a%0A%20%20%20%20Random%20Forest.%20Both%20produce%20probability%20forecasts%20via%20rolling%0A%20%20%20%20%60observe_predict_class_proba()%60.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fetch_air_quality_classification%2C%20train_test_split)%3A%0A%20%20%20%20data%20%3D%20fetch_air_quality_classification()%0A%20%20%20%20y%2C%20X_actual%20%3D%20data.y%2C%20data.X_actual%0A%0A%20%20%20%20y_train%2C%20y_test%2C%20X_actual_train%2C%20X_actual_test%20%3D%20train_test_split(%0A%20%20%20%20%20%20%20%20y%2C%0A%20%20%20%20%20%20%20%20X_actual%2C%0A%20%20%20%20%20%20%20%20test_size%3D200%2C%0A%20%20%20%20)%0A%0A%20%20%20%20print(f%22Classes%3A%20%7Bdata.classes%7D%22)%0A%20%20%20%20print(f%22Train%3A%20%7Blen(y_train)%7D%20obs%20%7C%20Test%3A%20%7Blen(y_test)%7D%20obs%22)%0A%20%20%20%20return%20X_actual%2C%20X_actual_test%2C%20X_actual_train%2C%20data%2C%20y%2C%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%23%20Dataset%20Overview%0A%0A%20%20%20%20The%20features%20are%205%20pollutant%20time%20series%20measured%20hourly.%20Visualizing%0A%20%20%20%20them%20helps%20understand%20the%20temporal%20patterns%20the%20models%20must%20learn.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(X_actual%2C%20plot_time_series)%3A%0A%20%20%20%20plot_time_series(X_actual%2C%20title%3D%22Air%20Quality%20-%20Pollutant%20Features%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(data%2C%20y)%3A%0A%20%20%20%20target_col%20%3D%20data.target_names%5B0%5D%0A%20%20%20%20counts%20%3D%20y.group_by(target_col).len().sort(%22len%22%2C%20descending%3DTrue)%0A%20%20%20%20print(%22Class%20distribution%3A%22)%0A%20%20%20%20counts%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%23%20Categorical%20Target%20Over%20Time%0A%0A%20%20%20%20Visualizing%20the%20target%20as%20a%20step%20chart%20reveals%20temporal%20patterns%3A%0A%20%20%20%20transitions%20between%20air%20quality%20classes%20and%20how%20long%20each%20state%20persists.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(plot_forecast%2C%20y%2C%20y_train)%3A%0A%20%20%20%20plot_forecast(%0A%20%20%20%20%20%20%20%20y%2C%0A%20%20%20%20%20%20%20%20y%2C%0A%20%20%20%20%20%20%20%20y_train%3Dy_train%2C%0A%20%20%20%20%20%20%20%20n_history%3D200%2C%0A%20%20%20%20%20%20%20%20title%3D%22Air%20Quality%20Target%20Over%20Time%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20ClassProbaReductionForecaster%2C%0A%20%20%20%20DecisionTreeClassifier%2C%0A%20%20%20%20LagTransformer%2C%0A%20%20%20%20RandomForestClassifier%2C%0A%20%20%20%20X_actual_test%2C%0A%20%20%20%20X_actual_train%2C%0A%20%20%20%20deepcopy%2C%0A%20%20%20%20y_test%2C%0A%20%20%20%20y_train%2C%0A)%3A%0A%20%20%20%20fh%20%3D%2024%0A%0A%20%20%20%20dt%20%3D%20ClassProbaReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DDecisionTreeClassifier(random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%202%2C%203%2C%206%2C%2012%2C%2024%5D)%2C%0A%20%20%20%20)%0A%20%20%20%20dt.fit(y_train%2C%20X_actual_train%2C%20forecasting_horizon%3Dfh)%0A%20%20%20%20dt_hard%20%3D%20deepcopy(dt)%0A%20%20%20%20y_proba_dt%20%3D%20dt.observe_predict_class_proba(y%3Dy_test%2C%20X_actual%3DX_actual_test).sort(%22time%22)%0A%0A%20%20%20%20rf%20%3D%20ClassProbaReductionForecaster(%0A%20%20%20%20%20%20%20%20estimator%3DRandomForestClassifier(n_estimators%3D50%2C%20random_state%3D42)%2C%0A%20%20%20%20%20%20%20%20feature_transformer%3DLagTransformer(lag%3D%5B1%2C%202%2C%203%2C%206%2C%2012%2C%2024%5D)%2C%0A%20%20%20%20)%0A%20%20%20%20rf.fit(y_train%2C%20X_actual_train%2C%20forecasting_horizon%3Dfh)%0A%20%20%20%20rf_hard%20%3D%20deepcopy(rf)%0A%20%20%20%20y_proba_rf%20%3D%20rf.observe_predict_class_proba(y%3Dy_test%2C%20X_actual%3DX_actual_test).sort(%22time%22)%0A%0A%20%20%20%20print(f%22DT%20predictions%3A%20%7Blen(y_proba_dt)%7D%20rows%22)%0A%20%20%20%20print(f%22RF%20predictions%3A%20%7Blen(y_proba_rf)%7D%20rows%22)%0A%20%20%20%20return%20dt_hard%2C%20rf_hard%2C%20y_proba_dt%2C%20y_proba_rf%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%23%20Hard-Label%20Forecast%20Comparison%0A%0A%20%20%20%20Before%20looking%20at%20probabilities%2C%20let's%20compare%20the%20hard%20class%20predictions%0A%20%20%20%20(argmax%20of%20probabilities)%20from%20both%20models%20against%20the%20actual%20classes.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(X_actual_test%2C%20dt_hard%2C%20plot_forecast%2C%20rf_hard%2C%20y_test)%3A%0A%20%20%20%20y_pred_dt%20%3D%20dt_hard.observe_predict(y%3Dy_test%2C%20X_actual%3DX_actual_test).sort(%22time%22)%0A%20%20%20%20y_pred_rf%20%3D%20rf_hard.observe_predict(y%3Dy_test%2C%20X_actual%3DX_actual_test).sort(%22time%22)%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%22Decision%20Tree%22%3A%20y_pred_dt%2C%20%22Random%20Forest%22%3A%20y_pred_rf%7D%2C%0A%20%20%20%20%20%20%20%20title%3D%22Categorical%20Forecast%20Comparison%20(Hard%20Labels)%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%23%20Multi-Model%20Probability%20Forecast%0A%0A%20%20%20%20%5B%60plot_forecast%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.plotting.forecasting.plot_forecast%2F)%0A%20%20%20%20auto-detects%20%60_proba_%60%20columns%20and%20renders%20stacked%20area%20charts.%0A%20%20%20%20Passing%20a%20dict%20of%20predictions%20creates%20one%20subplot%20per%20model%20for%0A%20%20%20%20side-by-side%20comparison.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(plot_forecast%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%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%22Decision%20Tree%22%3A%20y_proba_dt%2C%20%22Random%20Forest%22%3A%20y_proba_rf%7D%2C%0A%20%20%20%20%20%20%20%20title%3D%22Probability%20Forecast%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%202.%20Log%20Loss%0A%0A%20%20%20%20%5B%60LogLoss%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.metrics.class_proba.LogLoss%2F)%20computes%20cross-entropy%20loss%20between%20predicted%20probabilities%0A%20%20%20%20and%20the%20true%20class%20distribution.%20Lower%20values%20indicate%20better-calibrated%0A%20%20%20%20predictions.%20Probabilities%20are%20clipped%20to%20avoid%20infinite%20loss.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(LogLoss%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20ll%20%3D%20LogLoss()%0A%20%20%20%20ll.fit(y_test)%0A%0A%20%20%20%20ll_dt%20%3D%20ll.score(y_test%2C%20y_proba_dt)%0A%20%20%20%20ll_rf%20%3D%20ll.score(y_test%2C%20y_proba_rf)%0A%0A%20%20%20%20print(f%22Log%20Loss%20(Decision%20Tree)%3A%20%20%7Bll_dt%3A.4f%7D%22)%0A%20%20%20%20print(f%22Log%20Loss%20(Random%20Forest)%3A%20%20%7Bll_rf%3A.4f%7D%22)%0A%20%20%20%20return%20ll_dt%2C%20ll_rf%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%23%20Per-Timestep%20Scores%0A%0A%20%20%20%20Set%20%60aggregation%3D%5B%22stepwise%22%2C%20%22vintagewise%22%5D%60%20to%20get%20a%20score%20for%20each%20component.%20This%0A%20%20%20%20reveals%20when%20predictions%20are%20most%20uncertain.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(LogLoss%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20ll_sv%20%3D%20LogLoss(aggregation_method%3D%5B%22stepwise%22%2C%20%22vintagewise%22%5D)%0A%20%20%20%20ll_sv.fit(y_test)%0A%20%20%20%20scores_time%20%3D%20ll_sv.score(y_test%2C%20y_proba_rf)%0A%0A%20%20%20%20print(%22Per-timestep%20Log%20Loss%20(first%2010)%3A%22)%0A%20%20%20%20scores_time.head(10)%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.%20Brier%20Score%0A%0A%20%20%20%20%5B%60BrierScore%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.metrics.class_proba.BrierScore%2F)%20measures%20the%20mean%20squared%20error%20between%20predicted%0A%20%20%20%20probabilities%20and%20one-hot%20truth%20vectors.%20It%20ranges%20from%200%20(perfect)%0A%20%20%20%20to%202%20(worst%20case)%20for%20multi-class%20problems.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(BrierScore%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20bs%20%3D%20BrierScore()%0A%20%20%20%20bs.fit(y_test)%0A%0A%20%20%20%20bs_dt%20%3D%20bs.score(y_test%2C%20y_proba_dt)%0A%20%20%20%20bs_rf%20%3D%20bs.score(y_test%2C%20y_proba_rf)%0A%0A%20%20%20%20print(f%22Brier%20Score%20(Decision%20Tree)%3A%20%20%7Bbs_dt%3A.4f%7D%22)%0A%20%20%20%20print(f%22Brier%20Score%20(Random%20Forest)%3A%20%20%7Bbs_rf%3A.4f%7D%22)%0A%20%20%20%20return%20bs_dt%2C%20bs_rf%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%23%20Componentwise%20Aggregation%0A%0A%20%20%20%20For%20multi-target%20datasets%2C%20%60aggregation%3D%22componentwise%22%60%20returns%20one%0A%20%20%20%20score%20per%20target%20column.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(BrierScore%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20bs_comp%20%3D%20BrierScore(aggregation_method%3D%22componentwise%22)%0A%20%20%20%20bs_comp.fit(y_test)%0A%20%20%20%20scores_comp%20%3D%20bs_comp.score(y_test%2C%20y_proba_rf)%0A%0A%20%20%20%20print(%22Componentwise%20Brier%20Score%3A%22)%0A%20%20%20%20scores_comp%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.%20Accuracy%0A%0A%20%20%20%20%5B%60Accuracy%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.metrics.class_proba.Accuracy%2F)%20converts%20probabilities%20to%20class%20labels%20via%20argmax%0A%20%20%20%20and%20computes%20the%20fraction%20of%20correct%20predictions.%20Higher%20is%20better.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Accuracy%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20acc%20%3D%20Accuracy()%0A%20%20%20%20acc.fit(y_test)%0A%0A%20%20%20%20acc_dt%20%3D%20acc.score(y_test%2C%20y_proba_dt)%0A%20%20%20%20acc_rf%20%3D%20acc.score(y_test%2C%20y_proba_rf)%0A%0A%20%20%20%20print(f%22Accuracy%20(Decision%20Tree)%3A%20%20%7Bacc_dt%3A.4f%7D%22)%0A%20%20%20%20print(f%22Accuracy%20(Random%20Forest)%3A%20%20%7Bacc_rf%3A.4f%7D%22)%0A%20%20%20%20return%20acc_dt%2C%20acc_rf%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.%20Model%20Comparison%20Summary%0A%0A%20%20%20%20Let's%20compare%20all%20three%20metrics%20side-by-side.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(acc_dt%2C%20acc_rf%2C%20bs_dt%2C%20bs_rf%2C%20ll_dt%2C%20ll_rf%2C%20mo)%3A%0A%20%20%20%20_table%20%3D%20mo.ui.table(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%22Metric%22%3A%20%22Log%20Loss%22%2C%20%22Decision%20Tree%22%3A%20f%22%7Bll_dt%3A.4f%7D%22%2C%20%22Random%20Forest%22%3A%20f%22%7Bll_rf%3A.4f%7D%22%2C%20%22Better%22%3A%20%22lower%22%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%22%3A%20%22Brier%20Score%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Decision%20Tree%22%3A%20f%22%7Bbs_dt%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Random%20Forest%22%3A%20f%22%7Bbs_rf%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Better%22%3A%20%22lower%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Metric%22%3A%20%22Accuracy%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Decision%20Tree%22%3A%20f%22%7Bacc_dt%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Random%20Forest%22%3A%20f%22%7Bacc_rf%3A.4f%7D%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%22Better%22%3A%20%22higher%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20selection%3DNone%2C%0A%20%20%20%20)%0A%20%20%20%20mo.md(f%22%22%22%0A%20%20%20%20%23%23%23%20Results%0A%0A%20%20%20%20%7B_table%7D%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%206.%20Visualize%20Predictions%0A%0A%20%20%20%20%5B%60plot_forecast%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.plotting.forecasting.plot_forecast%2F)%20shows%20how%20predicted%20class%20probabilities%20evolve%0A%20%20%20%20over%20time.%20Diamond%20markers%20indicate%20the%20true%20class%20at%20each%20time%20step.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(plot_forecast%2C%20y_proba_rf%2C%20y_test)%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_proba_rf%2C%0A%20%20%20%20%20%20%20%20title%3D%22Random%20Forest%20-%20Class%20Probabilities%20vs%20Actuals%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.%20Reliability%20Diagram%0A%0A%20%20%20%20%5B%60plot_calibration%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.plotting.evaluation.plot_calibration%2F)%20compares%20predicted%20probabilities%20to%20observed%0A%20%20%20%20frequencies.%20A%20well-calibrated%20model%20has%20points%20near%20the%20diagonal.%20This%0A%20%20%20%20helps%20diagnose%20whether%20your%20model%20is%20over-%20or%20under-confident.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(plot_calibration%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20plot_calibration(%0A%20%20%20%20%20%20%20%20y_proba_rf%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20n_bins%3D8%2C%0A%20%20%20%20%20%20%20%20title%3D%22Random%20Forest%20Calibration%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.%20Score%20Over%20Time%0A%0A%20%20%20%20%5B%60plot_score_time_series%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.plotting.evaluation.plot_score_time_series%2F)%0A%20%20%20%20shows%20how%20each%20metric%20evolves%20across%20time%20steps.%20Passing%20a%20dict%20of%0A%20%20%20%20predictions%20overlays%20both%20models%20on%20the%20same%20axes%20for%20easy%20comparison.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(LogLoss%2C%20plot_score_time_series%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20plot_score_time_series(%0A%20%20%20%20%20%20%20%20LogLoss()%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20%7B%22Decision%20Tree%22%3A%20y_proba_dt%2C%20%22Random%20Forest%22%3A%20y_proba_rf%7D%2C%0A%20%20%20%20%20%20%20%20title%3D%22Log%20Loss%20Over%20Time%20-%20Model%20Comparison%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(BrierScore%2C%20plot_score_time_series%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20plot_score_time_series(%0A%20%20%20%20%20%20%20%20BrierScore()%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20%7B%22Decision%20Tree%22%3A%20y_proba_dt%2C%20%22Random%20Forest%22%3A%20y_proba_rf%7D%2C%0A%20%20%20%20%20%20%20%20title%3D%22Brier%20Score%20Over%20Time%20-%20Model%20Comparison%22%2C%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Accuracy%2C%20plot_score_time_series%2C%20y_proba_dt%2C%20y_proba_rf%2C%20y_test)%3A%0A%20%20%20%20plot_score_time_series(%0A%20%20%20%20%20%20%20%20Accuracy()%2C%0A%20%20%20%20%20%20%20%20y_test%2C%0A%20%20%20%20%20%20%20%20%7B%22Decision%20Tree%22%3A%20y_proba_dt%2C%20%22Random%20Forest%22%3A%20y_proba_rf%7D%2C%0A%20%20%20%20%20%20%20%20title%3D%22Accuracy%20Over%20Time%20-%20Model%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%20Next%20Steps%0A%0A%20%20%20%20-%20%5B%60class_proba_forecaster.py%60%5D(%2Fexamples%2Fpoint%2Fclass_proba_forecaster%2F)%20-%20Full%20class-probability%20forecasting%20walkthrough%0A%20%20%20%20-%20%5B%60point_metrics.py%60%5D(%2Fexamples%2Fevaluation-search%2Fpoint_metrics%2F)%20-%20Point%20forecast%20evaluation%20metrics%0A%20%20%20%20-%20%5B%60aggregation_modes.py%60%5D(%2Fexamples%2Fevaluation-search%2Faggregation_modes%2F)%20-%20Deep%20dive%20into%20aggregation%20modes%0A%20%20%20%20-%20%5BMetrics%5D(%2Fexamples%2F%23metrics)%20-%20All%20metric%20examples%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
6731259ffa4bc0605fac8f0ca23a1b1f