-
Notifications
You must be signed in to change notification settings - Fork 22
MESMER-MTP: precipitation #837
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 17 commits
b860f26
89e8379
f8666dc
1a887f0
6aa64b8
dd107ef
280c2d5
a201b92
d12984d
41516be
2ce820b
64d74e7
ae35f10
be0f0ad
2c20be8
f164511
8468527
4ef816e
2c4a4e6
fa77591
af0d1c4
2a6b192
376a66e
227b886
b6b6f4c
820b019
6bf8812
86543c2
2d0f360
01b9244
fee6952
aaddfe9
8c71c1e
e204f7a
98e6c6e
11f57da
84e2a12
9d29750
8154e3c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,176 @@ | ||
| import numpy as np | ||
| import xarray as xr | ||
|
|
||
| # from mesmer.core.utils import ( | ||
| # _check_dataarray_form, | ||
| # _check_dataset_form | ||
| # ) | ||
| # ToDo: Add inverse transform & StandardScaling prior to transforming | ||
| from sklearn.preprocessing import StandardScaler | ||
|
|
||
|
|
||
| def fit_principal_components(X: xr.DataArray, n_components=None): | ||
| """ | ||
| Fit a principal component decomposition | ||
|
|
||
| Parameters | ||
| ---------- | ||
| X : xr.DataArray | ||
| DataArray to decompose. Must be 2D. PCA is tranformed over the second dimension. | ||
| """ | ||
|
|
||
| if n_components is None: | ||
| n_components = X.values.shape[1] | ||
|
|
||
| params = _fit_principal_component_decomposition_xr(X=X, n_components=n_components) | ||
|
|
||
| return params | ||
|
|
||
|
|
||
| def _fit_principal_component_decomposition_xr( | ||
| X: xr.DataArray, | ||
| n_components: int, | ||
| ) -> xr.Dataset: | ||
| """ | ||
| Fit a principal component decomposition | ||
|
|
||
| Parameters | ||
| ---------- | ||
| X : xr.DataArray | ||
| DataArray to decompose. Must be 2D. | ||
|
|
||
| Returns | ||
| ------- | ||
| :obj:`xr.Dataset` | ||
| Dataset of projection coefficients. | ||
| """ | ||
|
|
||
| X_np = X.values | ||
|
|
||
| std = StandardScaler().fit(X_np) | ||
| X_np_std = std.transform(X_np) | ||
|
|
||
| from sklearn.decomposition import PCA as PCA_np | ||
|
|
||
| pca = PCA_np(n_components=n_components).fit(X_np_std) | ||
|
|
||
| params = xr.Dataset( | ||
| { | ||
| "coeffs": (("component", X.dims[1]), pca.components_), | ||
| "mean": (X.dims[1], pca.mean_), | ||
| "explained_variance": ("component", pca.explained_variance_), | ||
| "std_scale": (X.dims[1], std.scale_), | ||
| "std_mean": (X.dims[1], std.mean_), | ||
| "std_var": (X.dims[1], std.var_), | ||
| }, | ||
| coords={X.dims[1]: X[X.dims[1]], "component": np.arange(n_components)}, | ||
| ) | ||
|
|
||
| return params | ||
|
|
||
|
|
||
| def transform_principal_components( | ||
| X: xr.DataArray, | ||
| params: xr.DataArray, | ||
| ) -> xr.DataArray: | ||
| """ | ||
| Project input data onto eigenspace. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| X : xr.DataArray | ||
| DataArray to project onto eigenspace given the previously computed components. | ||
|
|
||
| Returns | ||
| ------- | ||
| T : xr.DataArray | ||
| Vector of principal components. | ||
| """ | ||
|
|
||
| T = _transform_principal_component_decomposition_xr(X=X, params=params) | ||
|
|
||
| return T | ||
|
|
||
|
|
||
| def _transform_principal_component_decomposition_xr( | ||
|
Comment on lines
+90
to
+95
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (there is not much point to having a wrapper function here) |
||
| X: xr.DataArray, params: xr.DataArray | ||
| ) -> xr.DataArray: | ||
|
|
||
| from sklearn.decomposition import PCA as PCA_np | ||
|
|
||
| std = StandardScaler() | ||
| std.n_features_in_ = len(params["std_scale"]) | ||
| std.scale_ = params["std_scale"].values | ||
| std.mean_ = params["std_mean"].values | ||
| std.var_ = params["std_var"].values | ||
|
|
||
| pca = PCA_np() | ||
| pca.n_components_ = params["coeffs"].shape[0] | ||
| pca.components_ = params["coeffs"].values | ||
| pca.mean_ = params["mean"].values | ||
| pca.explained_variance_ = params["explained_variance"].values | ||
|
|
||
| X_trans_np = pca.transform(std.transform(X.values)) | ||
|
|
||
| X_trans = xr.DataArray( | ||
| X_trans_np, | ||
| dims=[X.dims[0], "component"], | ||
| coords={X.dims[0]: X[X.dims[0]], "component": np.arange(pca.n_components_)}, | ||
| ) | ||
| return X_trans | ||
|
|
||
|
|
||
| def inverse_transform_principal_components( | ||
| T: xr.DataArray, | ||
| params: xr.DataArray, | ||
| ) -> xr.DataArray: | ||
| """ | ||
| Project input data onto eigenspace. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| X : xr.DataArray | ||
| DataArray to project onto eigenspace given the previously computed components. | ||
|
|
||
| Returns | ||
| ------- | ||
| T : xr.DataArray | ||
| Vector of principal components. | ||
| """ | ||
|
|
||
| T = _inverse_transform_principal_component_decomposition_xr(T=T, params=params) | ||
|
|
||
| return T | ||
|
|
||
|
|
||
| def _inverse_transform_principal_component_decomposition_xr( | ||
| T: xr.DataArray, params: xr.DataArray | ||
| ) -> xr.DataArray: | ||
|
|
||
| from sklearn.decomposition import PCA as PCA_np | ||
|
|
||
| pca = PCA_np() | ||
| pca.n_components_ = params["coeffs"].shape[0] | ||
| pca.components_ = params["coeffs"].values | ||
| pca.mean_ = params["mean"].values | ||
| pca.explained_variance_ = params["explained_variance"].values | ||
|
|
||
| X_np_std = pca.inverse_transform(T.values) | ||
|
|
||
| std = StandardScaler() | ||
| std.n_features_in_ = len(params["std_scale"]) | ||
| std.scale_ = params["std_scale"].values | ||
| std.mean_ = params["std_mean"].values | ||
| std.var_ = params["std_var"].values | ||
|
|
||
| X_np = std.inverse_transform(X_np_std) | ||
|
|
||
| X = xr.DataArray( | ||
| X_np, | ||
| dims=[T.dims[0], "gridcell"], | ||
| coords={ | ||
| T.dims[0]: T[T.dims[0]], | ||
| params["coeffs"].dims[1]: params["coeffs"][params["coeffs"].dims[1]], | ||
| }, | ||
| ) | ||
| return X | ||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,182 @@ | ||||
| # MESMER-M, land-climate dynamics group, S.I. Seneviratne | ||||
| # Copyright (c) 2021 ETH Zurich, MESMER contributors listed in AUTHORS. | ||||
| # Licensed under the GNU General Public License v3.0 or later see LICENSE or | ||||
| # https://www.gnu.org/licenses/ | ||||
|
|
||||
| """ | ||||
| Functions to train monthly trend module of MESMER-M | ||||
| """ | ||||
|
|
||||
|
|
||||
| import numpy as np | ||||
| import statsmodels.api as sm | ||||
| import xarray as xr | ||||
| from joblib import Parallel, delayed | ||||
|
|
||||
| from mesmer._core.utils import _ignore_warnings | ||||
|
|
||||
|
|
||||
| # haven't properly commented this yet - WIP | ||||
|
||||
| # haven't properly commented this yet - WIP |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not looked at this in details but this is very use case specific - check if we could move this out of the function somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I find it not very obvious that these belong to the
StandardScaler.