def testMatchCIWidth(self): Ys = get_data([self.obsd1, self.obsd2, self.obsd3], ["m2"]) pt = _compute_power_transforms(Ys) pt["m2"].lambdas_.fill(-3.0) bounds = _compute_inverse_bounds(pt)["m2"] # Both will be NaN since we are far outside the bounds new_mean_1, new_var_1 = match_ci_width_truncated( mean=bounds[1] + 2.0, variance=0.1, transform=lambda y: pt["m2"].inverse_transform(np.array(y, ndmin=2)), lower_bound=bounds[0], upper_bound=bounds[1], margin=0.001, clip_mean=False, ) # This will be finite since we clip new_mean_2, new_var_2 = match_ci_width_truncated( mean=bounds[1] + 2.0, variance=0.1, transform=lambda y: pt["m2"].inverse_transform(np.array(y, ndmin=2)), lower_bound=bounds[0], upper_bound=bounds[1], margin=0.001, clip_mean=True, ) self.assertTrue(isnan(new_mean_1) and isnan(new_var_1)) self.assertTrue(isfinite(new_mean_2) and isfinite(new_var_2))
def transform_observation_data( self, observation_data: List[ObservationData], observation_features: List[ObservationFeatures], ) -> List[ObservationData]: """Winsorize observation data in place.""" for obsd in observation_data: for i, m in enumerate(obsd.metric_names): if m in self.metric_names: transform = self.power_transforms[m].transform obsd.means[i], obsd.covariance[i, i] = match_ci_width_truncated( mean=obsd.means[i], variance=obsd.covariance[i, i], transform=lambda y: transform(np.array(y, ndmin=2)), lower_bound=-np.inf, upper_bound=np.inf, ) return observation_data
def transform_observation_data( self, observation_data: List[ObservationData], observation_features: List[ObservationFeatures], ) -> List[ObservationData]: """Map to inverse Gaussian CDF in place.""" # TODO (jej): Transform covariances. for obsd in observation_data: for idx, _ in enumerate(obsd.metric_names): mean = float(obsd.means[idx]) # Error on out-of-domain values. if mean <= 0.0 or mean >= 1.0: raise ValueError( f"Inverse CDF cannot transform value: {mean} outside (0, 1)" ) var = float(obsd.covariance[idx, idx]) transformed_mean, transformed_var = match_ci_width_truncated( mean, var, self._map, lower_bound=0.0, upper_bound=1.0) obsd.means[idx] = transformed_mean obsd.covariance[idx, idx] = transformed_var return observation_data
def untransform_observation_data( self, observation_data: List[ObservationData], observation_features: List[ObservationFeatures], ) -> List[ObservationData]: """Winsorize observation data in place.""" for obsd in observation_data: for i, m in enumerate(obsd.metric_names): if m in self.metric_names: l, u = self.inv_bounds[m] transform = self.power_transforms[m].inverse_transform if not self.clip_mean and (obsd.means[i] < l or obsd.means[i] > u): raise ValueError( "Can't untransform mean outside the bounds without clipping" ) obsd.means[i], obsd.covariance[i, i] = match_ci_width_truncated( mean=obsd.means[i], variance=obsd.covariance[i, i], transform=lambda y: transform(np.array(y, ndmin=2)), lower_bound=l, upper_bound=u, clip_mean=True, ) return observation_data