internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: optuna/optuna

Issue:
Duplicated DB access in `_log_completed_trial`
### Motivation

We can reduce the number of calling `storage.get_best_trial`.

### Description

In `_log_completed_trial`, `best_trial` is called twice. (Note: `best_value` calls `best_trial`) https://github.com/optuna/optuna/blob/a07a36e124d6523677d718819cad61628e8621e7/optuna/study/study.py#L1051-L1052

### Alternatives (optional)

_No response_

### Additional context (optional)

_No response_


Discussion:
This issue has not seen any recent activity.
This issue has not seen any recent activity.
This issue has not seen any recent activity.

Resolving patch:
diff --git a/optuna/study/study.py b/optuna/study/study.py
--- a/optuna/study/study.py
+++ b/optuna/study/study.py
@@ -948,14 +948,15 @@ def _log_completed_trial(self, trial: trial_module.FrozenTrial) -> None:
                 )
             )
         elif len(trial.values) == 1:
+            best_trial = self.best_trial
             _logger.info(
                 "Trial {} finished with value: {} and parameters: {}. "
                 "Best is trial {} with value: {}.".format(
                     trial.number,
                     trial.values[0],
                     trial.params,
-                    self.best_trial.number,
-                    self.best_value,
+                    best_trial.number,
+                    best_trial.value,
                 )
             )
         else:


Test patch:
diff --git a/tests/study_tests/test_study.py b/tests/study_tests/test_study.py
--- a/tests/study_tests/test_study.py
+++ b/tests/study_tests/test_study.py
@@ -1009,8 +1009,7 @@ def test_log_completed_trial_skip_storage_access() -> None:
 
     with patch.object(storage, "get_best_trial", wraps=storage.get_best_trial) as mock_object:
         study._log_completed_trial(frozen_trial)
-        # Trial.best_trial and Trial.best_params access storage.
-        assert mock_object.call_count == 2
+        assert mock_object.call_count == 1
 
     logging.set_verbosity(logging.WARNING)
     with patch.object(storage, "get_best_trial", wraps=storage.get_best_trial) as mock_object:
@@ -1020,7 +1019,7 @@ def test_log_completed_trial_skip_storage_access() -> None:
     logging.set_verbosity(logging.DEBUG)
     with patch.object(storage, "get_best_trial", wraps=storage.get_best_trial) as mock_object:
         study._log_completed_trial(frozen_trial)
-        assert mock_object.call_count == 2
+        assert mock_object.call_count == 1
 
 
 def test_create_study_with_multi_objectives() -> None:
Repository: optuna/optuna

Issue:
If seed is fixed, SkoptSampler suggests exactly the same parameter sets during startup trials
### Expected behavior

The suggested parameters should be reproducible but not all trials should use exactly the same values.

### Environment

- Optuna version:3.0.2
- Python version:3.8.5
- OS:Windows-10-10.0.19041-SP0
- skopt version: 0.9.0

### Error messages, stack traces, or logs

```shell
params_x
0    0.976270
1    1.856892
2    1.856892
3    1.856892
4    1.856892
5    1.856892
6    1.856892
7    1.856892
8    1.856892
9    1.856892
10   2.326864
11  -9.084558
12  10.000000
13   2.173857
14   2.111044
15   2.090603
16   2.069437
17   2.061775
18   2.032221
19   2.018462
```


### Steps to reproduce

Run the minimal example. Trials 1 (not 0) to 9 have identical x.

```python
import optuna


def objective(trial):
    x = trial.suggest_float("x", -10, 10)
    return (x - 2) ** 2

sampler = optuna.integration.SkoptSampler(seed=0)
study = optuna.create_study(sampler=sampler)

study.optimize(objective,  n_trials=20)

print(study.trials_dataframe()[['params_x']])
```

![image](https://user-images.githubusercontent.com/7721866/192567723-5362ec5e-26d7-47cc-a236-93971c54ae23.png)


### Additional context (optional)

_No response_


Discussion:

Resolving patch:
diff --git a/optuna/integration/skopt.py b/optuna/integration/skopt.py
--- a/optuna/integration/skopt.py
+++ b/optuna/integration/skopt.py
@@ -136,6 +136,7 @@ def __init__(
 
         if seed is not None and "random_state" not in self._skopt_kwargs:
             self._skopt_kwargs["random_state"] = seed
+        self._rng: Optional[np.random.RandomState] = None
 
     def reseed_rng(self) -> None:
 
@@ -177,8 +178,12 @@ def sample_relative(
             return {}
 
         optimizer = _Optimizer(search_space, self._skopt_kwargs)
+        if self._rng is not None:
+            optimizer._optimizer.rng = self._rng
         optimizer.tell(study, complete_trials)
-        return optimizer.ask()
+        params = optimizer.ask()
+        self._rng = optimizer._optimizer.rng
+        return params
 
     def sample_independent(
         self,


Test patch:
Repository: optuna/optuna

Issue:
`None` categorical not visible on Slice plot
### Expected behavior

I have a categorical like this: `trial.suggest_categorical("class_weight", ["balanced", None])`

The slice plot shows the "balanced" value but not the `None` value.
I could write a workaround by using `"None"` as a string and then convert it to `None`
but I thing it could be nice if the real `None` is ploted.

See sceenshot:

<img width="234" alt="image" src="https://user-images.githubusercontent.com/229382/199188383-981f256d-0b66-4a1c-be40-68ecd6ae4528.png">


### Environment

- Optuna version:3.0.3
- Python version:3.9.13
- OS:Linux-5.10.0-17-amd64-x86_64-with-glibc2.31

### Error messages, stack traces, or logs

```shell
see screenshot
```


### Steps to reproduce

see description above

### Additional context (optional)

_No response_


Discussion:
Thank you for reporting this but. I can reproduce this bug with the following code.

```python
import optuna


def objective(trial):
    x = trial.suggest_float("x", -100, 100)
    trial.suggest_categorical("y", ["hoge", None])
    return x ** 2


sampler = optuna.samplers.TPESampler(seed=3)
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=2)

fig = optuna.visualization.plot_slice(study)
fig.show()
```

Note that this bug doesn't happen with matplotlib version; it correctly shows `None`.
> Note that this bug doesn't happen with matplotlib version; it correctly shows None.

Then it seems to be a plotly issue only.

Resolving patch:
diff --git a/optuna/visualization/_slice.py b/optuna/visualization/_slice.py
--- a/optuna/visualization/_slice.py
+++ b/optuna/visualization/_slice.py
@@ -195,9 +195,12 @@ def _get_slice_plot(info: _SlicePlotInfo) -> "go.Figure":
 
 
 def _generate_slice_subplot(subplot_info: _SliceSubplotInfo) -> "Scatter":
+    x = [x if x is not None else "None" for x in subplot_info.x]
+    y = [y if y is not None else "None" for y in subplot_info.y]
+
     return go.Scatter(
-        x=subplot_info.x,
-        y=subplot_info.y,
+        x=x,
+        y=y,
         mode="markers",
         marker={
             "line": {"width": 0.5, "color": "Grey"},


Test patch:
Repository: optuna/optuna

Issue:
Constrained single-objective TPE always throws unnecessary warnings when `constant_liar=True`
### Expected behavior

It should not throw warnings.

### Environment

- Optuna version: v3.0.2
- Python version: any
- OS: any
- (Optional) Other libraries and their versions:


### Error messages, stack traces, or logs

```shell
optuna/samplers/_tpe/sampler.py:679: UserWarning: Trial 0 does not have constraint values. It will be treated as a lower priority than other trials.
```


### Steps to reproduce

```python
import optuna


def objective(trial):
    x = trial.suggest_float("x", -1, 1)
    trial.set_user_attr("constraint", (-x,))
    return x


def constraints_func(trial):
    return trial.user_attrs["constraint"]


sampler = optuna.samplers.TPESampler(constraints_func=constraints_func, constant_liar=True)
study = optuna.create_study(sampler=sampler)
study.optimize(objective, n_trials=3)
```


### Additional context (optional)

Reported [here](https://github.com/optuna/optuna/pull/3506#issuecomment-1333389460).
We can skip this warning when the trial is running.
~It seems we can fix this problem by skipping a trial that is the same as the current one. https://github.com/optuna/optuna/blob/2419e616e536e456867c9425e1e8db7af0da0d35/optuna/samplers/_tpe/sampler.py#L652-L657~


Discussion:

Resolving patch:
diff --git a/optuna/samplers/_tpe/sampler.py b/optuna/samplers/_tpe/sampler.py
--- a/optuna/samplers/_tpe/sampler.py
+++ b/optuna/samplers/_tpe/sampler.py
@@ -670,7 +670,7 @@ def _get_observation_pairs(
                 param_value = None
             values[param_name].append(param_value)
 
-        if constraints_enabled:
+        if constraints_enabled and trial.state != TrialState.RUNNING:
             assert violations is not None
             constraint = trial.system_attrs.get(_CONSTRAINTS_KEY)
             if constraint is None:


Test patch:
Repository: optuna/optuna

Issue:
Resolve mypy error on master branch
### Motivation

Due to the recent release of pytorch-lightning, `Checks (Integration)` fails on the master branch 
https://github.com/optuna/optuna/actions/runs/3381750055. 



### Suggestion

[The changelog](https://github.com/Lightning-AI/lightning/blob/e52d6c5b35e5fd42810dca949ee408e2c831047a/src/pytorch_lightning/CHANGELOG.md
) says 

> Renamed `training_type_plugin` file to `strategy` 

So we can replace `training_type_plugin` with `strategy` in the integration file.

### Additional context (optional)

The pytorch-lightning integration is not tested while in optuna https://github.com/optuna/optuna/issues/3418.


Discussion:

Resolving patch:
diff --git a/optuna/integration/pytorch_distributed.py b/optuna/integration/pytorch_distributed.py
--- a/optuna/integration/pytorch_distributed.py
+++ b/optuna/integration/pytorch_distributed.py
@@ -4,7 +4,6 @@
 from typing import Any
 from typing import Callable
 from typing import Dict
-from typing import List
 from typing import Optional
 from typing import overload
 from typing import Sequence
@@ -36,7 +35,7 @@
     "Use :func:`~optuna.integration.TorchDistributedTrial.suggest_float` instead."
 )
 
-_g_pg: List[Optional["ProcessGroup"]] = [None]
+_g_pg: Optional["ProcessGroup"] = None
 
 
 def broadcast_properties(f: "Callable[_P, _T]") -> "Callable[_P, _T]":
@@ -119,11 +118,12 @@ def __init__(
         group: Optional["ProcessGroup"] = None,
     ) -> None:
         _imports.check()
+        global _g_pg
 
         if group is not None:
             self._group: "ProcessGroup" = group
         else:
-            if _g_pg[0] is None:
+            if _g_pg is None:
                 if dist.group.WORLD is None:
                     raise RuntimeError("torch distributed is not initialized.")
                 default_pg: "ProcessGroup" = dist.group.WORLD
@@ -131,10 +131,10 @@ def __init__(
                     new_group: "ProcessGroup" = dist.new_group(  # type: ignore[no-untyped-call]
                         backend="gloo"
                     )
-                    _g_pg[0] = new_group
+                    _g_pg = new_group
                 else:
-                    _g_pg[0] = default_pg
-            self._group = _g_pg[0]
+                    _g_pg = default_pg
+            self._group = _g_pg
 
         if dist.get_rank(self._group) == 0:  # type: ignore[no-untyped-call]
             if not isinstance(trial, optuna.trial.Trial):


Test patch:
Repository: optuna/optuna

Issue:
Remove experimental label from `_ProgressBar`
### Motivation

Several issues related to `_ProgressBar` have been already addressed (ref: https://github.com/optuna/optuna/issues/2892, https://github.com/optuna/optuna/issues/2957, https://github.com/optuna/optuna/issues/2958). Now we can remove the experimental label from `_ProgressBar`.

### Suggestion

Remove the `@experimental_func` decorator from `_ProgressBar`. Also, `_init_valid` method can be removed as explained in [TODO comment](https://github.com/optuna/optuna/blob/806448420863606c113aeb2e33457acf022be066/optuna/progress_bar.py#L57C28-L58).

### Additional context (optional)

_No response_


Discussion:
@knshnb Can I pick up this task?
@tungbq Sure, of course!

Resolving patch:
diff --git a/optuna/progress_bar.py b/optuna/progress_bar.py
--- a/optuna/progress_bar.py
+++ b/optuna/progress_bar.py
@@ -6,7 +6,6 @@
 from tqdm.auto import tqdm
 
 from optuna import logging as optuna_logging
-from optuna._experimental import experimental_func
 
 
 if TYPE_CHECKING:
@@ -52,29 +51,22 @@ def __init__(
         self._last_elapsed_seconds = 0.0
 
         if self._is_valid:
-            self._init_valid()
-
-    # TODO(hvy): Remove initialization indirection via this method when the progress bar is no
-    # longer experimental.
-    @experimental_func("1.2.0", name="Progress bar")
-    def _init_valid(self) -> None:
-        if self._n_trials is not None:
-            self._progress_bar = tqdm(total=self._n_trials)
-
-        elif self._timeout is not None:
-            total = tqdm.format_interval(self._timeout)
-            fmt = "{desc} {percentage:3.0f}%|{bar}| {elapsed}/" + total
-            self._progress_bar = tqdm(total=self._timeout, bar_format=fmt)
-        else:
-            assert False
-
-        global _tqdm_handler
-
-        _tqdm_handler = _TqdmLoggingHandler()
-        _tqdm_handler.setLevel(logging.INFO)
-        _tqdm_handler.setFormatter(optuna_logging.create_default_formatter())
-        optuna_logging.disable_default_handler()
-        optuna_logging._get_library_root_logger().addHandler(_tqdm_handler)
+            if self._n_trials is not None:
+                self._progress_bar = tqdm(total=self._n_trials)
+            elif self._timeout is not None:
+                total = tqdm.format_interval(self._timeout)
+                fmt = "{desc} {percentage:3.0f}%|{bar}| {elapsed}/" + total
+                self._progress_bar = tqdm(total=self._timeout, bar_format=fmt)
+            else:
+                assert False
+
+            global _tqdm_handler
+
+            _tqdm_handler = _TqdmLoggingHandler()
+            _tqdm_handler.setLevel(logging.INFO)
+            _tqdm_handler.setFormatter(optuna_logging.create_default_formatter())
+            optuna_logging.disable_default_handler()
+            optuna_logging._get_library_root_logger().addHandler(_tqdm_handler)
 
     def update(self, elapsed_seconds: float, study: "Study") -> None:
         """Update the progress bars if ``is_valid`` is :obj:`True`.


Test patch:
Repository: optuna/optuna

Issue:
Fix `Test` warnings from `BoTorch`
### Motivation

Resolve following warnings from test:
```
tests/terminator_tests/improvement_tests/gp_tests/test_botorch.py: 4 warnings
tests/visualization_tests/test_terminator_improvement.py: 46 warnings
  /opt/hostedtoolcache/Python/3.9.18/x64/lib/python3.9/site-packages/botorch/fit.py:139: DeprecationWarning:
  
  `fit_gpytorch_model` is marked for deprecation, consider using `fit_gpytorch_mll` instead.
```

### Suggestion

Look for the proper way to fix this warning (Hopefully, just replacing `fit_gpytorch_model` with `fit_gpytorch_mll`).

### Additional context (optional)

_No response_


Discussion:

Resolving patch:
diff --git a/optuna/terminator/improvement/gp/botorch.py b/optuna/terminator/improvement/gp/botorch.py
--- a/optuna/terminator/improvement/gp/botorch.py
+++ b/optuna/terminator/improvement/gp/botorch.py
@@ -3,6 +3,7 @@
 from typing import Optional
 
 import numpy as np
+from packaging import version
 
 from optuna._imports import try_import
 from optuna.distributions import _is_distribution_log
@@ -16,15 +17,20 @@
 
 
 with try_import() as _imports:
-    from botorch.fit import fit_gpytorch_model
+    import botorch
     from botorch.models import SingleTaskGP
     from botorch.models.transforms import Normalize
     from botorch.models.transforms import Standardize
     import gpytorch
     import torch
 
+    if version.parse(botorch.version.version) < version.parse("0.8.0"):
+        from botorch.fit import fit_gpytorch_model as fit_gpytorch_mll
+    else:
+        from botorch.fit import fit_gpytorch_mll
+
 __all__ = [
-    "fit_gpytorch_model",
+    "fit_gpytorch_mll",
     "SingleTaskGP",
     "Normalize",
     "Standardize",
@@ -61,7 +67,7 @@ def fit(
 
         mll = gpytorch.mlls.ExactMarginalLogLikelihood(self._gp.likelihood, self._gp)
 
-        fit_gpytorch_model(mll)
+        fit_gpytorch_mll(mll)
 
     def predict_mean_std(
         self,


Test patch:
Repository: optuna/optuna

Issue:
Better raising an error or making n_below zero for more robust splits
### Motivation

When spliting trials in TPESampler, n_below might be negative value [here](https://github.com/optuna/optuna/blob/master/optuna/samplers/_tpe/sampler.py#L606-L616).
The problem is that `sorted_trials[:n_below]` and `sorted_trials[n_below:]` may exhibit completely unexpected behavior when `n_below < 0`.

### Suggestion

To this end, I suppose that we should raise an error when we get `n_below < 0` during the process [here](https://github.com/optuna/optuna/blob/master/optuna/samplers/_tpe/sampler.py#L606-L616) or we should enforce `n_below >= 0` by using `max(n_below, 0)`.

In my opinion, the second solution is better as I assume that the order of adding trials to `samples_below` is sorted by priority.

It should look like the following after my modification:

```python
below_complete, above_complete = _split_complete_trials(complete_trials, study, n_below)
n_below = max(0, n_below - len(below_complete))
below_pruned, above_pruned = _split_pruned_trials(pruned_trials, study, n_below)
n_below = max(0, n_below - len(below_pruned))
below_infeasible, above_infeasible = _split_infeasible_trials(infeasible_trials, n_below)
```

### Additional context (optional)

_No response_


Discussion:
Can I pick this up ?
@p1kit Yes, please go ahead.
Thanks @HideakiImamura , Can you please assign this to me. Will start working on it . 

Resolving patch:
diff --git a/optuna/samplers/_tpe/sampler.py b/optuna/samplers/_tpe/sampler.py
--- a/optuna/samplers/_tpe/sampler.py
+++ b/optuna/samplers/_tpe/sampler.py
@@ -629,9 +629,11 @@ def _split_trials(
 
     # We divide data into below and above.
     below_complete, above_complete = _split_complete_trials(complete_trials, study, n_below)
-    n_below -= len(below_complete)
+    # This ensures `n_below` is non-negative to prevent unexpected trial splits.
+    n_below = max(0, n_below - len(below_complete))
     below_pruned, above_pruned = _split_pruned_trials(pruned_trials, study, n_below)
-    n_below -= len(below_pruned)
+    # This ensures `n_below` is non-negative to prevent unexpected trial splits.
+    n_below = max(0, n_below - len(below_pruned))
     below_infeasible, above_infeasible = _split_infeasible_trials(infeasible_trials, n_below)
 
     below_trials = below_complete + below_pruned + below_infeasible


Test patch:
Repository: optuna/optuna

Issue:
Clarify `GridSampler` and ask-and-tell interface problem
### What is an issue?

`GridSampler` with ask-and-tell interface does not work the same way as the `optimize` interface due to `RuntimeError` as reported in https://github.com/optuna/optuna/issues/4121 and https://github.com/optuna/optuna/issues/5141. This should be clarified in the GridSampler page, possibly the first note section that sounds related to this problem.


Discussion:

Resolving patch:
diff --git a/optuna/samplers/_grid.py b/optuna/samplers/_grid.py
--- a/optuna/samplers/_grid.py
+++ b/optuna/samplers/_grid.py
@@ -51,9 +51,12 @@ def objective(trial):
 
     Note:
 
-        :class:`~optuna.samplers.GridSampler` automatically stops the optimization if all
-        combinations in the passed ``search_space`` have already been evaluated, internally
-        invoking the :func:`~optuna.study.Study.stop` method.
+        This sampler with :ref:`ask_and_tell` raises :exc:`RuntimeError` just after evaluating
+        the final grid. This is because :class:`~optuna.samplers.GridSampler` automatically
+        stops the optimization if all combinations in the passed ``search_space`` have already
+        been evaluated, internally invoking the :func:`~optuna.study.Study.stop` method.
+        As a workaround, we need to handle the error manually as in
+        https://github.com/optuna/optuna/issues/4121#issuecomment-1305289910.
 
     Note:
 


Test patch:
Repository: optuna/optuna

Issue:
Add documentation for customizing visualization function output
### What is an issue?

Optuna's visualisation functions return editable objects. But it's not well documented. It would be good to have a description in [the visualization tutorial](https://optuna.readthedocs.io/en/stable/tutorial/10_key_features/005_visualization.html). (ref #4613)


Discussion:

Resolving patch:
diff --git a/tutorial/10_key_features/005_visualization.py b/tutorial/10_key_features/005_visualization.py
--- a/tutorial/10_key_features/005_visualization.py
+++ b/tutorial/10_key_features/005_visualization.py
@@ -149,3 +149,18 @@ def objective(trial):
 ###################################################################################################
 # Visualize the optimization timeline of performed trials. See :func:`~optuna.visualization.plot_timeline` for the details.
 plot_timeline(study)
+
+###################################################################################################
+# Customize generated figures
+# ---------------------------
+# In :mod:`optuna.visualization` and :mod:`optuna.visualization.matplotlib`, a function returns an editable figure object:
+# :class:`plotly.graph_objects.Figure` or :class:`matplotlib.axes.Axes` depending on the module.
+# This allows users to modify the generated figure for their demand by using API of the visualization library.
+# The following example replaces figure titles drawn by Plotly-based :func:`~optuna.visualization.plot_intermediate_values` manually.
+fig = plot_intermediate_values(study)
+
+fig.update_layout(
+    title="Hyperparameter optimization for GBDT-based binary classification",
+    xaxis_title="Iteration",
+    yaxis_title="Validation AUC",
+)


Test patch: