Commit 0db2a252 authored by Le Roux Erwan's avatar Le Roux Erwan
Browse files

[quantile regression] add quantile regression model

parent a594c050
No related merge requests found
Showing with 136 additions and 24 deletions
+136 -24
...@@ -11,7 +11,7 @@ from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset ...@@ -11,7 +11,7 @@ from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
class AbstractEstimator(object): class AbstractEstimator(object):
def __init__(self, dataset: AbstractDataset): def __init__(self, dataset: AbstractDataset, **kwargs):
self.dataset = dataset # type: AbstractDataset self.dataset = dataset # type: AbstractDataset
self._result_from_fit = None # type: Union[None, AbstractResultFromModelFit] self._result_from_fit = None # type: Union[None, AbstractResultFromModelFit]
......
...@@ -3,14 +3,17 @@ from cached_property import cached_property ...@@ -3,14 +3,17 @@ 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
from extreme_fit.function.margin_function.abstract_margin_function import AbstractMarginFunction
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.result_from_model_fit.abstract_result_from_model_fit import AbstractResultFromModelFit
from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
class AbstractQuantileEstimator(AbstractEstimator): class AbstractQuantileEstimator(AbstractEstimator):
def __init__(self, quantile: float, **kwargs): def __init__(self, dataset: AbstractDataset, quantile: float, **kwargs):
super().__init__(**kwargs) super().__init__(dataset, **kwargs)
assert 0 < quantile < 1 assert 0 < quantile < 1
self.quantile = quantile self.quantile = quantile
...@@ -26,5 +29,19 @@ class QuantileEstimatorFromMargin(AbstractQuantileEstimator, LinearMarginEstimat ...@@ -26,5 +29,19 @@ class QuantileEstimatorFromMargin(AbstractQuantileEstimator, LinearMarginEstimat
@cached_property @cached_property
def quantile_function_from_fit(self) -> AbstractQuantileFunction: def quantile_function_from_fit(self) -> AbstractQuantileFunction:
linear_margin_function = super().function_from_fit linear_margin_function = super().function_from_fit # type: AbstractMarginFunction
return AbstractQuantileFunction(linear_margin_function, self.quantile) return AbstractQuantileFunction(linear_margin_function, self.quantile)
class QuantileRegressionEstimator(AbstractQuantileEstimator):
def __init__(self, dataset: AbstractDataset, quantile: float, quantile_regression_model_class: type, **kwargs):
super().__init__(dataset, quantile, **kwargs)
self.quantile_regression_model = quantile_regression_model_class(dataset, quantile) # type: AbstractQuantileRegressionModel
def _fit(self) -> AbstractResultFromModelFit:
return self.quantile_regression_model.fit()
@cached_property
def quantile_function_from_fit(self) -> AbstractQuantileFunction:
return self.result_from_model_fit.quantile_function
...@@ -12,4 +12,9 @@ class AbstractQuantileFunction(AbstractFunction): ...@@ -12,4 +12,9 @@ class AbstractQuantileFunction(AbstractFunction):
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)
\ No newline at end of file
def visualize(self):
pass
# for coordine
# self.margin_function.
\ No newline at end of file
import numpy as np
from rpy2 import robjects
from extreme_fit.model.abstract_model import AbstractModel
from extreme_fit.model.result_from_model_fit.result_from_quantilreg import ResultFromQuantreg
from extreme_fit.model.utils import r, safe_run_r_estimator, get_coord_df
from spatio_temporal_dataset.dataset.abstract_dataset import AbstractDataset
class AbstractQuantileRegressionModel(AbstractModel):
def __init__(self, dataset: AbstractDataset, quantile: float):
self.dataset = dataset
self.quantile = quantile
@property
def data(self):
return get_coord_df(self.dataset.df_dataset)
@property
def first_column_of_observation(self):
return self.data.colnames[1]
# print(self.dataset.df_dataset.columns)
# return str(self.dataset.df_dataset.columns[0])
def fit(self):
print(self.data)
parameters = {
'tau': self.quantile,
'data': self.data,
'formula': self.formula
}
res = safe_run_r_estimator(r.rq, **parameters)
return ResultFromQuantreg(res)
@property
def formula_str(self):
raise NotImplementedError
@property
def formula(self):
return robjects.Formula(self.first_column_of_observation + '~ ' + self.formula_str)
class ConstantQuantileRegressionModel(AbstractQuantileRegressionModel):
@property
def formula_str(self):
return '1'
class AllCoordinatesQuantileRegressionModel(AbstractQuantileRegressionModel):
@property
def formula_str(self):
return '+'.join(self.dataset.coordinates.coordinates_names[-1:])
from cached_property import cached_property
from extreme_fit.model.result_from_model_fit.abstract_result_from_model_fit import AbstractResultFromModelFit
class ResultFromQuantreg(AbstractResultFromModelFit):
@property
def coefficients(self):
return self.name_to_value['coefficients']
@cached_property
def quantile_function(self):
print(self.coefficients)
\ No newline at end of file
...@@ -23,6 +23,7 @@ numpy2ri.activate() ...@@ -23,6 +23,7 @@ numpy2ri.activate()
pandas2ri.activate() pandas2ri.activate()
r.library('SpatialExtremes') r.library('SpatialExtremes')
r.library('data.table') r.library('data.table')
r.library('quantreg')
# Desactivate temporarily warnings # Desactivate temporarily warnings
default_filters = warnings.filters.copy() default_filters = warnings.filters.copy()
warnings.filterwarnings("ignore") warnings.filterwarnings("ignore")
...@@ -125,12 +126,11 @@ def get_coord(df_coordinates: pd.DataFrame): ...@@ -125,12 +126,11 @@ def get_coord(df_coordinates: pd.DataFrame):
def get_coord_df(df_coordinates: pd.DataFrame): def get_coord_df(df_coordinates: pd.DataFrame):
coord = pandas2ri.py2ri_pandasdataframe(df_coordinates) coord = pandas2ri.py2ri_pandasdataframe(df_coordinates)
# coord = r.transpose(coord) # coord = r.transpose(coord)
colname = df_coordinates.columns[0] colname = df_coordinates.columns
coord.colnames = r.c(colname) coord.colnames = r.c(colname)
coord = r('data.frame')(coord, stringsAsFactors=True) coord = r('data.frame')(coord, stringsAsFactors=True)
return coord return coord
def get_null(): def get_null():
as_null = r['as.null'] as_null = r['as.null']
return as_null(1.0) return as_null(1.0)
......
...@@ -53,7 +53,7 @@ class AbstractSpatioTemporalObservations(object): ...@@ -53,7 +53,7 @@ class AbstractSpatioTemporalObservations(object):
(self.df_maxima_frech, self.OBSERVATIONS_FRECH)]: (self.df_maxima_frech, self.OBSERVATIONS_FRECH)]:
if df is not None: if df is not None:
df_maxima = df.copy() df_maxima = df.copy()
df_maxima.columns = [str(c) + ' ' + suffix for c in df_maxima.columns] df_maxima.columns = [str(c) for c in df_maxima.columns]
df_maxima_list.append(df_maxima) df_maxima_list.append(df_maxima)
return pd.concat(df_maxima_list, axis=1) return pd.concat(df_maxima_list, axis=1)
......
import unittest import unittest
from extreme_fit.estimator.quantile_estimator.abstract_quantile_estimator import QuantileEstimatorFromMargin from extreme_fit.estimator.quantile_estimator.abstract_quantile_estimator import QuantileEstimatorFromMargin, \
QuantileRegressionEstimator
from spatio_temporal_dataset.dataset.simulation_dataset import MarginDataset from spatio_temporal_dataset.dataset.simulation_dataset import MarginDataset
from test.test_utils import load_test_1D_and_2D_spatial_coordinates, load_test_spatiotemporal_coordinates, \ from test.test_utils import load_test_1D_and_2D_spatial_coordinates, load_test_spatiotemporal_coordinates, \
load_smooth_margin_models load_smooth_margin_models, load_smooth_quantile_model_classes
class TestSmoothMarginEstimator(unittest.TestCase): class TestQuantileEstimator(unittest.TestCase):
DISPLAY = False DISPLAY = False
def test_smooth_margin_estimator_spatial(self): def test_smooth_margin_estimator_spatial(self):
self.nb_points = 2 self.nb_points = 20
self.nb_obs = 2 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)
def test_smooth_margin_estimator_spatio_temporal(self): def test_smooth_margin_estimator_spatio_temporal(self):
...@@ -21,21 +22,28 @@ class TestSmoothMarginEstimator(unittest.TestCase): ...@@ -21,21 +22,28 @@ class TestSmoothMarginEstimator(unittest.TestCase):
self.coordinates = load_test_spatiotemporal_coordinates(nb_steps=self.nb_steps, nb_points=self.nb_points) self.coordinates = load_test_spatiotemporal_coordinates(nb_steps=self.nb_steps, nb_points=self.nb_points)
def tearDown(self) -> None: def tearDown(self) -> None:
quantile = 0.98 quantile = 0.5
for coordinates in self.coordinates: for coordinates in self.coordinates:
constant_margin_model = load_smooth_margin_models(coordinates=coordinates)[0] constant_margin_model = load_smooth_margin_models(coordinates=coordinates)[0]
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)
quantile_estimators = [QuantileEstimatorFromMargin(dataset, constant_margin_model, quantile)] print(dataset)
help(QuantileEstimatorFromMargin) # Load quantile estimators
quantile_estimators = [
QuantileEstimatorFromMargin(dataset, constant_margin_model, quantile),
]
for quantile_model_class in load_smooth_quantile_model_classes()[:1]:
quantile_estimator = QuantileRegressionEstimator(dataset, quantile, quantile_model_class)
quantile_estimators.append(quantile_estimator)
# Fit quantile estimators
for quantile_estimator in quantile_estimators: for quantile_estimator in quantile_estimators:
quantile_estimator.fit() quantile_estimator.fit()
print(quantile_estimator.function_from_fit) print(quantile_estimator.quantile_function_from_fit)
# self.assertTrue(True) self.assertTrue(True)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
\ No newline at end of file
...@@ -6,7 +6,8 @@ from experiment.meteo_france_data.scm_models_data.crocus.crocus import Crocus, C ...@@ -6,7 +6,8 @@ from experiment.meteo_france_data.scm_models_data.crocus.crocus import Crocus, C
from extreme_fit.estimator.full_estimator.abstract_full_estimator import SmoothMarginalsThenUnitaryMsp, \ from extreme_fit.estimator.full_estimator.abstract_full_estimator import SmoothMarginalsThenUnitaryMsp, \
FullEstimatorInASingleStepWithSmoothMargin FullEstimatorInASingleStepWithSmoothMargin
from extreme_fit.estimator.max_stable_estimator.abstract_max_stable_estimator import MaxStableEstimator from extreme_fit.estimator.max_stable_estimator.abstract_max_stable_estimator import MaxStableEstimator
from extreme_fit.model.margin_model.linear_margin_model.linear_margin_model import LinearAllParametersAllDimsMarginModel, \ from extreme_fit.model.margin_model.linear_margin_model.linear_margin_model import \
LinearAllParametersAllDimsMarginModel, \
ConstantMarginModel ConstantMarginModel
from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import \ from extreme_fit.model.margin_model.linear_margin_model.temporal_linear_margin_models import \
NonStationaryLocationTemporalModel, NonStationaryScaleTemporalModel, NonStationaryShapeTemporalModel NonStationaryLocationTemporalModel, NonStationaryScaleTemporalModel, NonStationaryShapeTemporalModel
...@@ -16,6 +17,8 @@ from extreme_fit.model.max_stable_model.max_stable_models import Smith, BrownRes ...@@ -16,6 +17,8 @@ from extreme_fit.model.max_stable_model.max_stable_models import Smith, BrownRes
Geometric, ExtremalT, ISchlather Geometric, ExtremalT, ISchlather
from experiment.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall, Safran, SafranRainfall, \ from experiment.meteo_france_data.scm_models_data.safran.safran import SafranSnowfall, Safran, SafranRainfall, \
SafranTemperature, SafranPrecipitation SafranTemperature, SafranPrecipitation
from extreme_fit.model.quantile_model.quantile_regression_model import ConstantQuantileRegressionModel, \
AllCoordinatesQuantileRegressionModel
from spatio_temporal_dataset.coordinates.spatial_coordinates.abstract_spatial_coordinates import \ from spatio_temporal_dataset.coordinates.spatial_coordinates.abstract_spatial_coordinates import \
AbstractSpatialCoordinates AbstractSpatialCoordinates
from spatio_temporal_dataset.coordinates.spatial_coordinates.alps_station_3D_coordinates import \ from spatio_temporal_dataset.coordinates.spatial_coordinates.alps_station_3D_coordinates import \
...@@ -40,7 +43,9 @@ TEST_3D_SPATIAL_COORDINATES = [AlpsStation3DCoordinatesWithAnisotropy] ...@@ -40,7 +43,9 @@ TEST_3D_SPATIAL_COORDINATES = [AlpsStation3DCoordinatesWithAnisotropy]
TEST_TEMPORAL_COORDINATES = [ConsecutiveTemporalCoordinates] TEST_TEMPORAL_COORDINATES = [ConsecutiveTemporalCoordinates]
TEST_SPATIO_TEMPORAL_COORDINATES = [UniformSpatioTemporalCoordinates, LinSpaceSpatial2DSpatioTemporalCoordinates] TEST_SPATIO_TEMPORAL_COORDINATES = [UniformSpatioTemporalCoordinates, LinSpaceSpatial2DSpatioTemporalCoordinates]
TEST_MARGIN_TYPES = [ConstantMarginModel, LinearAllParametersAllDimsMarginModel][:] TEST_MARGIN_TYPES = [ConstantMarginModel, LinearAllParametersAllDimsMarginModel][:]
TEST_NON_STATIONARY_TEMPORAL_MARGIN_TYPES = [NonStationaryLocationTemporalModel, NonStationaryScaleTemporalModel, NonStationaryShapeTemporalModel] TEST_QUANTILES_TYPES = [ConstantQuantileRegressionModel, AllCoordinatesQuantileRegressionModel][:]
TEST_NON_STATIONARY_TEMPORAL_MARGIN_TYPES = [NonStationaryLocationTemporalModel, NonStationaryScaleTemporalModel,
NonStationaryShapeTemporalModel]
TEST_MAX_STABLE_ESTIMATOR = [MaxStableEstimator] TEST_MAX_STABLE_ESTIMATOR = [MaxStableEstimator]
TEST_FULL_ESTIMATORS = [SmoothMarginalsThenUnitaryMsp, FullEstimatorInASingleStepWithSmoothMargin][:] TEST_FULL_ESTIMATORS = [SmoothMarginalsThenUnitaryMsp, FullEstimatorInASingleStepWithSmoothMargin][:]
...@@ -62,6 +67,10 @@ def load_smooth_margin_models(coordinates): ...@@ -62,6 +67,10 @@ def load_smooth_margin_models(coordinates):
return [margin_class(coordinates=coordinates) for margin_class in TEST_MARGIN_TYPES] return [margin_class(coordinates=coordinates) for margin_class in TEST_MARGIN_TYPES]
def load_smooth_quantile_model_classes():
return [quantile_reg_class for quantile_reg_class in TEST_QUANTILES_TYPES]
def load_test_max_stable_models(default_covariance_function=None): def load_test_max_stable_models(default_covariance_function=None):
# Load all max stable model # Load all max stable model
max_stable_models = [] max_stable_models = []
...@@ -84,14 +93,16 @@ def load_test_spatial_coordinates(nb_points, coordinate_types, train_split_ratio ...@@ -84,14 +93,16 @@ def load_test_spatial_coordinates(nb_points, coordinate_types, train_split_ratio
for coordinate_class in coordinate_types] for coordinate_class in coordinate_types]
def load_test_1D_and_2D_spatial_coordinates(nb_points, train_split_ratio=None, transformation_class=None) -> List[AbstractSpatialCoordinates]: def load_test_1D_and_2D_spatial_coordinates(nb_points, train_split_ratio=None, transformation_class=None) -> List[
AbstractSpatialCoordinates]:
return load_test_spatial_coordinates(nb_points, TEST_1D_AND_2D_SPATIAL_COORDINATES, return load_test_spatial_coordinates(nb_points, TEST_1D_AND_2D_SPATIAL_COORDINATES,
train_split_ratio=train_split_ratio, train_split_ratio=train_split_ratio,
transformation_class=transformation_class) transformation_class=transformation_class)
def load_test_3D_spatial_coordinates(nb_points, transformation_class=None) -> List[AbstractSpatialCoordinates]: def load_test_3D_spatial_coordinates(nb_points, transformation_class=None) -> List[AbstractSpatialCoordinates]:
return load_test_spatial_coordinates(nb_points, TEST_3D_SPATIAL_COORDINATES, transformation_class=transformation_class) return load_test_spatial_coordinates(nb_points, TEST_3D_SPATIAL_COORDINATES,
transformation_class=transformation_class)
def load_test_temporal_coordinates(nb_steps, train_split_ratio=None, transformation_class=None): def load_test_temporal_coordinates(nb_steps, train_split_ratio=None, transformation_class=None):
......
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