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
class AbstractNonStationaryTrendTest(object):
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):
self.verbose = verbose
self.dataset = dataset
self.estimator_class = estimator_class
self.stationary_margin_model_class = stationary_margin_model_class
......@@ -33,9 +34,10 @@ class AbstractNonStationaryTrendTest(object):
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)
estimator = self._load_estimator(margin_model)
estimator_name = get_display_name_from_object_type(estimator)
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))
if self.verbose:
estimator_name = get_display_name_from_object_type(estimator)
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()
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)]
......@@ -79,12 +81,15 @@ class AbstractNonStationaryTrendTest(object):
mu1_trends = [self.get_mu1(starting_point=year) for year in years]
ax2 = ax.twinx()
color_mu1 = 'c'
print(mu1_trends)
if self.verbose:
print(mu1_trends)
ax2.plot(years, mu1_trends, color_mu1 + 'o-')
ax2.set_ylabel('mu1 parameter', color=color_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
ax.set_title(title)
ax.legend()
......@@ -94,7 +99,7 @@ class AbstractNonStationaryTrendTest(object):
if complete_analysis:
year_min, year_max, step = 1960, 1990, 1
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))
return years
......@@ -111,8 +116,9 @@ class IndependenceLocationTrendTest(AbstractNonStationaryTrendTest):
class ConditionalIndedendenceLocationTrendTest(AbstractNonStationaryTrendTest):
def __init__(self, dataset):
def __init__(self, dataset, verbose=False):
super().__init__(dataset=dataset,
verbose=verbose,
estimator_class=LinearMarginEstimator,
stationary_margin_model_class=LinearStationaryMarginModel,
non_stationary_margin_model_class=LinearNonStationaryLocationMarginModel)
......@@ -124,8 +130,9 @@ class ConditionalIndedendenceLocationTrendTest(AbstractNonStationaryTrendTest):
class MaxStableLocationTrendTest(AbstractNonStationaryTrendTest):
def __init__(self, dataset, max_stable_model):
def __init__(self, dataset, max_stable_model, verbose=False):
super().__init__(dataset=dataset,
verbose=verbose,
estimator_class=FullEstimatorInASingleStepWithSmoothMargin,
stationary_margin_model_class=LinearStationaryMarginModel,
non_stationary_margin_model_class=LinearNonStationaryLocationMarginModel)
......
......@@ -37,6 +37,10 @@ class ResultFromFit(object):
def deviance(self):
raise NotImplementedError
@property
def convergence(self) -> str:
raise NotImplementedError
class ResultFromIsmev(ResultFromFit):
......
......@@ -31,6 +31,31 @@ class BetweenZeroAndOneNormalization(UniformNormalization):
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):
"""Normalize such that min(coord) >= (-1,-1) and max(coord) <= (1,1)"""
......
......@@ -38,6 +38,12 @@ class AbstractSpatioTemporalObservations(object):
else:
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
def df_maxima_merged(self) -> pd.DataFrame:
df_maxima_list = []
......@@ -99,4 +105,8 @@ class AbstractSpatioTemporalObservations(object):
def __str__(self) -> 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
ConditionalIndedendenceLocationTrendTest
from experiment.meteo_france_SCM_study.visualization.study_visualization.study_visualizer import StudyVisualizer
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
......@@ -15,11 +16,14 @@ class TestCoordinateSensitivity(unittest.TestCase):
DISPLAY = False
def test_coordinate_normalization_sensitivity(self):
altitudes = [3000]
transformation_classes = [BetweenZeroAndOneNormalization, BetweenMinusOneAndOneNormalization][:]
for transformation_class in transformation_classes:
study_classes = [CrocusSwe]
for study in study_iterator_global(study_classes, altitudes=altitudes, verbose=False):
altitudes = [300, 600, 900, 1200, 2100, 3000][-1:]
transformation_classes = [None, BetweenZeroAndOneNormalization, BetweenZeroAndOneNormalizationMinEpsilon, BetweenZeroAndOneNormalizationMaxEpsilon][1:2]
study_classes = [CrocusSwe]
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.temporal_non_stationarity = True
trend_test = ConditionalIndedendenceLocationTrendTest(study_visualizer.dataset)
......@@ -27,10 +31,20 @@ class TestCoordinateSensitivity(unittest.TestCase):
mu1s = [trend_test.get_mu1(year) for year in years]
if self.DISPLAY:
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(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('\n')
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