Skip to content

Commit 1c9a768

Browse files
docs: address review feedback on seasonal documentation
- Add seasonal ±1% CI parity note to migration-from-r.md - Fix season.duration param notation in compatibility-matrix.md - Improve season_duration examples with clearer use cases - Add nseasons=1 equivalence note and constraint rules to api.md - Define Matching vs Supported status labels in README.md
1 parent 6358830 commit 1c9a768

5 files changed

Lines changed: 16 additions & 10 deletions

File tree

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ Tests run on every commit with seed-fixed MCMC for deterministic reproduction.
122122
| Dynamic regression | Supported | Time-varying coefficients via random-walk FFBS; `dynamic_regression=True` |
123123
| Local linear trend | Supported | Opt in with `state_model="local_linear_trend"` |
124124

125+
Matching = CI-enforced numerical equivalence with R bsts (±3% or tighter).
126+
Supported = Feature implemented, no R parity fixture yet.
127+
125128
Covariate CI bounds are enforced twice: the legacy parity fixture remains tighter than
126129
Phase 2 requirements, and a separate Phase 2 acceptance test keeps the threshold at `±3%`.
127130

docs/api.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ ci = CausalImpact(data, pre_period, post_period, model_args=opts)
5656
| `expected_model_size` | `int` | 2 | Expected number of active covariates for spike-and-slab prior |
5757
| `dynamic_regression` | `bool` | `False` | Enable time-varying regression coefficients |
5858
| `state_model` | `str` | `"local_level"` | `"local_level"` or `"local_linear_trend"` |
59-
| `nseasons` | `int \| None` | `None` | Seasonal cycle count |
60-
| `season_duration` | `int \| None` | `None` | Duration of each seasonal block; defaults to 1 when `nseasons` is set |
59+
| `nseasons` | `int \| None` | `None` | Seasonal cycle count. `nseasons=1` is equivalent to no seasonal component. |
60+
| `season_duration` | `int \| None` | `None` | Duration of each seasonal block; defaults to 1 when `nseasons` is set. Requires `nseasons` to be set. |
6161

6262
## `CausalImpactResults`
6363

docs/compatibility-matrix.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ Comparison of features between R CausalImpact (bsts 1.4.1) and this Python imple
1818
|---|---|---|---|
1919
| niter | Yes | Yes | Same default (1000) |
2020
| nseasons | Yes | Yes | `ModelOptions.nseasons` or `model_args["nseasons"]` |
21-
| season.duration | Yes | Yes | `ModelOptions.season_duration` or `model_args["season.duration"]` |
21+
| season.duration | Yes | Yes | `ModelOptions.season_duration` or `model_args["season_duration"]` (R compat: `"season.duration"`) |
2222
| prior.level.sd | Yes | Yes | Same default (0.01) |
2323
| standardize.data | Yes | Yes | Same default (True) |
2424
| expected.model.size | Yes | Yes | Unified default `2` |

docs/examples.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -192,27 +192,28 @@ the negative sum of the previous `S-1` seasons plus noise.
192192

193193
### Using `season_duration`
194194

195-
When each season spans multiple time steps (e.g., daily data with weekly
196-
seasonality where each day of the week lasts one step), set `season_duration`
197-
accordingly. The seasonal transition only fires at season boundaries
195+
Set `season_duration > 1` when each season spans multiple time steps.
196+
The seasonal transition only fires at season boundaries
198197
(`t % season_duration == 0`); in between, the seasonal state is frozen.
199198

200199
```python
200+
# Using the same data from the seasonal example above
201+
201202
# Daily data with 7-day weekly pattern (default: season_duration=1)
202203
ci = CausalImpact(
203204
data, pre_period, post_period,
204205
model_args={"nseasons": 7, "season_duration": 1, "seed": 42},
205206
)
206207

207-
# Bi-weekly data with 26 two-week seasons per year
208+
# Monthly data with quarterly pattern (each quarter = 3 months)
208209
ci = CausalImpact(
209210
data, pre_period, post_period,
210-
model_args={"nseasons": 26, "season_duration": 2, "seed": 42},
211+
model_args={"nseasons": 4, "season_duration": 3, "seed": 42},
211212
)
212213
```
213214

214215
When `season_duration` is omitted, it defaults to 1 (every time step is a new
215-
season).
216+
season). `nseasons=1` is equivalent to no seasonal component.
216217

217218
---
218219

docs/migration-from-r.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,9 @@ Key differences:
8181

8282
## Numerical Equivalence
8383

84-
This library verifies ±3% agreement with R CausalImpact on point estimates and cumulative effects across multiple test scenarios, including a seasonal fixture. Tests run on every PR.
84+
This library verifies ±3% agreement with R CausalImpact on point estimates and cumulative effects across multiple test scenarios. Tests run on every PR.
85+
86+
The seasonal model uses the same state-space algorithm as R bsts `AddSeasonal()`, achieving ±1% CI parity on the seasonal fixture.
8587

8688
Differences arise from independent RNG implementations (R's `set.seed` vs Rust's `ChaCha8Rng`), not from algorithmic differences.
8789

0 commit comments

Comments
 (0)