Skip to content

Commit cae3174

Browse files
authored
[BUG] Fix issue with EncodeNormalizer(method='standard', center=False) for scale value (#1902)
Fixes #1901 Temporarily backported lazywhere implementation from `scipy._lib._util.` to avoid import errors in the `statsmodels` with the latest scipy version.
1 parent b2cfc14 commit cae3174

3 files changed

Lines changed: 25 additions & 4 deletions

File tree

pytorch_forecasting/data/encoders.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,6 @@ def _set_parameters(
664664
)
665665
self.scale_ = (q_75 - q_25) / 2.0 + eps
666666
if not self.center and self.method != "identity":
667-
self.scale_ = self.center_
668667
if isinstance(y_center, torch.Tensor):
669668
self.center_ = torch.zeros_like(self.center_)
670669
else:
@@ -881,8 +880,6 @@ def fit(self, y: Union[pd.Series, np.ndarray, torch.Tensor]):
881880
def min_length(self):
882881
if self.method == "identity":
883882
return 0 # no timeseries properties used
884-
elif self.center:
885-
return 1 # only calculation of mean required
886883
else:
887884
return 2 # requires std, i.e. at least 2 entries
888885

pytorch_forecasting/models/temporal_fusion_transformer/tuning.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from lightning.pytorch.loggers import TensorBoardLogger
1313
from lightning.pytorch.tuner import Tuner
1414
import numpy as np
15+
import scipy._lib._util
1516
from torch.utils.data import DataLoader
1617

1718
from pytorch_forecasting import TemporalFusionTransformer
@@ -22,6 +23,26 @@
2223
optuna_logger = logging.getLogger("optuna")
2324

2425

26+
# ToDo: remove this once statsmodels release a version compatible with latest
27+
# scipy version
28+
def _lazywhere(cond, arrays, f, fillvalue=np.nan, f2=None):
29+
"""
30+
Backported lazywhere implementation (basic version).
31+
"""
32+
arrays = np.broadcast_arrays(*arrays)
33+
cond = np.array(cond, dtype=bool, copy=False)
34+
out = np.full(cond.shape, fillvalue)
35+
if f2 is None:
36+
out[cond] = f(*[a[cond] for a in arrays])
37+
else:
38+
out[cond] = f(*[a[cond] for a in arrays])
39+
out[~cond] = f2(*[a[~cond] for a in arrays])
40+
return out
41+
42+
43+
scipy._lib._util._lazywhere = _lazywhere
44+
45+
2546
def optimize_hyperparameters(
2647
train_dataloaders: DataLoader,
2748
val_dataloaders: DataLoader,

tests/test_metrics.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,10 @@ def test_NegativeBinomialDistributionLoss(center, transformation):
191191
)
192192
samples = loss.sample(rescaled_parameters, 1)
193193
assert torch.isclose(target.mean(), samples.mean(), atol=0.1, rtol=0.5)
194-
assert torch.isclose(target.std(), samples.std(), atol=0.1, rtol=0.5)
194+
if transformation == "log1p" and not center:
195+
assert torch.isclose(target.std(), samples.std(), atol=0.1, rtol=0.8)
196+
else:
197+
assert torch.isclose(target.std(), samples.std(), atol=0.1, rtol=0.5)
195198

196199

197200
@pytest.mark.parametrize(

0 commit comments

Comments
 (0)