tinyconformal 0.2.0__tar.gz → 0.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/PKG-INFO +137 -3
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/README.md +127 -1
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/pyproject.toml +15 -3
- tinyconformal-0.2.1/tests/test_mscp.py +488 -0
- tinyconformal-0.2.1/tests/test_tsqcr.py +398 -0
- tinyconformal-0.2.1/tinyconformal/series/__init__.py +7 -0
- tinyconformal-0.2.1/tinyconformal/series/base.py +578 -0
- tinyconformal-0.2.1/tinyconformal/series/mscp.py +348 -0
- tinyconformal-0.2.1/tinyconformal/series/tscqr.py +313 -0
- tinyconformal-0.2.1/tinyconformal/utils/imports.py +71 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal.egg-info/PKG-INFO +137 -3
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal.egg-info/SOURCES.txt +8 -1
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal.egg-info/requires.txt +11 -1
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/LICENSE +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/setup.cfg +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tests/test_classifiers.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tests/test_regressors.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/classifier/__init__.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/classifier/base.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/classifier/class_conditional.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/classifier/marginal.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/regressor/__init__.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/regressor/base.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/regressor/cqr.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/regressor/exactness_bound.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal/regressor/icp.py +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal.egg-info/dependency_links.txt +0 -0
- {tinyconformal-0.2.0 → tinyconformal-0.2.1}/tinyconformal.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinyconformal
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A small toolbox for conformal prediction
|
|
5
5
|
Author-email: Lucas Leão <heylucasleao@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -18,9 +18,17 @@ Requires-Dist: tinyshift[plot]; extra == "plot"
|
|
|
18
18
|
Provides-Extra: notebook
|
|
19
19
|
Requires-Dist: nbformat>=5.10.4; extra == "notebook"
|
|
20
20
|
Requires-Dist: ipykernel>6.7.0; extra == "notebook"
|
|
21
|
+
Provides-Extra: series
|
|
22
|
+
Requires-Dist: statsforecast>=1.4.0; extra == "series"
|
|
23
|
+
Requires-Dist: mlforecast>=0.7.0; extra == "series"
|
|
24
|
+
Requires-Dist: utilsforecast>=0.1.0; extra == "series"
|
|
25
|
+
Provides-Extra: all
|
|
26
|
+
Requires-Dist: tinyshift[notebook,plot,series]; extra == "all"
|
|
21
27
|
Provides-Extra: dev
|
|
22
|
-
Requires-Dist:
|
|
28
|
+
Requires-Dist: tinyshift[all]; extra == "dev"
|
|
23
29
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
30
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
31
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
24
32
|
Dynamic: license-file
|
|
25
33
|
|
|
26
34
|
# TinyConformal
|
|
@@ -36,6 +44,8 @@ For more information on a previous project related to Out-of-Bag (OOB) solutions
|
|
|
36
44
|
- Added support for exactness-bound-based calibration through `ExactnessBound` for ICP and CQR workflows.
|
|
37
45
|
- Added `unlabeled_fit` support for conformal classifiers and regressors, enabling calibration without labeled calibration data when an exactness bound is available.
|
|
38
46
|
- Classifiers can now be calibrated from unlabeled data using pseudo-labels derived from model predictions, while regressors can use a pre-estimated exactness bound to build the conformity scores.
|
|
47
|
+
- Added `tinyconformal.series` support with `ConformalDistributionTimeSeriesRegressor` and `ConformalQuantileTimeSeriesRegressor` for multi-step time series interval forecasting with customizable backtesting strides (`step_size`).
|
|
48
|
+
- Added support for Conformalized Quantile Regression (CQR) on multi-step time series using base estimators producing quantile forecasts.
|
|
39
49
|
|
|
40
50
|
Previously, `calibrate` used `Balanced Accuracy Score`; it can now also be calibrated with `Matthews Correlation Coefficient` or `Bookmaker Informedness Score` for improved reliability. The `evaluate` method also reports `bm` and `mcc`.
|
|
41
51
|
|
|
@@ -85,6 +95,7 @@ TinyConformal is organized into two main submodules:
|
|
|
85
95
|
|
|
86
96
|
- `tinyconformal.classifier`: conformal classifiers for binary classification.
|
|
87
97
|
- `tinyconformal.regressor`: conformal regressors and exactness-bound utilities.
|
|
98
|
+
- `tinyconformal.series`: multi-step conformal prediction for time series forecasting.
|
|
88
99
|
|
|
89
100
|
### Classifier submodule
|
|
90
101
|
|
|
@@ -105,6 +116,13 @@ from tinyconformal.regressor import ConformalizedQuantileRegressor
|
|
|
105
116
|
from tinyconformal.regressor import ExactnessBound
|
|
106
117
|
```
|
|
107
118
|
|
|
119
|
+
### Time Series submodule
|
|
120
|
+
Import from `tinyconformal.series`:
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
from tinyconformal.series import ConformalDistributionTimeSeriesRegressor
|
|
124
|
+
```
|
|
125
|
+
|
|
108
126
|
### Example
|
|
109
127
|
|
|
110
128
|
Example usage of `BinaryClassConditionalConformalClassifier`:
|
|
@@ -134,12 +152,16 @@ For settings where labeled calibration data are unavailable, you can fit the con
|
|
|
134
152
|
```python
|
|
135
153
|
from sklearn.ensemble import RandomForestClassifier
|
|
136
154
|
from tinyconformal.classifier import BinaryMarginalConformalClassifier
|
|
155
|
+
from sklearn.model_selection import cross_val_score
|
|
137
156
|
|
|
138
157
|
learner = RandomForestClassifier(n_estimators=100, oob_score=True)
|
|
139
158
|
learner.fit(X_train, y_train)
|
|
140
159
|
|
|
160
|
+
score = cross_val_score(rf, X_train, y_train, cv=5, scoring='accuracy', n_jobs=-1)
|
|
161
|
+
beta = round(np.mean(1 - score), 3)
|
|
162
|
+
|
|
141
163
|
conformal_classifier = BinaryMarginalConformalClassifier(learner)
|
|
142
|
-
conformal_classifier.unlabeled_fit(X_unlabeled)
|
|
164
|
+
conformal_classifier.unlabeled_fit(X_unlabeled, beta)
|
|
143
165
|
|
|
144
166
|
predictions = conformal_classifier.predict(X_test)
|
|
145
167
|
```
|
|
@@ -173,6 +195,102 @@ results = conformal_classifier.evaluate(X_test, y_test)
|
|
|
173
195
|
print(results)
|
|
174
196
|
```
|
|
175
197
|
|
|
198
|
+
### Time Series Example
|
|
199
|
+
|
|
200
|
+
For point-forecast models, `ConformalDistributionTimeSeriesRegressor` extracts signed empirical residuals ($R = \hat{y} - y$) across backtesting windows to build horizon-specific prediction intervals for Nixtla-style learners (MLForecast or StatsForecast):
|
|
201
|
+
|
|
202
|
+
```python
|
|
203
|
+
from lightgbm import LGBMRegressor
|
|
204
|
+
from mlforecast import MLForecast
|
|
205
|
+
from tinyconformal.series import ConformalDistributionTimeSeriesRegressor
|
|
206
|
+
|
|
207
|
+
# Wrap a base forecaster
|
|
208
|
+
mlf = MLForecast(
|
|
209
|
+
models=[LGBMRegressor(random_state=42)],
|
|
210
|
+
freq="D",
|
|
211
|
+
lags=[1, 7],
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
conformal_ts = ConformalDistributionTimeSeriesRegressor(
|
|
215
|
+
learner=mlf,
|
|
216
|
+
horizon=7,
|
|
217
|
+
n_windows=5,
|
|
218
|
+
step_size=7, # Window displacement stride
|
|
219
|
+
alpha=0.10,
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
conformal_ts.fit(df)
|
|
223
|
+
intervals_df = conformal_ts.predict_interval(h=7)
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
For models outputting lower and upper quantile forecasts, `ConformalQuantileTimeSeriesRegressor` computes CQR nonconformity scores $E = \max(\hat{q}_{\text{low}} - y, y - \hat{q}_{\text{high}})$ to produce calibrated prediction intervals:
|
|
227
|
+
|
|
228
|
+
```python
|
|
229
|
+
from lightgbm import LGBMRegressor
|
|
230
|
+
from mlforecast import MLForecast
|
|
231
|
+
from tinyconformal.series import ConformalQuantileTimeSeriesRegressor
|
|
232
|
+
|
|
233
|
+
# Forecaster configured to output quantile columns
|
|
234
|
+
mlf = MLForecast(
|
|
235
|
+
models=[LGBMRegressor(objective="quantile", alpha=0.05), LGBMRegressor(objective="quantile", alpha=0.95)],
|
|
236
|
+
freq="D",
|
|
237
|
+
lags=[1, 7],
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
conformal_cqr_ts = ConformalQuantileTimeSeriesRegressor(
|
|
241
|
+
learner=mlf,
|
|
242
|
+
horizon=7,
|
|
243
|
+
n_windows=5,
|
|
244
|
+
step_size=7,
|
|
245
|
+
quantile_cols=("LGBM-lo-90", "LGBM-hi-90"),
|
|
246
|
+
alpha=0.10,
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
conformal_cqr_ts.fit(df)
|
|
250
|
+
intervals_df = conformal_cqr_ts.predict_interval(h=7)
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
### Time Series Mechanics: Horizon vs. Step Size
|
|
254
|
+
|
|
255
|
+
When calibrating over time series, nonconformity scores are extracted by performing sequential backtesting across multiple calibration windows. The calibration movement is controlled by two parameters:
|
|
256
|
+
- `horizon` ($H$): The forecast horizon step count generated in each window.
|
|
257
|
+
- `step_size` ($S$): The stride length used to advance the origin between backtesting windows.
|
|
258
|
+
|
|
259
|
+
Below are three typical backtesting movement patterns assuming a forecast horizon ($H = 4$):
|
|
260
|
+
|
|
261
|
+
#### Small `step_size` ($S = 1 < H$) — Overlapping Windows
|
|
262
|
+
The calibration origin advances by 1 step at a time. This creates significant overlap between consecutive forecast windows, maximizing sample size ($n$) for short historical series.
|
|
263
|
+
|
|
264
|
+
```plaintext
|
|
265
|
+
Time Axis: | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10|
|
|
266
|
+
------------------------------------------------------------------
|
|
267
|
+
Window 1: [=== Initial Train ===] [--- H=4 (t5 to t8) ---]
|
|
268
|
+
Window 2: [==== Train + 1 ====] [--- H=4 (t6 to t9) ---] (Shifted S=1)
|
|
269
|
+
Window 3: [===== Train + 2 =====] [--- H=4 (t7 to t10) --] (Shifted S=1)
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
#### Default `step_size` ($S = H = 4$) — Disjoint Windows
|
|
273
|
+
The calibration origin shifts by the full forecast horizon ($S = H$). Each window starts exactly where the previous forecast ended, eliminating overlap and ensuring independence among calibration residuals.
|
|
274
|
+
|
|
275
|
+
```
|
|
276
|
+
Time Axis: | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10| t11| t12|
|
|
277
|
+
----------------------------------------------------------------------------
|
|
278
|
+
Window 1: [=== Initial Train ===] [--- H=4 (t5 to t8) ---]
|
|
279
|
+
Window 2: [======= Expanded Train =======] [--- H=4 (t9 to t12) --] (Shifted S=4)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### Large step_size ($S = 6 > H$) — Windows with Gaps
|
|
283
|
+
The stride between windows exceeds the forecast horizon ($S > H$). This introduces temporal gaps between evaluation windows, mimicking real-world systems with infrequent retraining schedules.
|
|
284
|
+
```plaintext
|
|
285
|
+
Time Axis: | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10| t11| t12| t13| t14|
|
|
286
|
+
----------------------------------------------------------------------------------------
|
|
287
|
+
Window 1: [=== Initial Train ===] [--- H=4 (t5 to t8) ---]
|
|
288
|
+
| | |
|
|
289
|
+
|<- Evaluated Train -->| <-- Gap (t9, t10) -----> | (Shifted S=6)
|
|
290
|
+
| | v
|
|
291
|
+
Window 2: [============ Expanded Train ============] [--- H=4 (t11 to t14) --]
|
|
292
|
+
```
|
|
293
|
+
|
|
176
294
|
## Classes
|
|
177
295
|
|
|
178
296
|
### BinaryMarginalConformalClassifier
|
|
@@ -207,6 +325,22 @@ print(results)
|
|
|
207
325
|
- Training via OOB calibration: `fit(X, y, oob=True)`
|
|
208
326
|
- Training via unlabeled calibration: `unlabeled_fit(X, tilde_beta=..., beta=...)` using an exactness bound
|
|
209
327
|
|
|
328
|
+
### ConformalDistributionTimeSeriesRegressor
|
|
329
|
+
`ConformalDistributionTimeSeriesRegressor` is a multi-step time series conformal regressor compatible with Nixtla interface estimators (`MLForecast` or `StatsForecast`).
|
|
330
|
+
|
|
331
|
+
Training & Residual extraction via backtesting: `fit(df, step_size=...)`
|
|
332
|
+
|
|
333
|
+
Multi-step interval forecasting: `predict_interval(h=..., alpha=...)`
|
|
334
|
+
|
|
335
|
+
### ConformalQuantileTimeSeriesRegressor
|
|
336
|
+
`ConformalQuantileTimeSeriesRegressor` is a multi-step time series conformal quantile regressor (CQR) compatible with Nixtla interface estimators that output quantile predictions.
|
|
337
|
+
|
|
338
|
+
Training & Nonconformity score calculation via backtesting:` fit(df, step_size=...)`
|
|
339
|
+
|
|
340
|
+
Multi-step interval forecasting: `predict_interval(h=..., alpha=...)`
|
|
341
|
+
|
|
342
|
+
ExactnessBound
|
|
343
|
+
|
|
210
344
|
### ExactnessBound
|
|
211
345
|
|
|
212
346
|
`ExactnessBound` provides helper methods to estimate the exactness bound used in unlabeled conformal calibration for ICP and CQR workflows.
|
|
@@ -11,6 +11,8 @@ For more information on a previous project related to Out-of-Bag (OOB) solutions
|
|
|
11
11
|
- Added support for exactness-bound-based calibration through `ExactnessBound` for ICP and CQR workflows.
|
|
12
12
|
- Added `unlabeled_fit` support for conformal classifiers and regressors, enabling calibration without labeled calibration data when an exactness bound is available.
|
|
13
13
|
- Classifiers can now be calibrated from unlabeled data using pseudo-labels derived from model predictions, while regressors can use a pre-estimated exactness bound to build the conformity scores.
|
|
14
|
+
- Added `tinyconformal.series` support with `ConformalDistributionTimeSeriesRegressor` and `ConformalQuantileTimeSeriesRegressor` for multi-step time series interval forecasting with customizable backtesting strides (`step_size`).
|
|
15
|
+
- Added support for Conformalized Quantile Regression (CQR) on multi-step time series using base estimators producing quantile forecasts.
|
|
14
16
|
|
|
15
17
|
Previously, `calibrate` used `Balanced Accuracy Score`; it can now also be calibrated with `Matthews Correlation Coefficient` or `Bookmaker Informedness Score` for improved reliability. The `evaluate` method also reports `bm` and `mcc`.
|
|
16
18
|
|
|
@@ -60,6 +62,7 @@ TinyConformal is organized into two main submodules:
|
|
|
60
62
|
|
|
61
63
|
- `tinyconformal.classifier`: conformal classifiers for binary classification.
|
|
62
64
|
- `tinyconformal.regressor`: conformal regressors and exactness-bound utilities.
|
|
65
|
+
- `tinyconformal.series`: multi-step conformal prediction for time series forecasting.
|
|
63
66
|
|
|
64
67
|
### Classifier submodule
|
|
65
68
|
|
|
@@ -80,6 +83,13 @@ from tinyconformal.regressor import ConformalizedQuantileRegressor
|
|
|
80
83
|
from tinyconformal.regressor import ExactnessBound
|
|
81
84
|
```
|
|
82
85
|
|
|
86
|
+
### Time Series submodule
|
|
87
|
+
Import from `tinyconformal.series`:
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from tinyconformal.series import ConformalDistributionTimeSeriesRegressor
|
|
91
|
+
```
|
|
92
|
+
|
|
83
93
|
### Example
|
|
84
94
|
|
|
85
95
|
Example usage of `BinaryClassConditionalConformalClassifier`:
|
|
@@ -109,12 +119,16 @@ For settings where labeled calibration data are unavailable, you can fit the con
|
|
|
109
119
|
```python
|
|
110
120
|
from sklearn.ensemble import RandomForestClassifier
|
|
111
121
|
from tinyconformal.classifier import BinaryMarginalConformalClassifier
|
|
122
|
+
from sklearn.model_selection import cross_val_score
|
|
112
123
|
|
|
113
124
|
learner = RandomForestClassifier(n_estimators=100, oob_score=True)
|
|
114
125
|
learner.fit(X_train, y_train)
|
|
115
126
|
|
|
127
|
+
score = cross_val_score(rf, X_train, y_train, cv=5, scoring='accuracy', n_jobs=-1)
|
|
128
|
+
beta = round(np.mean(1 - score), 3)
|
|
129
|
+
|
|
116
130
|
conformal_classifier = BinaryMarginalConformalClassifier(learner)
|
|
117
|
-
conformal_classifier.unlabeled_fit(X_unlabeled)
|
|
131
|
+
conformal_classifier.unlabeled_fit(X_unlabeled, beta)
|
|
118
132
|
|
|
119
133
|
predictions = conformal_classifier.predict(X_test)
|
|
120
134
|
```
|
|
@@ -148,6 +162,102 @@ results = conformal_classifier.evaluate(X_test, y_test)
|
|
|
148
162
|
print(results)
|
|
149
163
|
```
|
|
150
164
|
|
|
165
|
+
### Time Series Example
|
|
166
|
+
|
|
167
|
+
For point-forecast models, `ConformalDistributionTimeSeriesRegressor` extracts signed empirical residuals ($R = \hat{y} - y$) across backtesting windows to build horizon-specific prediction intervals for Nixtla-style learners (MLForecast or StatsForecast):
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from lightgbm import LGBMRegressor
|
|
171
|
+
from mlforecast import MLForecast
|
|
172
|
+
from tinyconformal.series import ConformalDistributionTimeSeriesRegressor
|
|
173
|
+
|
|
174
|
+
# Wrap a base forecaster
|
|
175
|
+
mlf = MLForecast(
|
|
176
|
+
models=[LGBMRegressor(random_state=42)],
|
|
177
|
+
freq="D",
|
|
178
|
+
lags=[1, 7],
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
conformal_ts = ConformalDistributionTimeSeriesRegressor(
|
|
182
|
+
learner=mlf,
|
|
183
|
+
horizon=7,
|
|
184
|
+
n_windows=5,
|
|
185
|
+
step_size=7, # Window displacement stride
|
|
186
|
+
alpha=0.10,
|
|
187
|
+
)
|
|
188
|
+
|
|
189
|
+
conformal_ts.fit(df)
|
|
190
|
+
intervals_df = conformal_ts.predict_interval(h=7)
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
For models outputting lower and upper quantile forecasts, `ConformalQuantileTimeSeriesRegressor` computes CQR nonconformity scores $E = \max(\hat{q}_{\text{low}} - y, y - \hat{q}_{\text{high}})$ to produce calibrated prediction intervals:
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from lightgbm import LGBMRegressor
|
|
197
|
+
from mlforecast import MLForecast
|
|
198
|
+
from tinyconformal.series import ConformalQuantileTimeSeriesRegressor
|
|
199
|
+
|
|
200
|
+
# Forecaster configured to output quantile columns
|
|
201
|
+
mlf = MLForecast(
|
|
202
|
+
models=[LGBMRegressor(objective="quantile", alpha=0.05), LGBMRegressor(objective="quantile", alpha=0.95)],
|
|
203
|
+
freq="D",
|
|
204
|
+
lags=[1, 7],
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
conformal_cqr_ts = ConformalQuantileTimeSeriesRegressor(
|
|
208
|
+
learner=mlf,
|
|
209
|
+
horizon=7,
|
|
210
|
+
n_windows=5,
|
|
211
|
+
step_size=7,
|
|
212
|
+
quantile_cols=("LGBM-lo-90", "LGBM-hi-90"),
|
|
213
|
+
alpha=0.10,
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
conformal_cqr_ts.fit(df)
|
|
217
|
+
intervals_df = conformal_cqr_ts.predict_interval(h=7)
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Time Series Mechanics: Horizon vs. Step Size
|
|
221
|
+
|
|
222
|
+
When calibrating over time series, nonconformity scores are extracted by performing sequential backtesting across multiple calibration windows. The calibration movement is controlled by two parameters:
|
|
223
|
+
- `horizon` ($H$): The forecast horizon step count generated in each window.
|
|
224
|
+
- `step_size` ($S$): The stride length used to advance the origin between backtesting windows.
|
|
225
|
+
|
|
226
|
+
Below are three typical backtesting movement patterns assuming a forecast horizon ($H = 4$):
|
|
227
|
+
|
|
228
|
+
#### Small `step_size` ($S = 1 < H$) — Overlapping Windows
|
|
229
|
+
The calibration origin advances by 1 step at a time. This creates significant overlap between consecutive forecast windows, maximizing sample size ($n$) for short historical series.
|
|
230
|
+
|
|
231
|
+
```plaintext
|
|
232
|
+
Time Axis: | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10|
|
|
233
|
+
------------------------------------------------------------------
|
|
234
|
+
Window 1: [=== Initial Train ===] [--- H=4 (t5 to t8) ---]
|
|
235
|
+
Window 2: [==== Train + 1 ====] [--- H=4 (t6 to t9) ---] (Shifted S=1)
|
|
236
|
+
Window 3: [===== Train + 2 =====] [--- H=4 (t7 to t10) --] (Shifted S=1)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
#### Default `step_size` ($S = H = 4$) — Disjoint Windows
|
|
240
|
+
The calibration origin shifts by the full forecast horizon ($S = H$). Each window starts exactly where the previous forecast ended, eliminating overlap and ensuring independence among calibration residuals.
|
|
241
|
+
|
|
242
|
+
```
|
|
243
|
+
Time Axis: | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10| t11| t12|
|
|
244
|
+
----------------------------------------------------------------------------
|
|
245
|
+
Window 1: [=== Initial Train ===] [--- H=4 (t5 to t8) ---]
|
|
246
|
+
Window 2: [======= Expanded Train =======] [--- H=4 (t9 to t12) --] (Shifted S=4)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
#### Large step_size ($S = 6 > H$) — Windows with Gaps
|
|
250
|
+
The stride between windows exceeds the forecast horizon ($S > H$). This introduces temporal gaps between evaluation windows, mimicking real-world systems with infrequent retraining schedules.
|
|
251
|
+
```plaintext
|
|
252
|
+
Time Axis: | t1 | t2 | t3 | t4 | t5 | t6 | t7 | t8 | t9 | t10| t11| t12| t13| t14|
|
|
253
|
+
----------------------------------------------------------------------------------------
|
|
254
|
+
Window 1: [=== Initial Train ===] [--- H=4 (t5 to t8) ---]
|
|
255
|
+
| | |
|
|
256
|
+
|<- Evaluated Train -->| <-- Gap (t9, t10) -----> | (Shifted S=6)
|
|
257
|
+
| | v
|
|
258
|
+
Window 2: [============ Expanded Train ============] [--- H=4 (t11 to t14) --]
|
|
259
|
+
```
|
|
260
|
+
|
|
151
261
|
## Classes
|
|
152
262
|
|
|
153
263
|
### BinaryMarginalConformalClassifier
|
|
@@ -182,6 +292,22 @@ print(results)
|
|
|
182
292
|
- Training via OOB calibration: `fit(X, y, oob=True)`
|
|
183
293
|
- Training via unlabeled calibration: `unlabeled_fit(X, tilde_beta=..., beta=...)` using an exactness bound
|
|
184
294
|
|
|
295
|
+
### ConformalDistributionTimeSeriesRegressor
|
|
296
|
+
`ConformalDistributionTimeSeriesRegressor` is a multi-step time series conformal regressor compatible with Nixtla interface estimators (`MLForecast` or `StatsForecast`).
|
|
297
|
+
|
|
298
|
+
Training & Residual extraction via backtesting: `fit(df, step_size=...)`
|
|
299
|
+
|
|
300
|
+
Multi-step interval forecasting: `predict_interval(h=..., alpha=...)`
|
|
301
|
+
|
|
302
|
+
### ConformalQuantileTimeSeriesRegressor
|
|
303
|
+
`ConformalQuantileTimeSeriesRegressor` is a multi-step time series conformal quantile regressor (CQR) compatible with Nixtla interface estimators that output quantile predictions.
|
|
304
|
+
|
|
305
|
+
Training & Nonconformity score calculation via backtesting:` fit(df, step_size=...)`
|
|
306
|
+
|
|
307
|
+
Multi-step interval forecasting: `predict_interval(h=..., alpha=...)`
|
|
308
|
+
|
|
309
|
+
ExactnessBound
|
|
310
|
+
|
|
185
311
|
### ExactnessBound
|
|
186
312
|
|
|
187
313
|
`ExactnessBound` provides helper methods to estimate the exactness bound used in unlabeled conformal calibration for ICP and CQR workflows.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tinyconformal"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.1"
|
|
4
4
|
description = "A small toolbox for conformal prediction"
|
|
5
5
|
license = "MIT"
|
|
6
6
|
authors = [{name = "Lucas Leão", email = "heylucasleao@gmail.com"}]
|
|
@@ -27,7 +27,19 @@ notebook = [
|
|
|
27
27
|
"ipykernel>6.7.0",
|
|
28
28
|
]
|
|
29
29
|
|
|
30
|
+
series = [
|
|
31
|
+
"statsforecast>=1.4.0",
|
|
32
|
+
"mlforecast>=0.7.0",
|
|
33
|
+
"utilsforecast>=0.1.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
all = [
|
|
37
|
+
"tinyshift[series,plot,notebook]",
|
|
38
|
+
]
|
|
39
|
+
|
|
30
40
|
dev = [
|
|
31
|
-
"
|
|
41
|
+
"tinyshift[all]",
|
|
32
42
|
"pytest>=7.0.0",
|
|
33
|
-
|
|
43
|
+
"ruff>=0.1.0",
|
|
44
|
+
"mypy>=1.0.0",
|
|
45
|
+
]
|