<jupyter_start><jupyter_text>Bias Removal Climate models can have biases relative to different verification datasets. Commonly, biases are removed by postprocessing before verification of forecasting skill. `climpred` provides convenience functions to do so.<jupyter_code>import climpred
import xarray as xr
import matplotlib.pyplot as plt
from climpred import HindcastEnsemble
hind = climpred.tutorial.load_dataset('CESM-DP-SST') # CESM-DPLE hindcast ensemble output.
obs = climpred.tutorial.load_dataset('ERSST') # observations
hind["lead"].attrs["units"] = "years"<jupyter_output><empty_output><jupyter_text>We begin by removing a mean climatology for the observations, since `CESM-DPLE` generates its anomalies over this same time period.<jupyter_code>obs = obs - obs.sel(time=slice('1964', '2014')).mean('time')
hindcast = HindcastEnsemble(hind)
hindcast = hindcast.add_observations(obs)
hindcast.plot()<jupyter_output>/Users/rileybrady/Desktop/dev/climpred/climpred/utils.py:141: UserWarning: Assuming annual resolution due to numeric inits. Change init to a datetime if it is another resolution.
  "Assuming annual resolution due to numeric inits. "<jupyter_text>The warming of the `observations` is similar to `initialized`.  Mean bias removal Typically, bias depends on lead-time and therefore should therefore also be removed depending on lead-time.<jupyter_code>bias = hindcast.verify(metric='bias', comparison='e2o', dim=[], alignment='same_verifs')
bias.SST.plot()<jupyter_output><empty_output><jupyter_text>Against `observations`, there is small cold bias in 1980 and 1990 initialization years and warm bias before and after.<jupyter_code># lead-time dependant mean bias over all initializations is quite small but negative
mean_bias = bias.mean('init')
mean_bias.SST.plot()<jupyter_output><empty_output><jupyter_text>Cross ValidatationTo remove the mean bias quickly, the mean bias over all initializations is subtracted. For formally correct bias removal with cross validation, the given initialization is left out when subtracting the mean bias. `climpred` wraps these functions in `HindcastEnsemble.remove_bias(how='mean', cross_validate={bool})`.<jupyter_code>hindcast.remove_bias(how='mean', cross_validate=True, alignment='same_verifs').plot()
plt.title('hindcast lead timeseries removed for unconditional mean bias')
plt.show()<jupyter_output><empty_output><jupyter_text>Skill Distance-based accuracy metrics like (`mse`,`rmse`,`nrmse`,...) are sensitive to mean bias removal. Correlations like (`pearson_r`, `spearman_r`) are insensitive to bias correction.<jupyter_code>metric='rmse'
hindcast.verify(metric=metric,
                comparison='e2o',
                dim='init',
                alignment='same_verifs')['SST'].plot(label='no bias correction')
hindcast.remove_bias(cross_validate=False,
                     alignment='same_verifs') \
        .verify(metric=metric,
                comparison='e2o',
                dim='init',
                alignment='same_verifs').SST.plot(label='bias correction without cross validation')
hindcast.remove_bias(cross_validate=True,
                     alignment='same_verifs') \
        .verify(metric=metric,
                comparison='e2o',
                dim='init',
                alignment='same_verifs').SST.plot(label='formally correct bias correction with cross validation')
plt.legend()
plt.title(f"{metric.upper()} SST evaluated against observations")
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10310166570936244, 'fraction_numerical': 0.006605399195864446, 'mean_word_length': 5.132042253521127, 'pattern_counts': {'":': 0, '<': 24, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '1963', 'license': 'MIT', 'n_tokens_mistral': 1032, 'n_tokens_neox': 969, 'n_words': 277, 'path': 'docs/source/bias_removal.ipynb', 'repo_name': 'andersy005/climpred', 'size': '3482'}