Commit 665ca20f authored by Le Roux Erwan's avatar Le Roux Erwan
Browse files

[EXTREME ESTIMATORS] add full/max_stable/margin estimators and corresponds tests.

parent cacccb60
No related merge requests found
Showing with 255 additions and 76 deletions
+255 -76
......@@ -7,6 +7,10 @@ class AbstractEstimator(object):
DURATION = 'Average duration'
MAE_ERROR = 'Mean Average Error'
# For each estimator, we shall define:
# - The loss
# - The optimization method for each part of the process
def __init__(self, dataset: AbstractDataset):
self.dataset = dataset
self.additional_information = dict()
......
from extreme_estimator.R_fit.gev_fit.abstract_margin_model import AbstractMarginModel
from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import AbstractMaxStableModel
from extreme_estimator.estimator.abstract_estimator import AbstractEstimator
from extreme_estimator.estimator.margin_estimator import SmoothMarginEstimator
from extreme_estimator.estimator.max_stable_estimator import MaxStableEstimator
from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
class AbstractFullEstimator(AbstractEstimator):
pass
class SmoothMarginalsThenUnitaryMsp(AbstractFullEstimator):
def __init__(self, dataset: AbstractDataset, margin_model: AbstractMarginModel,
max_stable_model: AbstractMaxStableModel):
super().__init__(dataset)
# Instantiate the two associated estimators
self.margin_estimator = SmoothMarginEstimator(dataset=dataset, margin_model=margin_model)
self.max_stable_estimator = MaxStableEstimator(dataset=dataset, max_stable_model=max_stable_model)
def _fit(self):
# Estimate the margin parameters
self.margin_estimator.fit()
# Compute the maxima_normalized
maxima_normalized = self.margin_estimator.margin_model.get_maxima_normalized(maxima=self.dataset.maxima,
df_gev_params=self.margin_estimator.df_gev_params)
# Update maxima normalized field through the dataset object
print(maxima_normalized)
self.dataset.maxima_normalized = maxima_normalized
# Estimate the max stable parameters
self.max_stable_estimator.fit()
class FullEstimatorInASingleStep(AbstractFullEstimator):
pass
class FullEstimatorInASingleStepWithSmoothMarginals(AbstractFullEstimator):
"""The method of Gaume, check if its method is in a single step or not"""
pass
class PointwiseAndThenUnitaryMsp(AbstractFullEstimator):
pass
class StochasticExpectationMaximization(AbstractFullEstimator):
pass
class INLAgoesExtremes(AbstractFullEstimator):
pass
from extreme_estimator.estimator.abstract_estimator import AbstractEstimator
class FullEstimatorInASingleStep(AbstractEstimator):
pass
class PointwiseAndThenUnitaryMsp(AbstractEstimator):
pass
class SmoothMarginalsThenUnitaryMsp(AbstractEstimator):
pass
class StochasticExpectationMaximization(AbstractEstimator):
pass
from extreme_estimator.R_fit.gev_fit.abstract_margin_model import AbstractMarginModel
from extreme_estimator.estimator.abstract_estimator import AbstractEstimator
from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
class PointWiseMarginEstimator(AbstractEstimator):
pass
class AbstractMarginEstimator(AbstractEstimator):
def __init__(self, dataset: AbstractDataset):
super().__init__(dataset)
assert dataset.temporal_observations.df_maxima is not None
class SmoothMarginEstimator(AbstractEstimator):
# with different type of marginals: cosntant, linear....
class PointWiseMarginEstimator(AbstractMarginEstimator):
pass
class SmoothMarginEstimator(AbstractMarginEstimator):
"""# with different type of marginals: cosntant, linear...."""
def __init__(self, dataset: AbstractDataset, margin_model: AbstractMarginModel):
super().__init__(dataset)
self.margin_model = margin_model
self.df_gev_params = None
def _fit(self):
self.df_gev_params = self.margin_model.fitmargin(maxima=self.dataset.maxima,
coord=self.dataset.coord)
......@@ -4,7 +4,7 @@ from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
import numpy as np
class MaxStableEstimator(AbstractEstimator):
class AbstractMaxStableEstimator(AbstractEstimator):
def __init__(self, dataset: AbstractDataset, max_stable_model: AbstractMaxStableModel):
super().__init__(dataset=dataset)
......@@ -12,9 +12,14 @@ class MaxStableEstimator(AbstractEstimator):
# Fit parameters
self.max_stable_params_fitted = None
class MaxStableEstimator(AbstractMaxStableEstimator):
def _fit(self):
self.max_stable_params_fitted = self.max_stable_model.fitmaxstab(maxima=self.dataset.maxima,
coord=self.dataset.coord)
assert self.dataset.maxima_normalized is not None
self.max_stable_params_fitted = self.max_stable_model.fitmaxstab(
maxima_normalized=self.dataset.maxima_normalized,
coord=self.dataset.coord)
def _error(self, true_max_stable_params: dict):
absolute_errors = {param_name: np.abs(param_true_value - self.max_stable_params_fitted[param_name])
......
import unittest
from extreme_estimator.estimator.full_estimator import FullEstimatorInASingleStep, \
FullEstimatorInASingleStepWithSmoothMarginals, SmoothMarginalsThenUnitaryMsp
from spatio_temporal_dataset.dataset.simulation_dataset import MarginDataset
from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import CircleCoordinatesRadius1
from test.extreme_estimator.test_margin_estimators import TestMarginEstimators
from test.extreme_estimator.test_max_stable_estimators import TestMaxStableEstimators
from itertools import product
class TestFullEstimators(unittest.TestCase):
DISPLAY = False
FULL_ESTIMATORS = [SmoothMarginalsThenUnitaryMsp]
def setUp(self):
super().setUp()
self.spatial_coord = CircleCoordinatesRadius1.from_nb_points(nb_points=5, max_radius=1)
self.max_stable_models = TestMaxStableEstimators.load_max_stable_models()
self.margin_models = TestMarginEstimators.load_margin_models()
def test_full_estimators(self):
print(self.margin_models, self.max_stable_models)
for margin_model, max_stable_model in product(self.margin_models, self.max_stable_models):
dataset = MarginDataset.from_sampling(nb_obs=10, margin_model=margin_model,
spatial_coordinates=self.spatial_coord)
for estimator_class in self.FULL_ESTIMATORS:
estimator = estimator_class(dataset=dataset, margin_model=margin_model,
max_stable_model=max_stable_model)
estimator.fit()
if self.DISPLAY:
print(type(margin_model))
print(dataset.df_dataset.head())
print(estimator.additional_information)
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
import unittest
import numpy as np
from extreme_estimator.R_fit.gev_fit.abstract_margin_model import ConstantMarginModel
from extreme_estimator.R_fit.gev_fit.gev_mle_fit import GevMleFit
from extreme_estimator.R_fit.utils import get_loaded_r
from extreme_estimator.estimator.margin_estimator import SmoothMarginEstimator
from spatio_temporal_dataset.dataset.simulation_dataset import MarginDataset
from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import CircleCoordinatesRadius1
class TestGevFit(unittest.TestCase):
class TestMarginEstimators(unittest.TestCase):
DISPLAY = False
MARGIN_TYPES = [ConstantMarginModel]
MARGIN_ESTIMATORS = [SmoothMarginEstimator]
def test_unitary_mle_gev_fit(self):
r = get_loaded_r()
......@@ -27,11 +35,29 @@ class TestGevFit(unittest.TestCase):
for key in mle_params_ref.keys():
self.assertAlmostEqual(mle_params_ref[key], mle_params_estimated[key], places=3)
# def test_unitary_frechet_unitary_transformation(self):
# data = np.array([0.0, 1.0])
# # frechet_unitary_transformation()
# self.assertTrue(False)
def setUp(self):
super().setUp()
self.spatial_coord = CircleCoordinatesRadius1.from_nb_points(nb_points=5, max_radius=1)
self.margin_models = self.load_margin_models()
@classmethod
def load_margin_models(cls):
return [margin_class() for margin_class in cls.MARGIN_TYPES]
def test_dependency_estimators(self):
for margin_model in self.margin_models:
dataset = MarginDataset.from_sampling(nb_obs=10, margin_model=margin_model,
spatial_coordinates=self.spatial_coord)
for estimator_class in self.MARGIN_ESTIMATORS:
estimator = estimator_class(dataset=dataset, margin_model=margin_model)
estimator.fit()
if self.DISPLAY:
print(type(margin_model))
print(dataset.df_dataset.head())
print(estimator.additional_information)
self.assertTrue(True)
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
unittest.main()
......@@ -4,33 +4,46 @@ from extreme_estimator.R_fit.max_stable_fit.abstract_max_stable_model import \
AbstractMaxStableModelWithCovarianceFunction, CovarianceFunction
from extreme_estimator.R_fit.max_stable_fit.max_stable_models import Smith, BrownResnick, Schlather, \
Geometric, ExtremalT, ISchlather
from spatio_temporal_dataset.dataset.simulation_dataset import SimulatedDataset
from extreme_estimator.estimator.max_stable_estimator import MaxStableEstimator
from spatio_temporal_dataset.dataset.simulation_dataset import MaxStableDataset
from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import CircleCoordinatesRadius1
class TestMaxStableFit(unittest.TestCase):
MAX_STABLE_CLASSES = [Smith, BrownResnick, Schlather, Geometric, ExtremalT, ISchlather]
class TestMaxStableEstimators(unittest.TestCase):
DISPLAY = False
MAX_STABLE_TYPES = [Smith, BrownResnick, Schlather, Geometric, ExtremalT, ISchlather]
MAX_STABLE_ESTIMATORS = [MaxStableEstimator]
def setUp(self):
super().setUp()
self.spatial_coord = CircleCoordinatesRadius1.from_nb_points(nb_points=5, max_radius=1)
self.max_stable_models = []
for max_stable_class in self.MAX_STABLE_CLASSES:
self.max_stable_models = self.load_max_stable_models()
@classmethod
def load_max_stable_models(cls):
# Load all max stable model
max_stable_models = []
for max_stable_class in cls.MAX_STABLE_TYPES:
if issubclass(max_stable_class, AbstractMaxStableModelWithCovarianceFunction):
self.max_stable_models.extend([max_stable_class(covariance_function=covariance_function)
max_stable_models.extend([max_stable_class(covariance_function=covariance_function)
for covariance_function in CovarianceFunction])
else:
self.max_stable_models.append(max_stable_class())
max_stable_models.append(max_stable_class())
return max_stable_models
def test_sampling_fit_with_models(self, display=False):
def test_max_stable_estimators(self):
for max_stable_model in self.max_stable_models:
dataset = SimulatedDataset.from_max_stable_sampling(nb_obs=10, max_stable_model=max_stable_model,
spatial_coordinates=self.spatial_coord)
fitted_values = max_stable_model.fitmaxstab(maxima=dataset.maxima, coord=dataset.coord)
if display:
print(type(max_stable_model))
print(dataset.df_dataset.head())
print(fitted_values)
dataset = MaxStableDataset.from_sampling(nb_obs=10,
max_stable_model=max_stable_model,
spatial_coordinates=self.spatial_coord)
for estimator_class in self.MAX_STABLE_ESTIMATORS:
estimator = estimator_class(dataset=dataset, max_stable_model=max_stable_model)
estimator.fit()
if self.DISPLAY:
print(type(max_stable_model))
print(dataset.df_dataset.head())
print(estimator.additional_information)
self.assertTrue(True)
......
import unittest
import pandas as pd
class TestPipeline(unittest.TestCase):
def main_pipeline(self):
# Select a type of marginals (either spatial, spatio temporal, temporal)
# this will define the dimension of the climatic space of interest
pass
# Select the max stable
# Define an optimization process
# The algo: In 1 time, in 2 times, ..., or more complex patterns
# This algo have at least main procedures (that might be repeated several times)
# For each procedure, we shall define:
# - The loss
# - The optimization method for each part of the process
def blanchet_smooth_pipeline(self):
pass
# Spatial marginal
# NO MAX STABLE
# Procedure:
# Optimization of a single likelihood process that sums up the likelihood of all the terms.
def padoan_extreme_pipeline(self):
pass
# Spatial marginal
# todo: question, when we are optimizing the full Pairwise loss, are we just optimization the relations ?
# or ideally do we need to add the term of order 1
def gaume(self):
# Combining the 2
pass
def test_pipeline_spatial(self):
pass
# Sample from a
# Fit the spatio temporal experiment margin
# Fit the max stable process
if __name__ == '__main__':
unittest.main()
\ No newline at end of file
import unittest
from spatio_temporal_dataset.spatial_coordinates.alps_station_2D_coordinates import \
AlpsStation2DCoordinatesBetweenZeroAndOne
from spatio_temporal_dataset.spatial_coordinates.alps_station_3D_coordinates import \
AlpsStation3DCoordinatesWithAnisotropy
from spatio_temporal_dataset.spatial_coordinates.generated_coordinates import CircleCoordinatesRadius1
class TestTemporalObservations(unittest.TestCase):
DISPLAY = False
if __name__ == '__main__':
unittest.main()
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment