Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion mkdocstrings_parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
# Suppress griffe warnings
logging.getLogger("griffe").setLevel(logging.ERROR)


class MkDocstringsParser:
def __init__(self):
pass
Expand Down Expand Up @@ -136,6 +135,12 @@ def generate_documentation(self, module_path: str, options: Dict[str, Any]) -> s
markdown_docs = render_object_docs(obj, config) # type: ignore

markdown_docs = markdown_docs.replace(f"### `{to_replace}.", "### `")
# Fix double backslashes in inline/block math equations
markdown_docs = re.sub(
r"\$([^$]+)\$",
lambda m: "$" + m.group(1).replace('\\\\', '\\') + "$",
markdown_docs
)

return markdown_docs

Expand Down
109 changes: 107 additions & 2 deletions tests/test_hierarchicalforecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def test_bottomup(setup_parser):
the first time by Orcutt in 1968.
The corresponding hierarchical "projection" matrix is defined as:
$$
\\\\mathbf{P}_{\\\\text{BU}} = \\[\\\\mathbf{0}_{\\\\mathrm{[b],[a]}};|;\\\\mathbf{I}\\_{\\\\mathrm{[b][b]}}\\]
\\mathbf{P}_{\\text{BU}} = \[\\mathbf{0}_{\\mathrm{[b],[a]}};|;\\mathbf{I}\_{\\mathrm{[b][b]}}\]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit strange. This will not render correctly! For pure latex blocks, we need \ instead of \\, any ideas on how to handle it? was it handled correctly before?

Copy link
Copy Markdown
Author

@nasaul nasaul Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this will not render correctly. The solution is to use the ```math code block syntax as in the alternative solution in here. However I think that first, we need to update the documentation of hierarchicalforecast and then we update the test suite of `mkdocstrings-parser`

$$

<details class="references" open markdown="1">
Expand Down Expand Up @@ -235,4 +235,109 @@ def test_bottomup(setup_parser):
Name | Type | Description
---- | ---- | -----------
`dict` | | y_tilde: Reconciliated y_hat using the Bottom Up approach.
"""
"""

def test_topdown(setup_parser):
fn = """::: hierarchicalforecast.methods.TopDown
handler: python
options:
docstring_style: google
members:
- fit
- predict
- fit_predict
- sample
inherited_members: false
heading_level: 3
show_root_heading: true
show_source: true"""
output = setup_parser.process_markdown(fn)
assert output == """### `TopDown`

```python
TopDown(method)
```

Bases: <code>[HReconciler](#hierarchicalforecast.methods.HReconciler)</code>

Top Down Reconciliation Class.

The Top Down hierarchical reconciliation method, distributes the total aggregate predictions and decomposes
it down the hierarchy using proportions $\mathbf{p}\_{\mathrm{[b]}}$ that can be actual historical values
or estimated.

$$\mathbf{P}=\[\mathbf{p}_{\mathrm{[b]}};|;\mathbf{0}_{\mathrm{[b][a,b;-1]}}\]$$

**Parameters:**

Name | Type | Description | Default
---- | ---- | ----------- | -------
`method` | <code>[str](#str)</code> | One of `forecast_proportions`, `average_proportions` and `proportion_averages`. | *required*

<details class="references" open markdown="1">
<summary>References</summary>

- [CW. Gross (1990). "Disaggregation methods to expedite product line forecasting". Journal of Forecasting, 9 , 233-254. doi:10.1002/for.3980090304](https://onlinelibrary.wiley.com/doi/abs/10.1002/for.3980090304).
- [G. Fliedner (1999). "An investigation of aggregate variable time series forecast strategies with specific subaggregate time series statistical correlation". Computers and Operations Research, 26 , 1133-1149. doi:10.1016/S0305-0548(99)00017-9](<https://doi.org/10.1016/S0305-0548(99)00017-9>).

</details>

#### `TopDown.fit`

```python
fit(S, y_hat, y_insample, y_hat_insample=None, sigmah=None, intervals_method=None, num_samples=None, seed=None, tags=None, idx_bottom=None)
```

TopDown Fit Method.

**Parameters:**

Name | Type | Description | Default
---- | ---- | ----------- | -------
`S` | | Summing matrix of size (`base`, `bottom`). | *required*
`y_hat` | | Forecast values of size (`base`, `horizon`). | *required*
`y_insample` | <code>[ndarray](#numpy.ndarray)</code> | Insample values of size (`base`, `insample_size`). Optional for `forecast_proportions` method. | *required*
`y_hat_insample` | <code>[Optional](#typing.Optional)\[[ndarray](#numpy.ndarray)\]</code> | Insample forecast values of size (`base`, `insample_size`). Optional for `forecast_proportions` method. | <code>None</code>
`sigmah` | <code>[Optional](#typing.Optional)\[[ndarray](#numpy.ndarray)\]</code> | Estimated standard deviation of the conditional marginal distribution. | <code>None</code>
`interval_method` | | Sampler for prediction intervals, one of `normality`, `bootstrap`, `permbu`. | *required*
`num_samples` | <code>[Optional](#typing.Optional)\[[int](#int)\]</code> | Number of samples for probabilistic coherent distribution. | <code>None</code>
`seed` | <code>[Optional](#typing.Optional)\[[int](#int)\]</code> | Seed for reproducibility. | <code>None</code>
`tags` | <code>[Optional](#typing.Optional)\[[dict](#dict)\[[str](#str), [ndarray](#numpy.ndarray)\]\]</code> | Each key is a level and each value its `S` indices. | <code>None</code>
`idx_bottom` | <code>[Optional](#typing.Optional)\[[ndarray](#numpy.ndarray)\]</code> | Indices corresponding to the bottom level of `S`, size (`bottom`). | <code>None</code>

**Returns:**

Name | Type | Description
---- | ---- | -----------
`self` | | object, fitted reconciler.

#### `TopDown.fit_predict`

```python
fit_predict(S, y_hat, tags, idx_bottom=None, y_insample=None, y_hat_insample=None, sigmah=None, level=None, intervals_method=None, num_samples=None, seed=None)
```

Top Down Reconciliation Method.

**Parameters:**

Name | Type | Description | Default
---- | ---- | ----------- | -------
`S` | <code>[ndarray](#numpy.ndarray)</code> | Summing matrix of size (`base`, `bottom`). | *required*
`y_hat` | <code>[ndarray](#numpy.ndarray)</code> | Forecast values of size (`base`, `horizon`). | *required*
`tags` | <code>[dict](#dict)\[[str](#str), [ndarray](#numpy.ndarray)\]</code> | Each key is a level and each value its `S` indices. | *required*
`idx_bottom` | <code>[ndarray](#numpy.ndarray)</code> | Indices corresponding to the bottom level of `S`, size (`bottom`). | <code>None</code>
`y_insample` | <code>[Optional](#typing.Optional)\[[ndarray](#numpy.ndarray)\]</code> | Insample values of size (`base`, `insample_size`). Optional for `forecast_proportions` method. | <code>None</code>
`y_hat_insample` | <code>[Optional](#typing.Optional)\[[ndarray](#numpy.ndarray)\]</code> | Insample forecast values of size (`base`, `insample_size`). Optional for `forecast_proportions` method. | <code>None</code>
`sigmah` | <code>[Optional](#typing.Optional)\[[ndarray](#numpy.ndarray)\]</code> | Estimated standard deviation of the conditional marginal distribution. | <code>None</code>
`level` | <code>[Optional](#typing.Optional)\[[list](#list)\[[int](#int)\]\]</code> | float list 0-100, confidence levels for prediction intervals. | <code>None</code>
`intervals_method` | <code>[Optional](#typing.Optional)\[[str](#str)\]</code> | Sampler for prediction intervals, one of `normality`, `bootstrap`, `permbu`. | <code>None</code>
`num_samples` | <code>[Optional](#typing.Optional)\[[int](#int)\]</code> | Number of samples for probabilistic coherent distribution. | <code>None</code>
`seed` | <code>[Optional](#typing.Optional)\[[int](#int)\]</code> | Seed for reproducibility. | <code>None</code>

**Returns:**

Name | Type | Description
---- | ---- | -----------
`y_tilde` | | Reconciliated y_hat using the Top Down approach.
"""
5 changes: 3 additions & 2 deletions tests/test_utilsforecast.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def test_utilsforecast_rmae(setup_parser):
assert output == """### `rmae`

```python
rmae(df, models, baseline, id_col='unique_id', target_col='y')
rmae(df, models, baseline, id_col='unique_id', target_col='y', cutoff_col='cutoff')
```

Relative Mean Absolute Error (RMAE)
Expand All @@ -30,10 +30,11 @@ def test_utilsforecast_rmae(setup_parser):
`baseline` | <code>[str](#str)</code> | Column that identifies the baseline model predictions. | *required*
`id_col` | <code>[str](#str)</code> | Column that identifies each serie. Defaults to 'unique_id'. | <code>'unique_id'</code>
`target_col` | <code>[str](#str)</code> | Column that contains the target. Defaults to 'y'. | <code>'y'</code>
`cutoff_col` | <code>[str](#str)</code> | Column that identifies the cutoff point for each forecast cross-validation fold. Defaults to 'cutoff'. | <code>'cutoff'</code>

**Returns:**

Type | Description
---- | -----------
<code>[DFType](#utilsforecast.compat.DFType)</code> | pandas or polars DataFrame: dataframe with one row per id and one column per model.
<code>[IntoDataFrameT](#narwhals.stable.v2.typing.IntoDataFrameT)</code> | pandas or polars DataFrame: dataframe with one row per id and one column per model.
"""