Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion src/nemo_spinup_forecast/dimensionality_reduction.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ def rmse(self, n):

return reconstruction, rmse_values, rmse_map

def rmseValues(self, reconstruction):
def rmse_values(self, reconstruction):
"""RMSE per time sample.

Parameters
Expand Down
31 changes: 13 additions & 18 deletions src/nemo_spinup_forecast/forecast_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ class RecursiveForecaster(BaseForecaster):
Number of lagged values of the target to include as features.
window_size : int, default=10
Size of the rolling window used to compute additional statistics.
steps : int, default=30
Number of future steps to forecast.

Attributes
----------
Expand All @@ -139,11 +137,9 @@ class RecursiveForecaster(BaseForecaster):
Number of lags used in forecasting.
window_size : int
Rolling window size for feature engineering.
steps : int
Horizon length for recursive forecasting.
"""

def __init__(self, regressor, lags=10, window_size=10, steps=30):
def __init__(self, regressor, lags=10, window_size=10):
"""
Initialize the recursive forecaster.

Expand All @@ -155,37 +151,35 @@ def __init__(self, regressor, lags=10, window_size=10, steps=30):
See class docstring.
window_size : int, default=10
See class docstring.
steps : int, default=30
See class docstring.
"""
self.regressor = regressor
self.lags = lags
self.window_size = window_size
self.steps = steps

def apply_forecast(self, y_train, _x_train, _x_pred):
def apply_forecast(self, y_train, _x_train, x_pred):
"""
Fit a recursive forecaster using the provided regressor.

Parameters
----------
y_train : array-like
Training target series.
_x_train : array-like, optional
Not used directly in this recursive implementation.
_x_pred : array-like, optional
Not used directly in this recursive implementation.
_x_train : array-like
Not used in this recursive implementation.
x_pred : array-like
Feature matrix whose first dimension determines the number of
forecast steps.

Returns
-------
tuple
``(y_hat, y_hat_std)`` where:

* **y_hat** : ndarray
Predicted values for the next `steps` periods.
Predicted values for ``x_pred.shape[0]`` periods.
* **y_hat_std** : ndarray
Returned here as a placeholder equal to ``y_hat`` since the
recursive strategy used does not compute prediction intervals.
Placeholder equal to ``y_hat`` since the recursive strategy
does not compute prediction intervals.

Notes
-----
Expand All @@ -209,7 +203,8 @@ def apply_forecast(self, y_train, _x_train, _x_pred):
forecaster.fit(pd.Series(y_train))

# Predict the specified steps
y_hat = forecaster.predict(steps=self.steps)
steps = x_pred.shape[0]
y_hat = forecaster.predict(steps=steps)

# Recursive forecaster does not return standard deviation for each point
# Use y_hat as a placeholder for std
Expand Down Expand Up @@ -275,7 +270,7 @@ def create_gp_regressor(


gp_recursive_forecaster = RecursiveForecaster(
create_gp_regressor(), lags=10, window_size=10, steps=30
create_gp_regressor(), lags=10, window_size=10
)
gp_forecaster = DirectForecaster(create_gp_regressor())

Expand Down
48 changes: 31 additions & 17 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,49 @@
from importlib.resources import files

import pytest

from nemo_spinup_forecast.dimensionality_reduction import (
dimensionality_reduction_techniques,
DimensionalityReductionKernelPCA,
DimensionalityReductionPCA,
)
from nemo_spinup_forecast.forecast import Predictions, Simulation, load_ts
from nemo_spinup_forecast.forecast_method import forecast_techniques
from nemo_spinup_forecast.utils import (
create_run_dir,
get_dr_technique,
get_forecast_technique,
prepare,
)

# Resolve packaged config file (no reliance on repo root layout)
tech_cfg = files("nemo_spinup_forecast.configs").joinpath("techniques_config.yaml")
DR_PARAMS = [
(DimensionalityReductionPCA, 0.9),
(DimensionalityReductionKernelPCA, 4),
]


@pytest.fixture(
params=DR_PARAMS,
ids=["PCA", "KernelPCA"],
)
def dr_technique(request):
"""Return a (DR class, comp) tuple."""
return request.param


dr_technique = get_dr_technique(tech_cfg, dimensionality_reduction_techniques)
forecast_technique = get_forecast_technique(tech_cfg, forecast_techniques)
@pytest.fixture(
params=list(forecast_techniques.values()),
ids=list(forecast_techniques.keys()),
)
def forecast_technique(request):
"""Return the forecast technique instance."""
return request.param


@pytest.fixture()
def setup_simulation_class(request):
def setup_simulation_class(request, dr_technique):
"""Fixture to set up the simulation class."""
# Parameters for the simulation class
dr_class, comp = dr_technique
path = "tests/data/nemo_data_e3/"
start = 20 # Start year for the simulation
end = 50 # End year for the simulation
ye = True # Indicates if the simulation is yearly
comp = 0.9 # Explained variance ratio for PCA
term, filename = request.param # Tuple (phycial property/term, file)

simu = Simulation(
Expand All @@ -40,15 +54,16 @@ def setup_simulation_class(request):
comp=comp,
term=term,
filename=filename,
dimensionality_reduction=dr_technique,
dimensionality_reduction=dr_class,
)

return simu


@pytest.fixture()
def setup_prediction_class(request):
def setup_prediction_class(request, dr_technique, forecast_technique):
"""Fixture to set up a prediction class."""
dr_class, comp = dr_technique
# create a per-run directory to store results
run_dir = create_run_dir("tests/data/nemo_data_e3/")
out_dir = run_dir / "forecasts"
Expand All @@ -60,13 +75,12 @@ def setup_prediction_class(request):
start = 20
end = 50
ye = True # Indicates if the simulation is yearly
comp = 0.9 # Explained variance ratio for PCA

# Applies PCA and saves the results to disk
prepare(term, filename, path, start, end, ye, comp, dr_technique)
# Applies DR technique and saves the results to disk
prepare(term, filename, path, start, end, ye, comp, dr_class)

df, infos = load_ts(f"{path}/simu_prepared/{term}", term)

simu_ts = Predictions(term, df, infos, forecast_technique, dr_technique)
simu_ts = Predictions(term, df, infos, forecast_technique, dr_class)

return simu_ts, infos
Loading
Loading