Closed tom-andersson closed 4 months ago
cc @wesselb, an alternative would be to make the location of the spike in Bernoulli-Gamma configurable in neuralprocesses
, and expose this through construct_convgnp
. We could then keep the [-1, +1] hard-coding in DeepSensor and set the spike location to -1. I'm not sure which approach would be simpler!
The Bernoulli-gamma distribution handles unbounded data. Instead of normalising to a bounded interval, perhaps it would be best to normalise to the unbounded the interval [0, inf)
? I'm thinking something like x -> (x - min(x)) / scale(x)
where scale(x) = std(x)
or scale(x) = median(x)
.
Good shout @wesselb! We could then add this as a new DataProcessor
normalisation method (for example, 'min_median'
, or perhaps more explicitly 'positive_semidefinite'
).
This would avoid having to worry about backwards compatibility of the 'min_max'
method (which we can keep as normalising to [-1, +1]).
Specific list of steps to implement this feature:
The test_data_processor
already loops over the valid_methods
of the DataProcessor, so we shouldn't need to explicitly add a unit test: https://github.com/alan-turing-institute/deepsensor/blob/main/tests/test_data_processor.py#L66
Closed by: https://github.com/alan-turing-institute/deepsensor/commit/88a98182d07edcaf0ac490ea75378f15b1c45dfb
Choices:
'positive_semidefinite
' for the DataProcessor normalisation method nameThanks @wesselb for the idea!
TL;DR The
DataProcessor
hard-codes min-max normalisation to [-1, 1], but we now have a use case for mapping to [0, new_max]. So we need a new feature that makes this configurable to the user. Motivation below:DeepSensor now supports a ConvCNP with a Bernoulli-Gamma likelihood (thanks @wesselb for implementing this upstream in
neuralprocesses
!), see https://github.com/alan-turing-institute/deepsensor/issues/95. This is useful for modelling lower-bounded variables which can take values exactly equal to the lower bound, e.g. precipitation which has many values of exactly zero (no rain).The current Bernoulli-Gamma implementation in
neuralprocesses
hard-codes the delta/'spike' component of the Bernoulli-Gamma mixture to take a value of zero (which is reasonable). However, when normalising data with DeepSensor'sDataProcessor
, usingdata_processor(data, method="min_max")
hard-codes the new min and max to be -1 and +1, respectively. This is incompatible withConvNP(..., likelihood="bernoulli-gamma")
, because any target values below 0 results in a NaN loss (and NaN weights). So, we now need to configure the new min/max of the normalised data.I would envisage this being configurable through the
__call__
so that it can be different for each variable, likenormalised_data = data_processor(raw_data, method="min_max", new_min=0, new_max=1)
, which would be passed from__call__
tomap
tomap_array
, with new logic for"min_max"
here.A few extra bits of housekeeping needed:
Set the default values to -1 and +1 for backwards compatibility. We should also consider how this will break user's existing
DataProcessor
configs (which will not have these parameter values).Store in the
DataProcessor
config, eg like:Unit test this in
deepsensor/tests/test_data_processor.py
, in particular adding this new normalisation feature to the unit test that asserts normalised data is the same after saving and loading aDataProcessor
.