def prepare_logistic(self, normalized_dist: dist.Logistic) -> dist.Logistic: """ Transform a single logistic distribution by clipping the parameters and adding scale information as needed for submission to Metaculus. The loc and scale have to be within a certain range for the Metaculus API to accept the prediction. :param dist: a (normalized) logistic distribution :return: a transformed logistic distribution """ if hasattr(normalized_dist, "base_dist"): normalized_dist = normalized_dist.base_dist # type: ignore if normalized_dist.s <= 0: raise ValueError("logistic_params.scale must be greater than 0") clipped_loc = min(normalized_dist.loc, max_loc) clipped_scale = float(onp.clip(normalized_dist.s, min_scale, max_scale)) # type: ignore if self.low_open: low = float(onp.clip(normalized_dist.cdf(0), min_open_low, max_open_low,)) else: low = 0 if self.high_open: high = float( onp.clip(normalized_dist.cdf(1), min_open_high + low, max_open_high,) ) else: high = 1 return dist.Logistic( clipped_loc, clipped_scale, Scale(0, 1), {"low": low, "high": high} )
def get_logistic_from_json(logistic_json: Dict) -> dist.Logistic: return dist.Logistic( logistic_json["x0"], logistic_json["s"], metadata={ "low": logistic_json["low"], "high": logistic_json["high"] }, )
def get_logistic_from_json(self, logistic_json: Dict) -> dist.Logistic: bounds = self.get_bounds() normed_bounds = {} if bounds.floor is not None: normed_bounds["floor"] = self.scale.normalize_point(bounds.floor) if bounds.ceiling is not None: normed_bounds["ceiling"] = self.scale.normalize_point(bounds.ceiling) return dist.Truncate( # type: ignore dist.Logistic(logistic_json["x0"], logistic_json["s"], normalized=True), **normed_bounds, )