Example #1
0
    def check_membership(
        self, parameterization: TParameterization, raise_error: bool = False
    ) -> bool:
        """Whether the given parameterization belongs in the search space.

        Checks that the given parameter values have the same name/type as
        search space parameters, are contained in the search space domain,
        and satisfy the parameter constraints.

        Args:
            parameterization: Dict from parameter name to value to validate.
            raise_error: If true parameterization does not belong, raises an error
                with detailed explanation of why.

        Returns:
            Whether the parameterization is contained in the search space.
        """
        if len(parameterization) != len(self._parameters):
            if raise_error:
                raise ValueError(
                    f"Parameterization has {len(parameterization)} parameters "
                    f"but search space has {len(self._parameters)}."
                )
            return False

        for name, value in parameterization.items():
            if name not in self._parameters:
                if raise_error:
                    raise ValueError(
                        f"Parameter {name} not defined in search space"
                        f"with parameters {self._parameters}"
                    )
                return False

            if not self._parameters[name].validate(value):
                if raise_error:
                    raise ValueError(
                        f"{value} is not a valid value for "
                        f"parameter {self._parameters[name]}"
                    )
                return False

        # parameter constraints only accept numeric parameters
        numerical_param_dict = {
            # pyre-fixme[6]: Expected `typing.Union[...oat]` but got `unknown`.
            name: float(value)
            for name, value in parameterization.items()
            if self._parameters[name].is_numeric
        }

        for constraint in self._parameter_constraints:
            if not constraint.check(numerical_param_dict):
                if raise_error:
                    raise ValueError(f"Parameter constraint {constraint} is violated.")
                return False

        return True
Example #2
0
    def check_types(
        self,
        parameterization: TParameterization,
        allow_none: bool = True,
        raise_error: bool = False,
    ) -> bool:
        """Checks that the given parameterization's types match the search space.

        Args:
            parameterization: Dict from parameter name to value to validate.
            allow_none: Whether None is a valid parameter value.
            raise_error: If true and parameterization does not belong, raises an error
                with detailed explanation of why.

        Returns:
            Whether the parameterization has valid types.
        """
        for name, value in parameterization.items():
            if name not in self._parameters:
                if raise_error:
                    raise ValueError(
                        f"Parameter {name} not defined in search space")
                return False

            if value is None and allow_none:
                continue

            if not self._parameters[name].is_valid_type(value):
                if raise_error:
                    raise ValueError(f"{value} is not a valid value for "
                                     f"parameter {self._parameters[name]}")
                return False

        return True
Example #3
0
def _numpy_types_to_python_types(
    parameterization: TParameterization, ) -> TParameterization:
    """If applicable, coerce values of the parameterization from Numpy int/float to
    Python int/float.
    """
    return {
        name: numpy_type_to_python_type(value)
        for name, value in parameterization.items()
    }
Example #4
0
def _parameterization_probability(
    parameterization: TParameterization,
    coefficients: Dict[str, Dict[TParamValue, float]],
    noise_var: float = 0.0,
) -> float:
    z = 0.0
    for factor, level in parameterization.items():
        if factor not in coefficients.keys():
            raise ValueError("{} not in supplied coefficients".format(factor))
        if level not in coefficients[factor].keys():
            raise ValueError("{} not a valid level of {}".format(level, factor))
        z += coefficients[factor][level]
    z += np.sqrt(noise_var) * np.random.randn()
    return np.exp(z) / (1 + np.exp(z))
Example #5
0
    def md5hash(parameters: TParameterization) -> str:
        """Return unique identifier for arm's parameters.

        Args:
            parameters: Parameterization; mapping of param name
                to value.

        Returns:
            Hash of arm's parameters.

        """
        for k, v in parameters.items():
            parameters[k] = numpy_type_to_python_type(v)
        parameters_str = json.dumps(parameters, sort_keys=True)
        return hashlib.md5(parameters_str.encode("utf-8")).hexdigest()
Example #6
0
    def check_types(
        self,
        parameterization: TParameterization,
        allow_none: bool = True,
        raise_error: bool = False,
    ) -> bool:
        """Checks that the given parameterization's types match the search space.

        Checks that the names of the parameterization match those specified in
        the search space, and the given values are of the correct type.

        Args:
            parameterization: Dict from parameter name to value to validate.
            allow_none: Whether None is a valid parameter value.
            raise_error: If true and parameterization does not belong, raises an error
                with detailed explanation of why.

        Returns:
            Whether the parameterization has valid types.
        """
        if len(parameterization) != len(self._parameters):
            if raise_error:
                raise ValueError(
                    f"Parameterization has {len(parameterization)} parameters "
                    f"but search space has {len(self._parameters)}.\n"
                    f"Parameterization: {parameterization}.\n"
                    f"Search Space: {self._parameters}."
                )
            return False

        for name, value in parameterization.items():
            if name not in self._parameters:
                if raise_error:
                    raise ValueError(f"Parameter {name} not defined in search space")
                return False

            if value is None and allow_none:
                continue

            if not self._parameters[name].is_valid_type(value):
                if raise_error:
                    raise ValueError(
                        f"{value} is not a valid value for "
                        f"parameter {self._parameters[name]}"
                    )
                return False

        return True
Example #7
0
def _format_dict(param_dict: TParameterization,
                 name: str = "Parameterization") -> str:
    """Format a dictionary for labels.

    Args:
        param_dict: Dictionary to be formatted
        name: String name of the thing being formatted.

    Returns: stringified blob.
    """
    if len(param_dict) >= 10:
        blob = "{} has too many items to render on hover ({}).".format(
            name, len(param_dict))
    else:
        blob = "<br><em>{}:</em><br>{}".format(
            name,
            "<br>".join("{}: {}".format(n, v) for n, v in param_dict.items()))
    return blob
Example #8
0
    def _cast_parameterization(
        self,
        parameters: TParameterization,
        check_all_parameters_present: bool = True,
    ) -> TParameterization:
        """Cast parameterization (of an arm, observation features, etc.) to the
        hierarchical structure of this search space.

        Args:
            parameters: Parameterization to cast to hierarchical structure.
            check_all_parameters_present: Whether to raise an error if a paramete
                 that is expected to be present (according to values of other
                 parameters and the hierarchical structure of the search space)
                 is not specified.
        """
        def _find_applicable_parameters(root: Parameter) -> Set[str]:
            applicable = {root.name}
            if check_all_parameters_present and root.name not in parameters:
                raise RuntimeError(
                    f"Parameter '{root.name}' not in parameterization to cast."
                )

            if not root.is_hierarchical:
                return applicable

            for val, deps in root.dependents.items():
                if parameters[root.name] == val:
                    for dep in deps:
                        applicable.update(
                            _find_applicable_parameters(root=self[dep]))

            return applicable

        applicable_paramers = _find_applicable_parameters(root=self.root)
        if not all(k in parameters for k in applicable_paramers):
            raise RuntimeError(
                f"Parameters {applicable_paramers- set(parameters.keys())} "
                "missing from the arm.")

        return {
            k: v
            for k, v in parameters.items() if k in applicable_paramers
        }
Example #9
0
def _filter_dict(param_dict: TParameterization,
                 subset_keys: List[str]) -> TParameterization:
    """Filter a dictionary to keys present in a given list."""
    return {k: v for k, v in param_dict.items() if k in subset_keys}