Commit 36ea1de2 authored by Le Roux Erwan's avatar Le Roux Erwan
Browse files

[refactor] refactor param_function.py. organize the code for the abstact_quantile_function.

parent f6d13838
No related merge requests found
Showing with 90 additions and 41 deletions
+90 -41
...@@ -13,16 +13,16 @@ from spatio_temporal_dataset.slicer.split import Split ...@@ -13,16 +13,16 @@ from spatio_temporal_dataset.slicer.split import Split
class AbstractMarginEstimator(AbstractEstimator, ABC): class AbstractMarginEstimator(AbstractEstimator, ABC):
def __init__(self, dataset: AbstractDataset): def __init__(self, dataset: AbstractDataset, **kwargs):
super().__init__(dataset) super().__init__(dataset, **kwargs)
assert self.dataset.maxima_gev() is not None assert self.dataset.maxima_gev() is not None
class LinearMarginEstimator(AbstractMarginEstimator): class LinearMarginEstimator(AbstractMarginEstimator):
"""# with different type of marginals: cosntant, linear....""" """# with different type of marginals: cosntant, linear...."""
def __init__(self, dataset: AbstractDataset, margin_model: LinearMarginModel): def __init__(self, dataset: AbstractDataset, margin_model: LinearMarginModel, **kwargs):
super().__init__(dataset) super().__init__(dataset, **kwargs)
assert isinstance(margin_model, LinearMarginModel) assert isinstance(margin_model, LinearMarginModel)
self.margin_model = margin_model self.margin_model = margin_model
......
from abc import ABC
import numpy as np
from cached_property import cached_property from cached_property import cached_property
from extreme_fit.estimator.abstract_estimator import AbstractEstimator from extreme_fit.estimator.abstract_estimator import AbstractEstimator
from extreme_fit.estimator.margin_estimator.abstract_margin_estimator import LinearMarginEstimator from extreme_fit.estimator.margin_estimator.abstract_margin_estimator import LinearMarginEstimator
from extreme_fit.function.abstract_quantile_function import AbstractQuantileFunction from extreme_fit.function.abstract_quantile_function import AbstractQuantileFunction, \
QuantileFunctionFromMarginFunction, QuantileFunctionFromParamFunction
from extreme_fit.function.margin_function.abstract_margin_function import AbstractMarginFunction from extreme_fit.function.margin_function.abstract_margin_function import AbstractMarginFunction
from extreme_fit.function.param_function.linear_coef import LinearCoef
from extreme_fit.function.param_function.param_function import LinearParamFunction
from extreme_fit.model.margin_model.linear_margin_model.linear_margin_model import LinearMarginModel from extreme_fit.model.margin_model.linear_margin_model.linear_margin_model import LinearMarginModel
from extreme_fit.model.quantile_model.quantile_regression_model import AbstractQuantileRegressionModel from extreme_fit.model.quantile_model.quantile_regression_model import AbstractQuantileRegressionModel
from extreme_fit.model.result_from_model_fit.abstract_result_from_model_fit import AbstractResultFromModelFit from extreme_fit.model.result_from_model_fit.abstract_result_from_model_fit import AbstractResultFromModelFit
from extreme_fit.model.result_from_model_fit.result_from_quantilreg import ResultFromQuantreg
from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
class AbstractQuantileEstimator(AbstractEstimator): class AbstractQuantileEstimator(AbstractEstimator, ABC):
def __init__(self, dataset: AbstractDataset, quantile: float, **kwargs): def __init__(self, dataset: AbstractDataset, quantile: float, **kwargs):
super().__init__(dataset, **kwargs) super().__init__(dataset, **kwargs)
...@@ -18,30 +25,37 @@ class AbstractQuantileEstimator(AbstractEstimator): ...@@ -18,30 +25,37 @@ class AbstractQuantileEstimator(AbstractEstimator):
self.quantile = quantile self.quantile = quantile
@cached_property @cached_property
def quantile_function_from_fit(self) -> AbstractQuantileFunction: def function_from_fit(self) -> AbstractQuantileFunction:
pass raise NotImplementedError
class QuantileEstimatorFromMargin(AbstractQuantileEstimator, LinearMarginEstimator): class QuantileEstimatorFromMargin(LinearMarginEstimator, AbstractQuantileEstimator):
def __init__(self, dataset: AbstractDataset, margin_model: LinearMarginModel, quantile): def __init__(self, dataset: AbstractDataset, margin_model: LinearMarginModel, quantile):
super().__init__(dataset=dataset, quantile=quantile, margin_model=margin_model) super().__init__(dataset=dataset, quantile=quantile, margin_model=margin_model)
@cached_property @cached_property
def quantile_function_from_fit(self) -> AbstractQuantileFunction: def function_from_fit(self) -> AbstractQuantileFunction:
linear_margin_function = super().function_from_fit # type: AbstractMarginFunction linear_margin_function = super().function_from_fit # type: AbstractMarginFunction
return AbstractQuantileFunction(linear_margin_function, self.quantile) return QuantileFunctionFromMarginFunction(self.dataset.coordinates, linear_margin_function, self.quantile)
class QuantileRegressionEstimator(AbstractQuantileEstimator): class QuantileRegressionEstimator(AbstractQuantileEstimator):
def __init__(self, dataset: AbstractDataset, quantile: float, quantile_regression_model_class: type, **kwargs): def __init__(self, dataset: AbstractDataset, quantile: float, quantile_regression_model_class: type, **kwargs):
super().__init__(dataset, quantile, **kwargs) super().__init__(dataset, quantile, **kwargs)
self.quantile_regression_model = quantile_regression_model_class(dataset, quantile) # type: AbstractQuantileRegressionModel self.quantile_regression_model = quantile_regression_model_class(dataset, quantile) # type: AbstractQuantileRegressionModel
def _fit(self) -> AbstractResultFromModelFit: def _fit(self) -> AbstractResultFromModelFit:
return self.quantile_regression_model.fit() return self.quantile_regression_model.fit()
@cached_property @cached_property
def quantile_function_from_fit(self) -> AbstractQuantileFunction: def function_from_fit(self) -> AbstractQuantileFunction:
return self.result_from_model_fit.quantile_function result_from_model_fit = self.result_from_model_fit # type: ResultFromQuantreg
coefs = result_from_model_fit.coefficients
dims = list(np.arange(len(coefs)) - 1)
linear_coef = LinearCoef('quantile', idx_to_coef=dict(zip(dims, coefs)))
param_function = LinearParamFunction(dims=dims, coordinates=self.dataset.coordinates.coordinates_values(),
linear_coef=linear_coef)
return QuantileFunctionFromParamFunction(coordinates=self.dataset.coordinates,
param_function=param_function)
from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoordinates
class AbstractFunction(object): class AbstractFunction(object):
pass
\ No newline at end of file def __init__(self, coordinates: AbstractCoordinates):
self.coordinates = coordinates
...@@ -2,19 +2,58 @@ import numpy as np ...@@ -2,19 +2,58 @@ import numpy as np
from extreme_fit.function.abstract_function import AbstractFunction from extreme_fit.function.abstract_function import AbstractFunction
from extreme_fit.function.margin_function.abstract_margin_function import AbstractMarginFunction from extreme_fit.function.margin_function.abstract_margin_function import AbstractMarginFunction
import matplotlib.pyplot as plt
from extreme_fit.function.param_function.param_function import AbstractParamFunction
from spatio_temporal_dataset.coordinates.abstract_coordinates import AbstractCoordinates
class AbstractQuantileFunction(AbstractFunction): class AbstractQuantileFunction(AbstractFunction):
def __init__(self, margin_function: AbstractMarginFunction, quantile: float): def get_quantile(self, coordinate: np.ndarray) -> float:
raise NotImplementedError
def visualize(self, show=True):
if self.coordinates.nb_coordinates == 1:
self.visualize_1D(show=show)
elif self.coordinates.nb_coordinates == 2:
self.visualize_2D()
else:
return
# raise NotImplementedError
def visualize_1D(self, ax=None, show=True):
if ax is None:
ax = plt.gca()
x = self.coordinates.coordinates_values()
resolution = 100
x = np.linspace(x.min(), x.max(), resolution)
y = [self.get_quantile(np.array([e])) for e in x]
ax.plot(x, y)
if show:
plt.show()
def visualize_2D(self):
return
class QuantileFunctionFromParamFunction(AbstractQuantileFunction):
def __init__(self, coordinates: AbstractCoordinates, param_function: AbstractParamFunction):
super().__init__(coordinates)
self.param_function = param_function
def get_quantile(self, coordinate: np.ndarray) -> float:
return self.param_function.get_param_value(coordinate)
class QuantileFunctionFromMarginFunction(AbstractQuantileFunction):
def __init__(self, coordinates: AbstractCoordinates, margin_function: AbstractMarginFunction, quantile: float):
super().__init__(coordinates)
self.margin_function = margin_function self.margin_function = margin_function
self.quantile = quantile self.quantile = quantile
def get_quantile(self, coordinate: np.ndarray) -> float: def get_quantile(self, coordinate: np.ndarray) -> float:
gev_params = self.margin_function.get_gev_params(coordinate) gev_params = self.margin_function.get_gev_params(coordinate)
return gev_params.quantile(self.quantile) return gev_params.quantile(self.quantile)
def visualize(self):
pass
# for coordine
# self.margin_function.
\ No newline at end of file
...@@ -21,7 +21,7 @@ class AbstractMarginFunction(AbstractFunction): ...@@ -21,7 +21,7 @@ class AbstractMarginFunction(AbstractFunction):
VISUALIZATION_TEMPORAL_STEPS = 2 VISUALIZATION_TEMPORAL_STEPS = 2
def __init__(self, coordinates: AbstractCoordinates): def __init__(self, coordinates: AbstractCoordinates):
self.coordinates = coordinates super().__init__(coordinates)
self.mask_2D = None self.mask_2D = None
# Visualization parameters # Visualization parameters
......
...@@ -29,7 +29,7 @@ class IndependentMarginFunction(AbstractMarginFunction): ...@@ -29,7 +29,7 @@ class IndependentMarginFunction(AbstractMarginFunction):
gev_params = {} gev_params = {}
for gev_param_name in GevParams.PARAM_NAMES: for gev_param_name in GevParams.PARAM_NAMES:
param_function = self.gev_param_name_to_param_function[gev_param_name] param_function = self.gev_param_name_to_param_function[gev_param_name]
gev_params[gev_param_name] = param_function.get_gev_param_value(transformed_coordinate) gev_params[gev_param_name] = param_function.get_param_value(transformed_coordinate)
return GevParams.from_dict(gev_params) return GevParams.from_dict(gev_params)
def transform(self, coordinate: np.ndarray) -> np.ndarray: def transform(self, coordinate: np.ndarray) -> np.ndarray:
......
...@@ -7,7 +7,7 @@ from extreme_fit.function.param_function.spline_coef import SplineCoef ...@@ -7,7 +7,7 @@ from extreme_fit.function.param_function.spline_coef import SplineCoef
class AbstractParamFunction(object): class AbstractParamFunction(object):
OUT_OF_BOUNDS_ASSERT = True OUT_OF_BOUNDS_ASSERT = True
def get_gev_param_value(self, coordinate: np.ndarray) -> float: def get_param_value(self, coordinate: np.ndarray) -> float:
pass pass
...@@ -16,7 +16,7 @@ class ConstantParamFunction(AbstractParamFunction): ...@@ -16,7 +16,7 @@ class ConstantParamFunction(AbstractParamFunction):
def __init__(self, constant): def __init__(self, constant):
self.constant = constant self.constant = constant
def get_gev_param_value(self, coordinate: np.ndarray) -> float: def get_param_value(self, coordinate: np.ndarray) -> float:
return self.constant return self.constant
...@@ -28,7 +28,7 @@ class LinearOneAxisParamFunction(AbstractParamFunction): ...@@ -28,7 +28,7 @@ class LinearOneAxisParamFunction(AbstractParamFunction):
self.t_max = coordinates[:, dim].max() self.t_max = coordinates[:, dim].max()
self.coef = coef self.coef = coef
def get_gev_param_value(self, coordinate: np.ndarray) -> float: def get_param_value(self, coordinate: np.ndarray) -> float:
t = coordinate[self.dim] t = coordinate[self.dim]
if self.OUT_OF_BOUNDS_ASSERT: if self.OUT_OF_BOUNDS_ASSERT:
assert self.t_min <= t <= self.t_max, '{} is out of bounds ({}, {})'.format(t, self.t_min, self.t_max) assert self.t_min <= t <= self.t_max, '{} is out of bounds ({}, {})'.format(t, self.t_min, self.t_max)
...@@ -46,11 +46,11 @@ class LinearParamFunction(AbstractParamFunction): ...@@ -46,11 +46,11 @@ class LinearParamFunction(AbstractParamFunction):
coef=self.linear_coef.get_coef(idx=dim)) coef=self.linear_coef.get_coef(idx=dim))
self.linear_one_axis_param_functions.append(param_function) self.linear_one_axis_param_functions.append(param_function)
def get_gev_param_value(self, coordinate: np.ndarray) -> float: def get_param_value(self, coordinate: np.ndarray) -> float:
# Add the intercept and the value with respect to each axis # Add the intercept and the value with respect to each axis
gev_param_value = self.linear_coef.intercept gev_param_value = self.linear_coef.intercept
for linear_one_axis_param_function in self.linear_one_axis_param_functions: for linear_one_axis_param_function in self.linear_one_axis_param_functions:
gev_param_value += linear_one_axis_param_function.get_gev_param_value(coordinate) gev_param_value += linear_one_axis_param_function.get_param_value(coordinate)
return gev_param_value return gev_param_value
...@@ -66,7 +66,7 @@ class SplineParamFunction(AbstractParamFunction): ...@@ -66,7 +66,7 @@ class SplineParamFunction(AbstractParamFunction):
def m(self) -> int: def m(self) -> int:
return int((self.degree + 1) / 2) return int((self.degree + 1) / 2)
def get_gev_param_value(self, coordinate: np.ndarray) -> float: def get_param_value(self, coordinate: np.ndarray) -> float:
gev_param_value = self.spline_coef.intercept gev_param_value = self.spline_coef.intercept
# Polynomial part # Polynomial part
for dim in self.dims: for dim in self.dims:
......
...@@ -19,12 +19,9 @@ class AbstractQuantileRegressionModel(AbstractModel): ...@@ -19,12 +19,9 @@ class AbstractQuantileRegressionModel(AbstractModel):
@property @property
def first_column_of_observation(self): def first_column_of_observation(self):
return self.data.colnames[1] return self.data.colnames[0]
# print(self.dataset.df_dataset.columns)
# return str(self.dataset.df_dataset.columns[0])
def fit(self): def fit(self):
print(self.data)
parameters = { parameters = {
'tau': self.quantile, 'tau': self.quantile,
'data': self.data, 'data': self.data,
......
from cached_property import cached_property from cached_property import cached_property
from extreme_fit.function.param_function.param_function import LinearParamFunction
from extreme_fit.model.result_from_model_fit.abstract_result_from_model_fit import AbstractResultFromModelFit from extreme_fit.model.result_from_model_fit.abstract_result_from_model_fit import AbstractResultFromModelFit
...@@ -8,7 +9,3 @@ class ResultFromQuantreg(AbstractResultFromModelFit): ...@@ -8,7 +9,3 @@ class ResultFromQuantreg(AbstractResultFromModelFit):
@property @property
def coefficients(self): def coefficients(self):
return self.name_to_value['coefficients'] return self.name_to_value['coefficients']
@cached_property
def quantile_function(self):
print(self.coefficients)
\ No newline at end of file
...@@ -90,7 +90,6 @@ def safe_run_r_estimator(function, data=None, use_start=False, max_ratio_between ...@@ -90,7 +90,6 @@ def safe_run_r_estimator(function, data=None, use_start=False, max_ratio_between
if isinstance(data, np.ndarray): if isinstance(data, np.ndarray):
# Raise warning if the gap is too important between the two biggest values of data # Raise warning if the gap is too important between the two biggest values of data
sorted_data = sorted(data.flatten()) sorted_data = sorted(data.flatten())
print(data)
if sorted_data[-2] * max_ratio_between_two_extremes_values < sorted_data[-1]: if sorted_data[-2] * max_ratio_between_two_extremes_values < sorted_data[-1]:
msg = "maxmimum absolute value in data {} is too high, i.e. above the defined threshold {}" \ msg = "maxmimum absolute value in data {} is too high, i.e. above the defined threshold {}" \
.format(sorted_data[-1], max_ratio_between_two_extremes_values) .format(sorted_data[-1], max_ratio_between_two_extremes_values)
......
...@@ -13,7 +13,7 @@ class TestQuantileEstimator(unittest.TestCase): ...@@ -13,7 +13,7 @@ class TestQuantileEstimator(unittest.TestCase):
def test_smooth_margin_estimator_spatial(self): def test_smooth_margin_estimator_spatial(self):
self.nb_points = 20 self.nb_points = 20
self.nb_obs = 1 self.nb_obs = 1
self.coordinates = load_test_1D_and_2D_spatial_coordinates(nb_points=self.nb_points) self.coordinates = load_test_1D_and_2D_spatial_coordinates(nb_points=self.nb_points)[:1]
def test_smooth_margin_estimator_spatio_temporal(self): def test_smooth_margin_estimator_spatio_temporal(self):
self.nb_points = 2 self.nb_points = 2
...@@ -28,7 +28,6 @@ class TestQuantileEstimator(unittest.TestCase): ...@@ -28,7 +28,6 @@ class TestQuantileEstimator(unittest.TestCase):
dataset = MarginDataset.from_sampling(nb_obs=self.nb_obs, dataset = MarginDataset.from_sampling(nb_obs=self.nb_obs,
margin_model=constant_margin_model, margin_model=constant_margin_model,
coordinates=coordinates) coordinates=coordinates)
print(dataset)
# Load quantile estimators # Load quantile estimators
quantile_estimators = [ quantile_estimators = [
QuantileEstimatorFromMargin(dataset, constant_margin_model, quantile), QuantileEstimatorFromMargin(dataset, constant_margin_model, quantile),
...@@ -40,7 +39,7 @@ class TestQuantileEstimator(unittest.TestCase): ...@@ -40,7 +39,7 @@ class TestQuantileEstimator(unittest.TestCase):
# Fit quantile estimators # Fit quantile estimators
for quantile_estimator in quantile_estimators: for quantile_estimator in quantile_estimators:
quantile_estimator.fit() quantile_estimator.fit()
print(quantile_estimator.quantile_function_from_fit) quantile_estimator.function_from_fit.visualize(show=self.DISPLAY)
self.assertTrue(True) self.assertTrue(True)
......
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