示例#1
0
    def gen(
        self,
        n: int,
        parameter_values: List[TParamValueList],
        objective_weights: Optional[np.ndarray],
        outcome_constraints: Optional[Tuple[np.ndarray, np.ndarray]] = None,
        fixed_features: Optional[Dict[int, TParamValue]] = None,
        pending_observations: Optional[List[List[TParamValueList]]] = None,
        model_gen_options: Optional[TConfig] = None,
    ) -> Tuple[List[TParamValueList], List[float], TGenMetadata]:
        if objective_weights is None:
            raise ValueError("ThompsonSampler requires objective weights.")

        arms = self.X
        k = len(arms)

        weights = self._generate_weights(
            objective_weights=objective_weights,
            outcome_constraints=outcome_constraints)
        min_weight = self.min_weight if self.min_weight is not None else 2.0 / k

        # Second entry is used for tie-breaking
        weighted_arms = [
            (weights[i], np.random.random(), arms[i]) for i in range(k)
            # pyre-fixme[58]: `>` is not supported for operand types `float` and
            #  `Optional[float]`.
            if weights[i] > min_weight
        ]

        if len(weighted_arms) == 0:
            raise ModelError(
                TS_MIN_WEIGHT_ERROR.format(min_weight=min_weight,
                                           max_weight=max(weights)))

        weighted_arms.sort(reverse=True)
        top_weighted_arms = weighted_arms[:n] if n > 0 else weighted_arms
        top_arms = [arm for _, _, arm in top_weighted_arms]
        top_weights = [weight for weight, _, _ in top_weighted_arms]

        # N TS arms should have total weight N
        if self.uniform_weights:
            top_weights = [1.0 for _ in top_weights]
        else:
            top_weights = [(x * len(top_weights)) / sum(top_weights)
                           for x in top_weights]
        return top_arms, top_weights, {
            "arms_to_weights": list(zip(arms, weights))
        }
示例#2
0
文件: thompson.py 项目: pr0d33p/Ax
    def gen(
        self,
        n: int,
        parameter_values: List[TParamValueList],
        objective_weights: Optional[np.ndarray],
        outcome_constraints: Optional[Tuple[np.ndarray, np.ndarray]] = None,
        fixed_features: Optional[Dict[int, TParamValue]] = None,
        pending_observations: Optional[List[List[TParamValueList]]] = None,
        model_gen_options: Optional[TConfig] = None,
    ) -> Tuple[List[TParamValueList], List[float], TGenMetadata]:
        if objective_weights is None:
            raise ValueError("ThompsonSampler requires objective weights.")

        arms = self.X
        # pyre-fixme[6]: Expected `Sized` for 1st param but got `None`.
        k = len(arms)

        weights = self._generate_weights(
            objective_weights=objective_weights, outcome_constraints=outcome_constraints
        )
        min_weight = self.min_weight if self.min_weight is not None else 2.0 / k

        # Second entry is used for tie-breaking
        weighted_arms = [
            # pyre-fixme[16]: `None` has no attribute `__getitem__`.
            (weights[i], np.random.random(), arms[i])
            for i in range(k)
            # pyre-fixme[6]: Expected `float` for 1st param but got `Optional[float]`.
            if weights[i] > min_weight
        ]

        if len(weighted_arms) == 0:
            raise ModelError(
                TS_MIN_WEIGHT_ERROR.format(
                    min_weight=min_weight, max_weight=max(weights)
                )
            )

        weighted_arms.sort(reverse=True)
        top_weighted_arms = weighted_arms[:n] if n > 0 else weighted_arms
        top_arms = [arm for _, _, arm in top_weighted_arms]
        top_weights = [weight for weight, _, _ in top_weighted_arms]

        if self.uniform_weights:
            top_weights = [1 / len(top_arms) for _ in top_arms]

        return top_arms, [x / sum(top_weights) for x in top_weights], {}