Commit 83e4de9b authored by Le Roux Erwan's avatar Le Roux Erwan
Browse files

[COORDINATES] add some normalization class for the coordinate, add a...

[COORDINATES] add some normalization class for the coordinate, add a normalization function for the observations.
parent c6b874f5
No related merge requests found
Showing with 77 additions and 17 deletions
+77 -17
...@@ -18,8 +18,9 @@ from utils import get_display_name_from_object_type ...@@ -18,8 +18,9 @@ from utils import get_display_name_from_object_type
class AbstractNonStationaryTrendTest(object): class AbstractNonStationaryTrendTest(object):
RESULT_ATTRIBUTE_METRIC = 'deviance' RESULT_ATTRIBUTE_METRIC = 'deviance'
def __init__(self, dataset: AbstractDataset, estimator_class, def __init__(self, dataset: AbstractDataset, verbose, estimator_class,
stationary_margin_model_class, non_stationary_margin_model_class): stationary_margin_model_class, non_stationary_margin_model_class):
self.verbose = verbose
self.dataset = dataset self.dataset = dataset
self.estimator_class = estimator_class self.estimator_class = estimator_class
self.stationary_margin_model_class = stationary_margin_model_class self.stationary_margin_model_class = stationary_margin_model_class
...@@ -33,9 +34,10 @@ class AbstractNonStationaryTrendTest(object): ...@@ -33,9 +34,10 @@ class AbstractNonStationaryTrendTest(object):
if (margin_model_class, starting_point) not in self._margin_model_class_and_starting_point_to_estimator: if (margin_model_class, starting_point) not in self._margin_model_class_and_starting_point_to_estimator:
margin_model = margin_model_class(coordinates=self.dataset.coordinates, starting_point=starting_point) margin_model = margin_model_class(coordinates=self.dataset.coordinates, starting_point=starting_point)
estimator = self._load_estimator(margin_model) estimator = self._load_estimator(margin_model)
estimator_name = get_display_name_from_object_type(estimator) if self.verbose:
margin_model_name = get_display_name_from_object_type(margin_model) estimator_name = get_display_name_from_object_type(estimator)
print('Fitting {} with margin: {} for starting_point={}'.format(estimator_name, margin_model_name, starting_point)) margin_model_name = get_display_name_from_object_type(margin_model)
print('Fitting {} with margin: {} for starting_point={}'.format(estimator_name, margin_model_name, starting_point))
estimator.fit() estimator.fit()
self._margin_model_class_and_starting_point_to_estimator[(margin_model_class, starting_point)] = estimator self._margin_model_class_and_starting_point_to_estimator[(margin_model_class, starting_point)] = estimator
return self._margin_model_class_and_starting_point_to_estimator[(margin_model_class, starting_point)] return self._margin_model_class_and_starting_point_to_estimator[(margin_model_class, starting_point)]
...@@ -79,12 +81,15 @@ class AbstractNonStationaryTrendTest(object): ...@@ -79,12 +81,15 @@ class AbstractNonStationaryTrendTest(object):
mu1_trends = [self.get_mu1(starting_point=year) for year in years] mu1_trends = [self.get_mu1(starting_point=year) for year in years]
ax2 = ax.twinx() ax2 = ax.twinx()
color_mu1 = 'c' color_mu1 = 'c'
print(mu1_trends)
if self.verbose:
print(mu1_trends)
ax2.plot(years, mu1_trends, color_mu1 + 'o-') ax2.plot(years, mu1_trends, color_mu1 + 'o-')
ax2.set_ylabel('mu1 parameter', color=color_mu1) ax2.set_ylabel('mu1 parameter', color=color_mu1)
ax.set_xlabel('starting year for the linear trend of mu1') ax.set_xlabel('starting year for the linear trend of mu1')
# align_yaxis_on_zero(ax, ax2) if min(mu1_trends) < 0.0 < max(mu1_trends):
align_yaxis_on_zero(ax, ax2)
title = self.display_name title = self.display_name
ax.set_title(title) ax.set_title(title)
ax.legend() ax.legend()
...@@ -94,7 +99,7 @@ class AbstractNonStationaryTrendTest(object): ...@@ -94,7 +99,7 @@ class AbstractNonStationaryTrendTest(object):
if complete_analysis: if complete_analysis:
year_min, year_max, step = 1960, 1990, 1 year_min, year_max, step = 1960, 1990, 1
else: else:
year_min, year_max, step = 1960, 1990, 10 year_min, year_max, step = 1960, 1990, 5
years = list(range(year_min, year_max + 1, step)) years = list(range(year_min, year_max + 1, step))
return years return years
...@@ -111,8 +116,9 @@ class IndependenceLocationTrendTest(AbstractNonStationaryTrendTest): ...@@ -111,8 +116,9 @@ class IndependenceLocationTrendTest(AbstractNonStationaryTrendTest):
class ConditionalIndedendenceLocationTrendTest(AbstractNonStationaryTrendTest): class ConditionalIndedendenceLocationTrendTest(AbstractNonStationaryTrendTest):
def __init__(self, dataset): def __init__(self, dataset, verbose=False):
super().__init__(dataset=dataset, super().__init__(dataset=dataset,
verbose=verbose,
estimator_class=LinearMarginEstimator, estimator_class=LinearMarginEstimator,
stationary_margin_model_class=LinearStationaryMarginModel, stationary_margin_model_class=LinearStationaryMarginModel,
non_stationary_margin_model_class=LinearNonStationaryLocationMarginModel) non_stationary_margin_model_class=LinearNonStationaryLocationMarginModel)
...@@ -124,8 +130,9 @@ class ConditionalIndedendenceLocationTrendTest(AbstractNonStationaryTrendTest): ...@@ -124,8 +130,9 @@ class ConditionalIndedendenceLocationTrendTest(AbstractNonStationaryTrendTest):
class MaxStableLocationTrendTest(AbstractNonStationaryTrendTest): class MaxStableLocationTrendTest(AbstractNonStationaryTrendTest):
def __init__(self, dataset, max_stable_model): def __init__(self, dataset, max_stable_model, verbose=False):
super().__init__(dataset=dataset, super().__init__(dataset=dataset,
verbose=verbose,
estimator_class=FullEstimatorInASingleStepWithSmoothMargin, estimator_class=FullEstimatorInASingleStepWithSmoothMargin,
stationary_margin_model_class=LinearStationaryMarginModel, stationary_margin_model_class=LinearStationaryMarginModel,
non_stationary_margin_model_class=LinearNonStationaryLocationMarginModel) non_stationary_margin_model_class=LinearNonStationaryLocationMarginModel)
......
...@@ -37,6 +37,10 @@ class ResultFromFit(object): ...@@ -37,6 +37,10 @@ class ResultFromFit(object):
def deviance(self): def deviance(self):
raise NotImplementedError raise NotImplementedError
@property
def convergence(self) -> str:
raise NotImplementedError
class ResultFromIsmev(ResultFromFit): class ResultFromIsmev(ResultFromFit):
......
...@@ -31,6 +31,31 @@ class BetweenZeroAndOneNormalization(UniformNormalization): ...@@ -31,6 +31,31 @@ class BetweenZeroAndOneNormalization(UniformNormalization):
return coord_scaled return coord_scaled
class BetweenZeroAndTenNormalization(BetweenZeroAndOneNormalization):
def uniform_normalization(self, coordinate_value: np.ndarray) -> np.ndarray:
return super().uniform_normalization(coordinate_value) / 10
epsilon = 0.001
class BetweenZeroAndOneNormalizationMinEpsilon(BetweenZeroAndOneNormalization):
def __init__(self, df_coordinates):
super().__init__(df_coordinates)
gap = self.max_coord - self.min_coord
self.min_coord -= gap * epsilon
class BetweenZeroAndOneNormalizationMaxEpsilon(BetweenZeroAndOneNormalization):
def __init__(self, df_coordinates):
super().__init__(df_coordinates)
gap = self.max_coord - self.min_coord
self.max_coord += gap * epsilon
class BetweenMinusOneAndOneNormalization(BetweenZeroAndOneNormalization): class BetweenMinusOneAndOneNormalization(BetweenZeroAndOneNormalization):
"""Normalize such that min(coord) >= (-1,-1) and max(coord) <= (1,1)""" """Normalize such that min(coord) >= (-1,-1) and max(coord) <= (1,1)"""
......
...@@ -38,6 +38,12 @@ class AbstractSpatioTemporalObservations(object): ...@@ -38,6 +38,12 @@ class AbstractSpatioTemporalObservations(object):
else: else:
return self.df_maxima_gev return self.df_maxima_gev
def normalize(self):
# It should stay superior to 0 and lower or equal to 1
# Thus the easiest way to do that is to divide by the maximum
maxima = self._df_maxima.values.flatten().max()
self._df_maxima /= maxima
@property @property
def df_maxima_merged(self) -> pd.DataFrame: def df_maxima_merged(self) -> pd.DataFrame:
df_maxima_list = [] df_maxima_list = []
...@@ -99,4 +105,8 @@ class AbstractSpatioTemporalObservations(object): ...@@ -99,4 +105,8 @@ class AbstractSpatioTemporalObservations(object):
def __str__(self) -> str: def __str__(self) -> str:
return self._df_maxima.__str__() return self._df_maxima.__str__()
@_df_maxima.setter
def _df_maxima(self, value):
self.__df_maxima = value
...@@ -7,7 +7,8 @@ from experiment.meteo_france_SCM_study.visualization.study_visualization.non_sta ...@@ -7,7 +7,8 @@ from experiment.meteo_france_SCM_study.visualization.study_visualization.non_sta
ConditionalIndedendenceLocationTrendTest ConditionalIndedendenceLocationTrendTest
from experiment.meteo_france_SCM_study.visualization.study_visualization.study_visualizer import StudyVisualizer from experiment.meteo_france_SCM_study.visualization.study_visualization.study_visualizer import StudyVisualizer
from spatio_temporal_dataset.coordinates.transformed_coordinates.transformation.uniform_normalization import \ from spatio_temporal_dataset.coordinates.transformed_coordinates.transformation.uniform_normalization import \
BetweenZeroAndOneNormalization, BetweenMinusOneAndOneNormalization BetweenZeroAndOneNormalization, BetweenMinusOneAndOneNormalization, BetweenZeroAndTenNormalization, \
BetweenZeroAndOneNormalizationMinEpsilon, BetweenZeroAndOneNormalizationMaxEpsilon
from utils import get_display_name_from_object_type from utils import get_display_name_from_object_type
...@@ -15,11 +16,14 @@ class TestCoordinateSensitivity(unittest.TestCase): ...@@ -15,11 +16,14 @@ class TestCoordinateSensitivity(unittest.TestCase):
DISPLAY = False DISPLAY = False
def test_coordinate_normalization_sensitivity(self): def test_coordinate_normalization_sensitivity(self):
altitudes = [3000] altitudes = [300, 600, 900, 1200, 2100, 3000][-1:]
transformation_classes = [BetweenZeroAndOneNormalization, BetweenMinusOneAndOneNormalization][:] transformation_classes = [None, BetweenZeroAndOneNormalization, BetweenZeroAndOneNormalizationMinEpsilon, BetweenZeroAndOneNormalizationMaxEpsilon][1:2]
for transformation_class in transformation_classes:
study_classes = [CrocusSwe] study_classes = [CrocusSwe]
for study in study_iterator_global(study_classes, altitudes=altitudes, verbose=False): for study in study_iterator_global(study_classes, altitudes=altitudes, verbose=False):
if self.DISPLAY:
print(study.altitude)
for transformation_class in transformation_classes:
study_visualizer = StudyVisualizer(study, transformation_class=transformation_class) study_visualizer = StudyVisualizer(study, transformation_class=transformation_class)
study_visualizer.temporal_non_stationarity = True study_visualizer.temporal_non_stationarity = True
trend_test = ConditionalIndedendenceLocationTrendTest(study_visualizer.dataset) trend_test = ConditionalIndedendenceLocationTrendTest(study_visualizer.dataset)
...@@ -27,10 +31,20 @@ class TestCoordinateSensitivity(unittest.TestCase): ...@@ -27,10 +31,20 @@ class TestCoordinateSensitivity(unittest.TestCase):
mu1s = [trend_test.get_mu1(year) for year in years] mu1s = [trend_test.get_mu1(year) for year in years]
if self.DISPLAY: if self.DISPLAY:
print('Stationary') print('Stationary')
print(trend_test.get_estimator(trend_test.stationary_margin_model_class, starting_point=None).margin_function_fitted.coef_dict) stationary_est = trend_test.get_estimator(trend_test.stationary_margin_model_class,
starting_point=None)
print(stationary_est.result_from_fit.convergence)
print(stationary_est.margin_function_fitted.coef_dict)
print('Non Stationary') print('Non Stationary')
print(trend_test.get_estimator(trend_test.non_stationary_margin_model_class, starting_point=1960).margin_function_fitted.coef_dict) non_stationary_est = trend_test.get_estimator(trend_test.non_stationary_margin_model_class,
starting_point=1960)
print(non_stationary_est.result_from_fit.convergence)
non_stationary_est = trend_test.get_estimator(trend_test.non_stationary_margin_model_class,
starting_point=1990)
print(non_stationary_est.result_from_fit.convergence)
print(non_stationary_est.margin_function_fitted.coef_dict)
print(get_display_name_from_object_type(transformation_class), 'mu1s: ', mu1s) print(get_display_name_from_object_type(transformation_class), 'mu1s: ', mu1s)
print('\n')
self.assertTrue(0.0 not in mu1s) self.assertTrue(0.0 not in mu1s)
......
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