From 00deaf7126c688b5e75a38d608a8d8440dfccc03 Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Mon, 23 Mar 2020 20:21:59 +0100 Subject: [PATCH] [quantile regression project] add exp params. refactor annual maxima simulations --- extreme_fit/distribution/exp_params.py | 9 ++++ .../linear_margin_model.py | 6 +-- .../quantile_regression_vs_evt/__init__.py | 0 .../annual_maxima_simulation/__init__.py | 0 .../abstract_annual_maxima_simulation.py | 45 +++++++++++++++++++ .../daily_exp_simulation.py | 26 +++++++++++ .../gev_simulation.py} | 32 +++---------- .../main_quantile_regression.py | 9 ++-- .../annual_maxima_observations.py | 16 +++++++ ...s.py => test_annual_maxima_simulations.py} | 14 +++++- 10 files changed, 120 insertions(+), 37 deletions(-) create mode 100644 extreme_fit/distribution/exp_params.py create mode 100644 projects/quantile_regression_vs_evt/__init__.py create mode 100644 projects/quantile_regression_vs_evt/annual_maxima_simulation/__init__.py create mode 100644 projects/quantile_regression_vs_evt/annual_maxima_simulation/abstract_annual_maxima_simulation.py create mode 100644 projects/quantile_regression_vs_evt/annual_maxima_simulation/daily_exp_simulation.py rename projects/quantile_regression_vs_evt/{GevSimulation.py => annual_maxima_simulation/gev_simulation.py} (61%) rename test/test_projects/test_quantile_regression/{test_gev_simulations.py => test_annual_maxima_simulations.py} (63%) diff --git a/extreme_fit/distribution/exp_params.py b/extreme_fit/distribution/exp_params.py new file mode 100644 index 00000000..6a003ee2 --- /dev/null +++ b/extreme_fit/distribution/exp_params.py @@ -0,0 +1,9 @@ +from extreme_fit.distribution.abstract_params import AbstractParams + + +class ExpParams(object): + PARAM_NAMES = [AbstractParams.SCALE] + + def __init__(self, scale: float): + self.scale = scale + diff --git a/extreme_fit/model/margin_model/linear_margin_model/linear_margin_model.py b/extreme_fit/model/margin_model/linear_margin_model/linear_margin_model.py index 11fcb150..08ac9900 100644 --- a/extreme_fit/model/margin_model/linear_margin_model/linear_margin_model.py +++ b/extreme_fit/model/margin_model/linear_margin_model/linear_margin_model.py @@ -9,9 +9,9 @@ class LinearMarginModel(ParametricMarginModel): @classmethod def from_coef_list(cls, coordinates, gev_param_name_to_coef_list, **kwargs): params = {} - for gev_param_name in GevParams.PARAM_NAMES: - for idx, coef in enumerate(gev_param_name_to_coef_list[gev_param_name], -1): - params[(gev_param_name, idx)] = coef + for param_name, coef_list in gev_param_name_to_coef_list.items(): + for idx, coef in enumerate(coef_list, -1): + params[(param_name, idx)] = coef return cls(coordinates, params_sample=params, params_start_fit=params, **kwargs) def load_margin_functions(self, gev_param_name_to_dims=None): diff --git a/projects/quantile_regression_vs_evt/__init__.py b/projects/quantile_regression_vs_evt/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/projects/quantile_regression_vs_evt/annual_maxima_simulation/__init__.py b/projects/quantile_regression_vs_evt/annual_maxima_simulation/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/projects/quantile_regression_vs_evt/annual_maxima_simulation/abstract_annual_maxima_simulation.py b/projects/quantile_regression_vs_evt/annual_maxima_simulation/abstract_annual_maxima_simulation.py new file mode 100644 index 00000000..74b35ea0 --- /dev/null +++ b/projects/quantile_regression_vs_evt/annual_maxima_simulation/abstract_annual_maxima_simulation.py @@ -0,0 +1,45 @@ +from collections import OrderedDict +from typing import List, Dict + +import numpy as np +from cached_property import cached_property + +from extreme_fit.estimator.quantile_estimator.abstract_quantile_estimator import AbstractQuantileEstimator +from extreme_fit.model.margin_model.abstract_margin_model import AbstractMarginModel +from projects.quantile_regression_vs_evt.AbstractSimulation import AbstractSimulation +from spatio_temporal_dataset.spatio_temporal_observations.abstract_spatio_temporal_observations import \ + AbstractSpatioTemporalObservations + + +class AnnualMaximaSimulation(AbstractSimulation): + + @property + def observations_class(self): + raise NotImplementedError + + @cached_property + def time_series_lengths_to_margin_model(self) -> Dict[int, AbstractMarginModel]: + d = OrderedDict() + for length in self.time_series_lengths: + coordinates = self.time_series_length_to_coordinates[length] + d[length] = self.create_model(coordinates) + return d + + def create_model(self, coordinates): + raise NotImplementedError + + def generate_all_observation(self, nb_time_series, length) -> List[AbstractSpatioTemporalObservations]: + coordinates = self.time_series_length_to_coordinates[length] + margin_model = self.time_series_lengths_to_margin_model[length] + return [self.observations_class.from_sampling(nb_obs=1, coordinates=coordinates, margin_model=margin_model) + for _ in range(nb_time_series)] + + def compute_errors(self, length: int, estimators: List[AbstractQuantileEstimator]): + coordinates = self.time_series_length_to_coordinates[length] + last_coordinate = coordinates.coordinates_values()[-1] + # Compute true value + margin_model = self.time_series_lengths_to_margin_model[length] + true_quantile = margin_model.margin_function_sample.get_gev_params(last_coordinate).quantile(self.quantile) + # Compute estimated values + estimated_quantiles = [estimator.function_from_fit.get_quantile(last_coordinate) for estimator in estimators] + return 100 * np.abs(np.array(estimated_quantiles) - true_quantile) / true_quantile diff --git a/projects/quantile_regression_vs_evt/annual_maxima_simulation/daily_exp_simulation.py b/projects/quantile_regression_vs_evt/annual_maxima_simulation/daily_exp_simulation.py new file mode 100644 index 00000000..fd6ee11f --- /dev/null +++ b/projects/quantile_regression_vs_evt/annual_maxima_simulation/daily_exp_simulation.py @@ -0,0 +1,26 @@ +from extreme_fit.distribution.gev.gev_params import GevParams +from extreme_fit.model.margin_model.linear_margin_model.abstract_temporal_linear_margin_model import \ + TemporalMarginFitMethod +from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import StationaryTemporalModel +from projects.quantile_regression_vs_evt.annual_maxima_simulation.abstract_annual_maxima_simulation import \ + AnnualMaximaSimulation +from spatio_temporal_dataset.spatio_temporal_observations.annual_maxima_observations import DailyExpAnnualMaxima + + +class DailyExpSimulation(AnnualMaximaSimulation): + + @property + def observations_class(self): + return DailyExpAnnualMaxima + + +class StationaryExpSimulation(DailyExpSimulation): + + def create_model(self, coordinates): + gev_param_name_to_coef_list = { + GevParams.SCALE: [1], + } + return StationaryTemporalModel.from_coef_list(coordinates, gev_param_name_to_coef_list, + fit_method=TemporalMarginFitMethod.extremes_fevd_mle) + + diff --git a/projects/quantile_regression_vs_evt/GevSimulation.py b/projects/quantile_regression_vs_evt/annual_maxima_simulation/gev_simulation.py similarity index 61% rename from projects/quantile_regression_vs_evt/GevSimulation.py rename to projects/quantile_regression_vs_evt/annual_maxima_simulation/gev_simulation.py index b14b36e7..decc4818 100644 --- a/projects/quantile_regression_vs_evt/GevSimulation.py +++ b/projects/quantile_regression_vs_evt/annual_maxima_simulation/gev_simulation.py @@ -12,40 +12,20 @@ from extreme_fit.model.margin_model.linear_margin_model.abstract_temporal_linear from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import StationaryTemporalModel, \ NonStationaryLocationTemporalModel from projects.quantile_regression_vs_evt.AbstractSimulation import AbstractSimulation +from projects.quantile_regression_vs_evt.annual_maxima_simulation.abstract_annual_maxima_simulation import \ + AnnualMaximaSimulation from spatio_temporal_dataset.spatio_temporal_observations.abstract_spatio_temporal_observations import \ AbstractSpatioTemporalObservations from spatio_temporal_dataset.spatio_temporal_observations.annual_maxima_observations import MarginAnnualMaxima -class GevSimulation(AbstractSimulation): - @cached_property - def time_series_lengths_to_margin_model(self) -> Dict[int, AbstractMarginModel]: - d = OrderedDict() - for length in self.time_series_lengths: - coordinates = self.time_series_length_to_coordinates[length] - d[length] = self.create_model(coordinates) - return d - def create_model(self, coordinates): - raise NotImplementedError - - def generate_all_observation(self, nb_time_series, length) -> List[AbstractSpatioTemporalObservations]: - coordinates = self.time_series_length_to_coordinates[length] - margin_model = self.time_series_lengths_to_margin_model[length] - return [MarginAnnualMaxima.from_sampling(nb_obs=1, coordinates=coordinates, margin_model=margin_model) - for _ in range(nb_time_series)] - - def compute_errors(self, length: int, estimators: List[AbstractQuantileEstimator]): - coordinates = self.time_series_length_to_coordinates[length] - last_coordinate = coordinates.coordinates_values()[-1] - # Compute true value - margin_model = self.time_series_lengths_to_margin_model[length] - true_quantile = margin_model.margin_function_sample.get_gev_params(last_coordinate).quantile(self.quantile) - # Compute estimated values - estimated_quantiles = [estimator.function_from_fit.get_quantile(last_coordinate) for estimator in estimators] - return 100 * np.abs(np.array(estimated_quantiles) - true_quantile) / true_quantile +class GevSimulation(AnnualMaximaSimulation): + @property + def observations_class(self): + return MarginAnnualMaxima class StationarySimulation(GevSimulation): diff --git a/projects/quantile_regression_vs_evt/main_quantile_regression.py b/projects/quantile_regression_vs_evt/main_quantile_regression.py index 6618762a..b163ad3d 100644 --- a/projects/quantile_regression_vs_evt/main_quantile_regression.py +++ b/projects/quantile_regression_vs_evt/main_quantile_regression.py @@ -1,13 +1,10 @@ -from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import StationaryTemporalModel, \ +from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import \ NonStationaryLocationTemporalModel, NonStationaryLocationGumbelModel -from extreme_fit.model.quantile_model.quantile_regression_model import ConstantQuantileRegressionModel, \ - TemporalCoordinatesQuantileRegressionModel -from projects.quantile_regression_vs_evt.GevSimulation import StationarySimulation, \ +from extreme_fit.model.quantile_model.quantile_regression_model import TemporalCoordinatesQuantileRegressionModel +from projects.quantile_regression_vs_evt.annual_maxima_simulation.gev_simulation import \ NonStationaryLocationGumbelSimulation, NonStationaryLocationGevSimulation from spatio_temporal_dataset.coordinates.transformed_coordinates.transformation.abstract_transformation import \ CenteredScaledNormalization, IdentityTransformation -from spatio_temporal_dataset.coordinates.transformed_coordinates.transformation.uniform_normalization import \ - BetweenZeroAndOneNormalization nb_time_series = 10 quantile = 0.98 diff --git a/spatio_temporal_dataset/spatio_temporal_observations/annual_maxima_observations.py b/spatio_temporal_dataset/spatio_temporal_observations/annual_maxima_observations.py index 7c21358e..93474165 100644 --- a/spatio_temporal_dataset/spatio_temporal_observations/annual_maxima_observations.py +++ b/spatio_temporal_dataset/spatio_temporal_observations/annual_maxima_observations.py @@ -30,6 +30,22 @@ class MarginAnnualMaxima(AnnualMaxima): return cls(df_maxima_gev=df_maxima_gev) +class DailyExpAnnualMaxima(AnnualMaxima): + + @classmethod + def from_sampling(cls, nb_obs: int, coordinates: AbstractCoordinates, + margin_model: AbstractMarginModel): + pass + + +class DailyExp(AbstractSpatioTemporalObservations): + + @classmethod + def from_sampling(cls, nb_obs: int, coordinates: AbstractCoordinates, + margin_model: AbstractMarginModel): + pass + + class MaxStableAnnualMaxima(AnnualMaxima): @classmethod diff --git a/test/test_projects/test_quantile_regression/test_gev_simulations.py b/test/test_projects/test_quantile_regression/test_annual_maxima_simulations.py similarity index 63% rename from test/test_projects/test_quantile_regression/test_gev_simulations.py rename to test/test_projects/test_quantile_regression/test_annual_maxima_simulations.py index b18321f3..ab3de724 100644 --- a/test/test_projects/test_quantile_regression/test_gev_simulations.py +++ b/test/test_projects/test_quantile_regression/test_annual_maxima_simulations.py @@ -4,7 +4,8 @@ from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_m NonStationaryLocationTemporalModel from extreme_fit.model.quantile_model.quantile_regression_model import ConstantQuantileRegressionModel, \ TemporalCoordinatesQuantileRegressionModel -from projects.quantile_regression_vs_evt.GevSimulation import GevSimulation, StationarySimulation, \ +from projects.quantile_regression_vs_evt.annual_maxima_simulation.daily_exp_simulation import StationaryExpSimulation +from projects.quantile_regression_vs_evt.annual_maxima_simulation.gev_simulation import StationarySimulation, \ NonStationaryLocationGumbelSimulation @@ -19,9 +20,18 @@ class TestGevSimulations(unittest.TestCase): def test_non_stationary_run(self): simulation = NonStationaryLocationGumbelSimulation(nb_time_series=1, quantile=0.5, time_series_lengths=[50, 60], model_classes=[NonStationaryLocationTemporalModel, - TemporalCoordinatesQuantileRegressionModel]) + TemporalCoordinatesQuantileRegressionModel]) simulation.plot_error_for_last_year_quantile(self.DISPLAY) +# class TestExpSimulations(unittest.TestCase): +# DISPLAY = True +# +# def test_stationary_run(self): +# simulation = StationaryExpSimulation(nb_time_series=1, quantile=0.5, time_series_lengths=[50, 60], +# model_classes=[StationaryTemporalModel, ConstantQuantileRegressionModel]) +# simulation.plot_error_for_last_year_quantile(self.DISPLAY) + + if __name__ == '__main__': unittest.main() -- GitLab