本記事では、説明変数間が従属関係にある制約条件下での多目的最適化を実施して、下図のようなパレート解を取得する雛形コードを載せました。

下図はその実施例です。説明変数3つ「PTRATIO」「INDUS」「DIS」の和が固定値25という制約下で乱数により、多目的最適化を実施した結果です。

■本プログラム
from pycaret.regression import *
load_model_y1 = load_model('best_model_PRICE')
load_model_y2 = load_model('best_model_RM')
print(load_model_y1)
print(load_model_y2)
import os
import optuna
import numpy as np
import matplotlib.pyplot as plt
outfile_name = 'history_data'
if os.path.isfile(outfile_name + '.csv'):
os.remove(outfile_name + '.csv')
def objective(trial):
lstat = trial.suggest_float('LSTAT', 1.7, 38)
ptratio = trial.suggest_float('PTRATIO', 12.6, 22)
indus = trial.suggest_float('INDUS', 0.4, 24)
dis = trial.suggest_float('DIS', 1.1, 12)
age = trial.suggest_float('AGE', 3, 100)
chas = trial.suggest_categorical('CHAS', ['0', '1'])
np_list = [ptratio, indus, dis]
param_arr = np.vstack(np_list).T
S = 25
arr = param_arr * S / param_arr.sum(axis=1)[:, np.newaxis]
ptratio, indus, dis = arr[0]
df = pd.DataFrame([(lstat, ptratio, indus, dis, age, chas)],
columns= ['LSTAT', 'PTRATIO', 'INDUS', 'DIS', 'AGE', 'CHAS'])
predict_y1 = predict_model(load_model_y1, data=df).values.tolist()[0][-1]
predict_y2 = predict_model(load_model_y2, data=df).values.tolist()[0][-1]
df['predict_y1'] = predict_y1
df['predict_y2'] = predict_y2
df.to_csv(outfile_name + '.csv', mode='a', index = False, header = False)
return predict_y1, predict_y2
study = optuna.multi_objective.create_study(
directions=["minimize", "maximize"],
sampler=optuna.multi_objective.samplers.NSGAIIMultiObjectiveSampler(seed = 1)
)
study.optimize(objective, n_trials=200)
DF = pd.read_csv(outfile_name + '.csv')
DF.columns = ['LSTAT', 'PTRATIO', 'INDUS', 'DIS', 'AGE', 'CHAS',
'predict_y1', 'predict_y2']
DF.index = np.arange(1, len(DF) + 1)
DF.to_csv(outfile_name + '.csv', mode='w', header=True)
trials = {str(trial.values): trial for trial in study.get_pareto_front_trials()}
trials = list(trials.values())
trials.sort(key=lambda t: t.values)
pareto_no_list = []
for i, trial in enumerate(trials, start=1):
print('pareto -> ', trial.number, trial.values[0], trial.values[1])
pareto_no_list.append(trial.number)
DF_pareto = DF[DF.index.isin(pareto_no_list)]
DF_pareto.to_csv('pareto_data.csv', index = True)
plt.rcParams["font.size"] = 22
plt.figure(figsize=(10, 6))
plt.title("multiobjective optimization")
plt.xlabel("PRICE (predict_y1)")
plt.ylabel("RM (predict_y2)")
plt.grid()
plt.scatter(DF['predict_y1'], DF['predict_y2'], s=100, c='blue', label='all trials')
plt.scatter(DF_pareto['predict_y1'], DF_pareto['predict_y2'], s=100, c='red', label='pareto front')
ax = plt.gca()
x_min, x_max = ax.get_xlim()
ax.set_xlim(0, x_max)
y_min, y_max = ax.get_ylim()
ax.set_ylim(0, y_max)
ax.legend(bbox_to_anchor=(1, 0.95))
plt.tight_layout()
(以下、参考)
回帰モデルの作成手順は、下記を参照下さい。
hk29.hatenablog.jp
Optunaによる多目的最適化の例は、下記を参照下さい。
hk29.hatenablog.jp
以上
<広告>
リンク