Skip to content

Commit ad7470e

Browse files
authored
FIX : properly deprecate TimeSeriesRegressor.partial_fit method (issue #699) (#738)
1 parent 36db891 commit ad7470e

File tree

5 files changed

+474
-476
lines changed

5 files changed

+474
-476
lines changed

AUTHORS.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,5 @@ Contributors
5050
* Brijesh Thummar <[email protected]>
5151
* Faustin Pulvéric <[email protected]>
5252
* Chaoqi Zhang <[email protected]>
53+
* Leena Kamran Qidwai
5354
To be continued ...

HISTORY.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ History
1313
* Add FAQ entry in the documentation about ongoing works to extend MAPIE for LLM control
1414
* MAPIE now supports Python versions up to the latest release (currently 3.13)
1515
* Change `prefit` default value to `True` in split methods' docstrings to remain consistent with the implementation
16+
* Fix issue 699 to replace `TimeSeriesRegressor.partial_fit` with `TimeSeriesRegressor.update`
1617

1718
1.0.1 (2025-05-22)
1819
------------------

examples/regression/2-advanced-analysis/plot_timeseries_enbpi.py

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,9 @@
2525
in which the training set is prior to the validation set.
2626
The best model is then feeded into
2727
:class:`~mapie.time_series_regression.TimeSeriesRegressor` to estimate the
28-
associated prediction intervals. We compare two approaches: with or without
29-
``partial_fit`` called at every step following [6]. It appears that
30-
``partial_fit`` offer a coverage closer to the targeted coverage, and with
31-
narrower PIs.
28+
associated prediction intervals. We compare two approaches: with or without calling
29+
``update`` at every step, following [6]. The results show coverage closer
30+
to the target, along with narrower PIs.
3231
"""
3332

3433
import warnings
@@ -123,88 +122,88 @@
123122
n_jobs=-1,
124123
)
125124

126-
print("EnbPI, with no partial_fit, width optimization")
125+
print("EnbPI, with no update, width optimization")
127126
mapie_enpbi = mapie_enpbi.fit(X_train, y_train)
128-
y_pred_npfit_enbpi, y_pis_npfit_enbpi = mapie_enpbi.predict(
127+
y_pred_n_update_enbpi, y_pis_n_update_enbpi = mapie_enpbi.predict(
129128
X_test, confidence_level=1-alpha, ensemble=True, optimize_beta=True
130129
)
131-
coverage_npfit_enbpi = regression_coverage_score(
132-
y_test, y_pis_npfit_enbpi
130+
coverage_n_update_enbpi = regression_coverage_score(
131+
y_test, y_pis_n_update_enbpi
133132
)[0]
134133

135-
width_npfit_enbpi = regression_mean_width_score(
136-
y_pis_npfit_enbpi
134+
width_n_update_enbpi = regression_mean_width_score(
135+
y_pis_n_update_enbpi
137136
)[0]
138137

139-
print("EnbPI with partial_fit, width optimization")
138+
print("EnbPI with update, width optimization")
140139
mapie_enpbi = mapie_enpbi.fit(X_train, y_train)
141-
y_pred_pfit_enbpi = np.zeros(y_pred_npfit_enbpi.shape)
142-
y_pis_pfit_enbpi = np.zeros(y_pis_npfit_enbpi.shape)
140+
y_pred_update_enbpi = np.zeros(y_pred_n_update_enbpi.shape)
141+
y_pis_update_enbpi = np.zeros(y_pis_n_update_enbpi.shape)
143142

144143
step_size = 1
145144
(
146-
y_pred_pfit_enbpi[:step_size],
147-
y_pis_pfit_enbpi[:step_size, :, :],
145+
y_pred_update_enbpi[:step_size],
146+
y_pis_update_enbpi[:step_size, :, :],
148147
) = mapie_enpbi.predict(
149148
X_test.iloc[:step_size, :], confidence_level=1-alpha, ensemble=True,
150149
optimize_beta=True
151150
)
152151

153152
for step in range(step_size, len(X_test), step_size):
154-
mapie_enpbi.partial_fit(
153+
mapie_enpbi.update(
155154
X_test.iloc[(step - step_size):step, :],
156155
y_test.iloc[(step - step_size):step],
157156
)
158157
(
159-
y_pred_pfit_enbpi[step:step + step_size],
160-
y_pis_pfit_enbpi[step:step + step_size, :, :],
158+
y_pred_update_enbpi[step:step + step_size],
159+
y_pis_update_enbpi[step:step + step_size, :, :],
161160
) = mapie_enpbi.predict(
162161
X_test.iloc[step:(step + step_size), :],
163162
confidence_level=1-alpha,
164163
ensemble=True,
165164
)
166-
coverage_pfit_enbpi = regression_coverage_score(
167-
y_test, y_pis_pfit_enbpi
165+
coverage_update_enbpi = regression_coverage_score(
166+
y_test, y_pis_update_enbpi
168167
)[0]
169-
width_pfit_enbpi = regression_mean_width_score(
170-
y_pis_pfit_enbpi
168+
width_update_enbpi = regression_mean_width_score(
169+
y_pis_update_enbpi
171170
)[0]
172171

173172
# Print results
174173
print(
175174
"Coverage / prediction interval width mean for TimeSeriesRegressor: "
176-
"\nEnbPI without any partial_fit:"
177-
f"{coverage_npfit_enbpi:.3f}, {width_npfit_enbpi:.3f}"
175+
"\nEnbPI without any update:"
176+
f"{coverage_n_update_enbpi:.3f}, {width_n_update_enbpi:.3f}"
178177
)
179178
print(
180179
"Coverage / prediction interval width mean for TimeSeriesRegressor: "
181-
"\nEnbPI with partial_fit:"
182-
f"{coverage_pfit_enbpi:.3f}, {width_pfit_enbpi:.3f}"
180+
"\nEnbPI with update:"
181+
f"{coverage_update_enbpi:.3f}, {width_update_enbpi:.3f}"
183182
)
184183

185-
enbpi_no_pfit = {
186-
"y_pred": y_pred_npfit_enbpi,
187-
"y_pis": y_pis_npfit_enbpi,
188-
"coverage": coverage_npfit_enbpi,
189-
"width": width_npfit_enbpi,
184+
enbpi_no_update = {
185+
"y_pred": y_pred_n_update_enbpi,
186+
"y_pis": y_pis_n_update_enbpi,
187+
"coverage": coverage_n_update_enbpi,
188+
"width": width_n_update_enbpi,
190189
}
191190

192-
enbpi_pfit = {
193-
"y_pred": y_pred_pfit_enbpi,
194-
"y_pis": y_pis_pfit_enbpi,
195-
"coverage": coverage_pfit_enbpi,
196-
"width": width_pfit_enbpi,
191+
enbpi_update = {
192+
"y_pred": y_pred_update_enbpi,
193+
"y_pis": y_pis_update_enbpi,
194+
"coverage": coverage_update_enbpi,
195+
"width": width_update_enbpi,
197196
}
198197

199-
results = [enbpi_no_pfit, enbpi_pfit]
198+
results = [enbpi_no_update, enbpi_update]
200199

201200
# Plot estimated prediction intervals on test set
202201
fig, axs = plt.subplots(
203202
nrows=2, ncols=1, figsize=(15, 12), sharex="col"
204203
)
205204

206205
for i, (ax, w, result) in enumerate(
207-
zip(axs, ["EnbPI, without partial_fit", "EnbPI with partial_fit"], results)
206+
zip(axs, ["EnbPI, without update", "EnbPI with update"], results)
208207
):
209208
ax.set_ylabel("Hourly demand (GW)", fontsize=20)
210209
ax.plot(demand_test.Demand, lw=2, label="Test data", c="C1")

mapie/regression/time_series_regression.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ def partial_fit(
163163
"""
164164
warnings.warn(
165165
"WARNING: Deprecated method. "
166-
+ "The method \"partial_fit\" is outdated. "
167-
+ "Prefer to use \"update\" instead to keep "
166+
+ "The method \"partial_fit\" will be removed in v1.2. "
167+
+ "Use \"update\" instead to keep "
168168
+ "the same behavior in the future.",
169169
DeprecationWarning
170170
)

notebooks/regression/ts-changepoint.ipynb

Lines changed: 433 additions & 436 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)