How to suggest multivariate of ratio (with bound) in Optuna?

Question:

I would like to suggest ratios in Optuna.

The ratios are X_1, X_2, ..., X_k, bounded by ∑X_i = 1 and 0 <= X_i <= 1 for all i.

Optuna does not provide a Dirichlet distribution.

I have tried the following code, but it does not work.

def objective(trial):
    k = 10
    ratios = np.zeros(k)
    
    residual = 1
    for i in range(k - 1):
        ratios[i] = trial.suggest_float(f'ratio_{i}', 0, residual)
        residual -= ratios[i]
        
#     ratios[k - 1] = trial.suggest_float(f'ratio_{k - 1}', residual, residual)
    ratios[k - 1] = residual
    return np.log(ratios).sum()

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=20)

Then I tried the following code and it terminated without any errors. However, it is suggested k times, even though the degree of freedom is k - 1, which is inconsistent.

def objective(trial):
    k = 10
    ratios = np.zeros(k)
    
    for i in range(k):
        ratios[i] = trial.suggest_float(f'ratio_{i}', 0, 1)
    
    ratios /= ratios.sum()
    return np.log(ratios).sum()

study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=20)

How can I suggest a ratio or bounded by multiple variables?

This is a simple example and is differentiable, but I want to deal with a more complex objective function and need variables for that.

Asked By: Azriel 1rf

||

Answers:

This worked.

class Objective:
    def __init__(self):
        self.max = 1
    def __call__(self, trial):
        k = 10
        ratios = np.zeros(k)

        for i in range(k):
            ratios[i] = trial.suggest_float(f'ratio_{i}', 0, self.max)

        ratios /= ratios.sum()
        self.max = (self.max + ratios.max()) / 2
        return np.log(ratios).sum()

study = optuna.create_study(direction='maximize')
study.optimize(Objective(), n_trials=100)
Answered By: Azriel 1rf