示例#1
0
def test_nonfinite_multiobjective(objective: int, value: float) -> None:

    study = prepare_study_with_trials(n_objectives=2,
                                      value_for_first_trial=value)
    info = _get_parallel_coordinate_info(study,
                                         target=lambda t: t.values[objective])
    assert all(np.isfinite(info.dim_objective.values))
def plot_parallel_coordinate(
    study: Study,
    params: Optional[List[str]] = None,
    *,
    target: Optional[Callable[[FrozenTrial], float]] = None,
    target_name: str = "Objective Value",
) -> "Axes":
    """Plot the high-dimensional parameter relationships in a study with Matplotlib.

    Note that, if a parameter contains missing values, a trial with missing values is not plotted.

    .. seealso::
        Please refer to :func:`optuna.visualization.plot_parallel_coordinate` for an example.

    Example:

        The following code snippet shows how to plot the high-dimensional parameter relationships.

        .. plot::

            import optuna

            def objective(trial):
                x = trial.suggest_float("x", -100, 100)
                y = trial.suggest_categorical("y", [-1, 0, 1])
                return x ** 2 + y


            sampler = optuna.samplers.TPESampler(seed=10)
            study = optuna.create_study(sampler=sampler)
            study.optimize(objective, n_trials=10)

            optuna.visualization.matplotlib.plot_parallel_coordinate(study, params=["x", "y"])

    Args:
        study:
            A :class:`~optuna.study.Study` object whose trials are plotted for their target values.
        params:
            Parameter list to visualize. The default is all parameters.
        target:
            A function to specify the value to display. If it is :obj:`None` and ``study`` is being
            used for single-objective optimization, the objective values are plotted.

            .. note::
                Specify this argument if ``study`` is being used for multi-objective optimization.
        target_name:
            Target's name to display on the axis label and the legend.

    Returns:
        A :class:`matplotlib.axes.Axes` object.

    .. note::
        The colormap is reversed when the ``target`` argument isn't :obj:`None` or ``direction``
        of :class:`~optuna.study.Study` is ``minimize``.
    """

    _imports.check()
    info = _get_parallel_coordinate_info(study, params, target, target_name)
    return _get_parallel_coordinate_plot(info)
示例#3
0
def test_get_parallel_coordinate_info_with_log_scale_and_str_and_numeric_category(
) -> None:
    # Test with sample from multiple distributions including categorical params
    # that can be interpreted as numeric params.
    study = _create_study_with_log_scale_and_str_and_numeric_category()
    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(1.0, 3.0, 0.0, 2.0),
            range=(0.0, 3.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="param_a",
                values=(1, 1, 0, 0),
                range=(0, 1),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1],
                ticktext=["preferred", "opt"],
            ),
            _DimensionInfo(
                label="param_b",
                values=(0, 1, 1, 2),
                range=(0, 2),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1, 2],
                ticktext=["1", "2", "10"],
            ),
            _DimensionInfo(
                label="param_c",
                values=(math.log10(200), 1.0, math.log10(30), 1.0),
                range=(1.0, math.log10(200)),
                is_log=True,
                is_cat=False,
                tickvals=[1, 2, math.log10(200)],
                ticktext=["10", "100", "200"],
            ),
            _DimensionInfo(
                label="param_d",
                values=(2, 0, 2, 1),
                range=(0, 2),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1, 2],
                ticktext=["-1", "1", "2"],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#4
0
def test_get_parallel_coordinate_info_categorical_numeric_params() -> None:
    # Test with categorical params that can be interpreted as numeric params.
    study = _create_study_with_numeric_categorical_params()

    # Trials are sorted by using param_a and param_b, i.e., trial#1, trial#2, and trial#0.
    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(1.0, 2.0, 0.0),
            range=(0.0, 2.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="category_a",
                values=(0, 1, 1),
                range=(0, 1),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1],
                ticktext=["1", "2"],
            ),
            _DimensionInfo(
                label="category_b",
                values=(2, 0, 1),
                range=(0, 2),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1, 2],
                ticktext=["10", "20", "30"],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#5
0
def test_get_parallel_coordinate_info_log_params() -> None:
    # Test with log params.
    study = _create_study_with_log_params()
    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, 1.0, 0.1),
            range=(0.0, 1.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="param_a",
                values=(-6, math.log10(2e-5), -4),
                range=(-6.0, -4.0),
                is_log=True,
                is_cat=False,
                tickvals=[-6, -5, -4.0],
                ticktext=["1e-06", "1e-05", "0.0001"],
            ),
            _DimensionInfo(
                label="param_b",
                values=(1.0, math.log10(200), math.log10(30)),
                range=(1.0, math.log10(200)),
                is_log=True,
                is_cat=False,
                tickvals=[1.0, 2.0, math.log10(200)],
                ticktext=["10", "100", "200"],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#6
0
def test_get_parallel_coordinate_info_categorical_params() -> None:
    # Test with categorical params that cannot be converted to numeral.
    study = _create_study_with_categorical_params()
    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, 2.0),
            range=(0.0, 2.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="category_a",
                values=(0, 1),
                range=(0, 1),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1],
                ticktext=["preferred", "opt"],
            ),
            _DimensionInfo(
                label="category_b",
                values=(0, 1),
                range=(0, 1),
                is_log=False,
                is_cat=True,
                tickvals=[0, 1],
                ticktext=["net", "una"],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#7
0
def test_get_parallel_coordinate_info_only_missing_params() -> None:
    # When all trials contain only a part of parameters,
    # the plot returns an empty figure.
    study = create_study()
    study.add_trial(
        create_trial(
            value=0.0,
            params={"param_a": 1e-6},
            distributions={
                "param_a": FloatDistribution(1e-7, 1e-2, log=True),
            },
        ))
    study.add_trial(
        create_trial(
            value=1.0,
            params={"param_b": 200},
            distributions={
                "param_b": FloatDistribution(1, 1000, log=True),
            },
        ))

    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(),
            range=(0, 0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#8
0
def test_nonfinite_removed(value: float) -> None:

    study = prepare_study_with_trials(value_for_first_trial=value)
    info = _get_parallel_coordinate_info(study)
    assert all(np.isfinite(info.dim_objective.values))
示例#9
0
def test_get_parallel_coordinate_info_unique_param() -> None:
    # Test case when one unique value is suggested during the optimization.

    study_categorical_params = create_study()
    distributions: Dict[str, BaseDistribution] = {
        "category_a": CategoricalDistribution(("preferred", "opt")),
        "param_b": FloatDistribution(1, 1000, log=True),
    }
    study_categorical_params.add_trial(
        create_trial(
            value=0.0,
            params={
                "category_a": "preferred",
                "param_b": 30
            },
            distributions=distributions,
        ))

    # Both parameters contain unique values.
    info = _get_parallel_coordinate_info(study_categorical_params)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, ),
            range=(0.0, 0.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="category_a",
                values=(0.0, ),
                range=(0, 0),
                is_log=False,
                is_cat=True,
                tickvals=[0],
                ticktext=["preferred"],
            ),
            _DimensionInfo(
                label="param_b",
                values=(math.log10(30), ),
                range=(math.log10(30), math.log10(30)),
                is_log=True,
                is_cat=False,
                tickvals=[math.log10(30)],
                ticktext=["30"],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )

    study_categorical_params.add_trial(
        create_trial(
            value=2.0,
            params={
                "category_a": "preferred",
                "param_b": 20
            },
            distributions=distributions,
        ))

    # Still "category_a" contains unique suggested value during the optimization.
    info = _get_parallel_coordinate_info(study_categorical_params)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, 2.0),
            range=(0.0, 2.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="category_a",
                values=(0, 0),
                range=(0, 0),
                is_log=False,
                is_cat=True,
                tickvals=[0],
                ticktext=["preferred"],
            ),
            _DimensionInfo(
                label="param_b",
                values=(math.log10(30), math.log10(20)),
                range=(math.log10(20), math.log10(30)),
                is_log=True,
                is_cat=False,
                tickvals=[math.log10(20), math.log10(30)],
                ticktext=["20", "30"],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#10
0
def test_get_parallel_coordinate_info() -> None:

    # Test with no trial.
    study = create_study()
    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(),
            range=(0, 0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[],
        reverse_scale=True,
        target_name="Objective Value",
    )

    study = prepare_study_with_trials()

    # Test with no parameters.
    info = _get_parallel_coordinate_info(study, params=[])
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, 2.0, 1.0),
            range=(0.0, 2.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[],
        reverse_scale=True,
        target_name="Objective Value",
    )

    # Test with a trial.
    info = _get_parallel_coordinate_info(study, params=["param_a", "param_b"])
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, 1.0),
            range=(0.0, 1.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="param_a",
                values=(1.0, 2.5),
                range=(1.0, 2.5),
                is_log=False,
                is_cat=False,
                tickvals=[],
                ticktext=[],
            ),
            _DimensionInfo(
                label="param_b",
                values=(2.0, 1.0),
                range=(1.0, 2.0),
                is_log=False,
                is_cat=False,
                tickvals=[],
                ticktext=[],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )

    # Test with a trial to select parameter.
    info = _get_parallel_coordinate_info(study, params=["param_a"])
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(0.0, 1.0),
            range=(0.0, 1.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="param_a",
                values=(1.0, 2.5),
                range=(1.0, 2.5),
                is_log=False,
                is_cat=False,
                tickvals=[],
                ticktext=[],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )

    # Test with a customized target value.
    with pytest.warns(UserWarning):
        info = _get_parallel_coordinate_info(
            study, params=["param_a"], target=lambda t: t.params["param_b"])
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(2.0, 1.0),
            range=(1.0, 2.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="param_a",
                values=(1.0, 2.5),
                range=(1.0, 2.5),
                is_log=False,
                is_cat=False,
                tickvals=[],
                ticktext=[],
            ),
        ],
        reverse_scale=True,
        target_name="Objective Value",
    )

    # Test with a customized target name.
    info = _get_parallel_coordinate_info(study,
                                         params=["param_a", "param_b"],
                                         target_name="Target Name")
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Target Name",
            values=(0.0, 1.0),
            range=(0.0, 1.0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[
            _DimensionInfo(
                label="param_a",
                values=(1.0, 2.5),
                range=(1.0, 2.5),
                is_log=False,
                is_cat=False,
                tickvals=[],
                ticktext=[],
            ),
            _DimensionInfo(
                label="param_b",
                values=(2.0, 1.0),
                range=(1.0, 2.0),
                is_log=False,
                is_cat=False,
                tickvals=[],
                ticktext=[],
            ),
        ],
        reverse_scale=True,
        target_name="Target Name",
    )

    # Test with wrong params that do not exist in trials.
    with pytest.raises(ValueError,
                       match="Parameter optuna does not exist in your study."):
        _get_parallel_coordinate_info(study, params=["optuna", "optuna"])

    # Ignore failed trials.
    study = _create_study_with_failed_trial()
    info = _get_parallel_coordinate_info(study)
    assert info == _ParallelCoordinateInfo(
        dim_objective=_DimensionInfo(
            label="Objective Value",
            values=(),
            range=(0, 0),
            is_log=False,
            is_cat=False,
            tickvals=[],
            ticktext=[],
        ),
        dims_params=[],
        reverse_scale=True,
        target_name="Objective Value",
    )
示例#11
0
def test_target_is_none_and_study_is_multi_obj() -> None:

    study = create_study(directions=["minimize", "minimize"])
    with pytest.raises(ValueError):
        _get_parallel_coordinate_info(study)