From 2bc5363c89dbf5df59e20f6c4ab296440094199a Mon Sep 17 00:00:00 2001 From: Le Roux Erwan <erwan.le-roux@irstea.fr> Date: Fri, 20 Mar 2020 16:29:57 +0100 Subject: [PATCH] [quantile regression project] first stationary run for the gev simulation --- .../AbstractSimulation.py | 28 +++++----- .../GevSimulation.py | 51 ++++++++++++++++--- .../test_gev_simulations.py | 8 ++- 3 files changed, 62 insertions(+), 25 deletions(-) diff --git a/projects/quantile_regression_vs_evt/AbstractSimulation.py b/projects/quantile_regression_vs_evt/AbstractSimulation.py index 3a013a04..14dbb926 100644 --- a/projects/quantile_regression_vs_evt/AbstractSimulation.py +++ b/projects/quantile_regression_vs_evt/AbstractSimulation.py @@ -5,11 +5,14 @@ from collections import OrderedDict import numpy as np from cached_property import cached_property +from extreme_fit.estimator.quantile_estimator.abstract_quantile_estimator import AbstractQuantileEstimator from extreme_fit.estimator.quantile_estimator.quantile_estimator_from_margin import QuantileEstimatorFromMargin from extreme_fit.estimator.quantile_estimator.quantile_estimator_from_regression import QuantileRegressionEstimator from extreme_fit.model.margin_model.linear_margin_model.abstract_temporal_linear_margin_model import \ AbstractTemporalLinearMarginModel from extreme_fit.model.quantile_model.quantile_regression_model import AbstractQuantileRegressionModel +from root_utils import get_display_name_from_object_type +from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoordinates from spatio_temporal_dataset.coordinates.temporal_coordinates.generated_temporal_coordinates import \ ConsecutiveTemporalCoordinates from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset @@ -31,22 +34,18 @@ class AbstractSimulation(object): self.time_series_lengths = time_series_lengths self.nb_time_series = nb_time_series - def generate_all_observation(self, nb_time_series, length, coordinates) -> List[AbstractSpatioTemporalObservations]: + def generate_all_observation(self, nb_time_series, length) -> List[AbstractSpatioTemporalObservations]: raise NotImplementedError @cached_property def time_serie_length_to_observation_list(self) -> Dict[int, List[AbstractSpatioTemporalObservations]]: d = OrderedDict() for length in self.time_series_lengths: - if self.multiprocessing: - raise NotImplementedError - else: - coordinates = self.time_serie_length_to_coordinates[length] - d[length] = self.generate_all_observation(self.nb_time_series, length, coordinates) + d[length] = self.generate_all_observation(self.nb_time_series, length) return d @cached_property - def time_serie_length_to_coordinates(self) -> Dict[int, Coordinates]: + def time_serie_length_to_coordinates(self) -> Dict[int, AbstractCoordinates]: d = OrderedDict() for length in self.time_series_lengths: d[length] = ConsecutiveTemporalCoordinates.from_nb_temporal_steps(length) @@ -83,22 +82,25 @@ class AbstractSimulation(object): for model_class, d_sub in self.model_class_to_time_serie_length_to_estimator_fitted.items(): length_to_error_values = OrderedDict() for length, estimators_fitted in d_sub.items(): - errors = [] - # Add the mean, and the quantile of the 95% confidence interval - error_values = [0.2, 1, 1.3] + errors = self.compute_errors(length, estimators_fitted) + error_values = [np.quantile(errors, q=0.025), np.mean(errors), np.quantile(errors, q=0.975)] length_to_error_values[length] = error_values d[model_class] = length_to_error_values - print(d) return d + def compute_errors(self, length: int, estimators_fitted: List[AbstractQuantileEstimator]): + raise NotImplementedError + def plot_error_for_last_year_quantile(self, show=True): ax = plt.gca() for model_class, length_to_error_values in self.model_class_to_error_last_year_quantile.items(): lengths = list(length_to_error_values.keys()) errors_values = np.array(list(length_to_error_values.values())) - print(errors_values.shape) mean_error = errors_values[:, 1] - ax.plot(lengths, mean_error, label=str(model_class)) + label = get_display_name_from_object_type(model_class) + ax.plot(lengths, mean_error, label=label) + ax.set_xlabel('# Data') + ax.set_ylabel('Absolute error for the {} quantile at the last coordinate'.format(self.quantile)) ax.legend() if show: plt.show() diff --git a/projects/quantile_regression_vs_evt/GevSimulation.py b/projects/quantile_regression_vs_evt/GevSimulation.py index 317c8e83..9ce61302 100644 --- a/projects/quantile_regression_vs_evt/GevSimulation.py +++ b/projects/quantile_regression_vs_evt/GevSimulation.py @@ -1,5 +1,13 @@ -from typing import List +from collections import OrderedDict +from typing import List, Dict +import numpy as np +from cached_property import cached_property + +from extreme_fit.distribution.gev.gev_params import GevParams +from extreme_fit.estimator.quantile_estimator.abstract_quantile_estimator import AbstractQuantileEstimator +from extreme_fit.model.margin_model.abstract_margin_model import AbstractMarginModel +from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import StationaryTemporalModel from projects.quantile_regression_vs_evt.AbstractSimulation import AbstractSimulation from spatio_temporal_dataset.spatio_temporal_observations.abstract_spatio_temporal_observations import \ AbstractSpatioTemporalObservations @@ -8,11 +16,40 @@ from spatio_temporal_dataset.spatio_temporal_observations.annual_maxima_observat class GevSimulation(AbstractSimulation): - def __init__(self, margin_model_class_for_simulation, nb_time_series, quantile, time_series_lengths=None, multiprocessing=False, model_classes=None): - super().__init__(nb_time_series, quantile, time_series_lengths, multiprocessing, model_classes) - self.margin_model_class_for_simulation = margin_model_class_for_simulation + @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_serie_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_serie_length_to_coordinates[length] + margin_model = self.time_series_lengths_to_margin_model[length] + return [MarginAnnualMaxima.from_sampling(nb_obs=length, coordinates=coordinates, margin_model=margin_model) + for _ in range(nb_time_series)] + + def compute_errors(self, length: int, estimators: List[AbstractQuantileEstimator]): + coordinates = self.time_serie_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 np.abs(np.array(estimated_quantiles) - true_quantile) + - def generate_all_observation(self, nb_time_series, length, coordinates) -> List[AbstractSpatioTemporalObservations]: - margin_model = self.margin_model_class_for_simulation(coordinates) - return [MarginAnnualMaxima.from_sampling(nb_obs=length, coordinates=coordinates, margin_model=margin_model) for _ in range(nb_time_series)] +class StationarySimulation(GevSimulation): + def create_model(self, coordinates): + gev_param_name_to_coef_list = { + GevParams.LOC: [0], + GevParams.SHAPE: [0], + GevParams.SCALE: [1], + } + return StationaryTemporalModel.from_coef_list(coordinates, gev_param_name_to_coef_list) diff --git a/test/test_projects/test_quantile_regression/test_gev_simulations.py b/test/test_projects/test_quantile_regression/test_gev_simulations.py index acddcdea..455bd518 100644 --- a/test/test_projects/test_quantile_regression/test_gev_simulations.py +++ b/test/test_projects/test_quantile_regression/test_gev_simulations.py @@ -2,17 +2,15 @@ import unittest from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import StationaryTemporalModel from extreme_fit.model.quantile_model.quantile_regression_model import ConstantQuantileRegressionModel -from projects.quantile_regression_vs_evt.GevSimulation import GevSimulation +from projects.quantile_regression_vs_evt.GevSimulation import GevSimulation, StationarySimulation class TestGevSimulations(unittest.TestCase): DISPLAY = False def test_stationary_run(self): - margin_model_class_for_simulation = StationaryTemporalModel - simulation = GevSimulation(margin_model_class_for_simulation, - nb_time_series=1, quantile=0.5, time_series_lengths=[50, 60], - model_classes=[StationaryTemporalModel, ConstantQuantileRegressionModel]) + simulation = StationarySimulation(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) -- GitLab