%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%22numpy%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%20How%20to%20Create%20a%20Custom%20Class-Probability%20Forecaster%0A%0A%20%20%20%20This%20notebook%20implements%20a%20%60MajorityClassForecaster%60%20from%20scratch%2C%0A%20%20%20%20validates%20it%20using%20the%20built-in%20check%20generator%2C%20and%20compares%0A%20%20%20%20its%20predictions%20against%0A%20%20%20%20%5B%60ClassProbaReductionForecaster%60%5D(%2Fpages%2Fapi%2Fgenerated%2Fyohou.class_proba.reduction.ClassProbaReductionForecaster%2F).%0A%0A%20%20%20%20**Prerequisites%3A**%20Familiarity%20with%20the%20fit%2Fpredict%20API%0A%20%20%20%20(%5BGetting%20Started%5D(%2Fpages%2Ftutorials%2Fgetting-started%2F))%20and%0A%20%20%20%20class-probability%20forecasting%0A%20%20%20%20(%5BForecast%20with%20Class%20Probabilities%5D(%2Fpages%2Fhow-to%2Fclass-probability-forecasting%2F)).%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%201.%20Implement%20the%20Forecaster%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%20import%20polars%20as%20pl%0A%0A%20%20%20%20from%20yohou.class_proba.base%20import%20BaseClassProbaForecaster%0A%20%20%20%20from%20yohou.utils.tags%20import%20Tags%0A%0A%20%20%20%20class%20MajorityClassForecaster(BaseClassProbaForecaster)%3A%0A%20%20%20%20%20%20%20%20%22%22%22Predicts%20the%20training-set%20class%20distribution%20at%20every%20step.%22%22%22%0A%0A%20%20%20%20%20%20%20%20def%20__sklearn_tags__(self)%20-%3E%20Tags%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20tags%20%3D%20super().__sklearn_tags__()%0A%20%20%20%20%20%20%20%20%20%20%20%20tags.forecaster_tags.requires_exogenous%20%3D%20False%0A%20%20%20%20%20%20%20%20%20%20%20%20tags.forecaster_tags.stateful%20%3D%20True%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20tags%0A%0A%20%20%20%20%20%20%20%20%40property%0A%20%20%20%20%20%20%20%20def%20_observation_horizon(self)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20return%201%0A%0A%20%20%20%20%20%20%20%20def%20_fit(self%2C%20y_t%2C%20X_t%2C%20forecasting_horizon)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20value_cols%20%3D%20%5Bc%20for%20c%20in%20y_t.columns%20if%20c%20!%3D%20%22time%22%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20self.classes_%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20self.n_classes_%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20self.label_to_code_%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20self._class_probs%20%3D%20%7B%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20col%20in%20value_cols%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20labels%20%3D%20sorted(y_t%5Bcol%5D.unique().to_list())%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.classes_%5Bcol%5D%20%3D%20labels%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.n_classes_%5Bcol%5D%20%3D%20len(labels)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self.label_to_code_%5Bcol%5D%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3A%20i%20for%20i%2C%20label%20in%20enumerate(labels)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20counts%20%3D%20y_t%5Bcol%5D.value_counts()%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20total%20%3D%20len(y_t)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20self._class_probs%5Bcol%5D%20%3D%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20row%5Bcol%5D%3A%20row%5B%22count%22%5D%20%2F%20total%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20row%20in%20counts.iter_rows(named%3DTrue)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20def%20_predict_class_proba_one(self%2C%20groups%2C%20**params)%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20h%20%3D%20self.fit_forecasting_horizon_%0A%20%20%20%20%20%20%20%20%20%20%20%20data%20%3D%20%7B%7D%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20col%2C%20probs%20in%20self._class_probs.items()%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20for%20label%20in%20self.classes_%5Bcol%5D%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20prob%20%3D%20probs.get(label%2C%200.0)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20data%5Bf%22%7Bcol%7D_proba_%7Blabel%7D%22%5D%20%3D%20%5Bprob%5D%20*%20h%0A%0A%20%20%20%20%20%20%20%20%20%20%20%20y_pred%20%3D%20pl.DataFrame(data)%0A%20%20%20%20%20%20%20%20%20%20%20%20y_pred%20%3D%20self._add_time_columns(y_pred)%0A%20%20%20%20%20%20%20%20%20%20%20%20return%20y_pred%0A%0A%20%20%20%20return%20MajorityClassForecaster%2C%20pl%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.%20Prepare%20Categorical%20Data%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(pl)%3A%0A%20%20%20%20import%20datetime%0A%0A%20%20%20%20import%20numpy%20as%20np%0A%0A%20%20%20%20rng%20%3D%20np.random.default_rng(42)%0A%20%20%20%20n%20%3D%20200%0A%20%20%20%20labels%20%3D%20%5B%22low%22%2C%20%22medium%22%2C%20%22high%22%5D%0A%20%20%20%20probs%20%3D%20%5B0.3%2C%200.5%2C%200.2%5D%0A%20%20%20%20values%20%3D%20rng.choice(labels%2C%20size%3Dn%2C%20p%3Dprobs)%0A%0A%20%20%20%20y%20%3D%20pl.DataFrame(%7B%0A%20%20%20%20%20%20%20%20%22time%22%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20datetime.datetime(2020%2C%201%2C%201)%20%2B%20datetime.timedelta(days%3Di)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20i%20in%20range(n)%0A%20%20%20%20%20%20%20%20%5D%2C%0A%20%20%20%20%20%20%20%20%22category%22%3A%20values%2C%0A%20%20%20%20%7D).cast(%7B%22category%22%3A%20pl.String%7D)%0A%0A%20%20%20%20forecasting_horizon%20%3D%2030%0A%0A%20%20%20%20from%20yohou.model_selection%20import%20train_test_split%0A%0A%20%20%20%20y_train%2C%20y_test%20%3D%20train_test_split(y%2C%20test_size%3Dforecasting_horizon)%0A%20%20%20%20y_train.head()%0A%20%20%20%20return%20forecasting_horizon%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%203.%20Fit%20and%20Predict%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(MajorityClassForecaster%2C%20forecasting_horizon%2C%20y_train)%3A%0A%20%20%20%20forecaster%20%3D%20MajorityClassForecaster()%0A%20%20%20%20forecaster.fit(y_train%2C%20forecasting_horizon%3Dforecasting_horizon)%0A%0A%20%20%20%20y_pred%20%3D%20forecaster.predict(forecasting_horizon%3Dforecasting_horizon)%0A%20%20%20%20y_pred_proba%20%3D%20forecaster.predict_class_proba(%0A%20%20%20%20%20%20%20%20forecasting_horizon%3Dforecasting_horizon%2C%0A%20%20%20%20)%0A%0A%20%20%20%20print(%22Hard%20predictions%3A%22)%0A%20%20%20%20print(y_pred.head())%0A%20%20%20%20print(%22%5CnClass%20probabilities%3A%22)%0A%20%20%20%20print(y_pred_proba.head())%0A%20%20%20%20return%20(y_pred_proba%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.%20Verify%20Probabilities%20Sum%20to%201%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(y_pred_proba)%3A%0A%20%20%20%20proba_cols%20%3D%20%5Bc%20for%20c%20in%20y_pred_proba.columns%20if%20%22_proba_%22%20in%20c%5D%0A%20%20%20%20row_sums%20%3D%20y_pred_proba.select(proba_cols).sum_horizontal()%0A%20%20%20%20print(f%22Probability%20sums%20(all%20rows)%3A%20%7Brow_sums.to_list()%5B%3A5%5D%7D%22)%0A%20%20%20%20assert%20all(abs(s%20-%201.0)%20%3C%201e-10%20for%20s%20in%20row_sums.to_list())%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%5BCreate%20a%20Class-Probability%20Forecaster%5D(%2Fpages%2Fhow-to%2Fcreate-a-class-proba-forecaster%2F)%20for%20the%20full%20guide%0A%20%20%20%20-%20%5BForecast%20with%20Class%20Probabilities%5D(%2Fpages%2Fhow-to%2Fclass-probability-forecasting%2F)%20for%20built-in%20approaches%0A%20%20%20%20-%20%5BCreate%20a%20Custom%20Scorer%5D(%2Fpages%2Fhow-to%2Fcreate-a-scorer%2F)%20for%20evaluation%20metrics%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
7d9d28d3620fbffafa872a422fce419d