Optunaインテグレーションによる材料配合最適化
Created on December 17|Last edited on December 18
Comment
1. テーマ概要2. 実行手順2-1. 予測モデルの作成2-1-1. 必要なモジュールのimportとデータセットの準備2-1-2. 学習の実行2-1-3. 精度評価2-2. 最適化/の実行2-2-1. 必要なライブラリのImport2-2-2. アーティファクトに保存していた予測モデルをロード2-2-3. 最適化の探索対象パラメータ・固定パラメータを設定2-2-4. 最適化の実行3. まとめ
1. テーマ概要
マテリアルズ・インフォマティクスの分野では、機械学習モデルによる物性予測とベイズ最適化などの最適化ソルバーの組み合わせにより、新素材開発などの用途で最適な配合提案を行うといった手法が知られています。
今回、UC Irvine Machine Learning Repositoryで公開されているコンクリートの圧縮強度予測用のデータセット(https://archive.ics.uci.edu/dataset/165/concrete+compressive+strength)を用いて、コンクリートの圧縮強度を最大化するための材料配合最適化のデモを行います。
最適化ソルバーとしてOptunaを利用しつつ、OptunaのW&Bインテグレーション機能を利用することで、最適化の進捗状況や最適化結果の可視化を行います。
2. 実行手順
2-1. 予測モデルの作成
何はともあれ予測モデルを作成します。
今回のデモでは特にモデルの部分はこだわらず(実際の業務ではここが最も肝心ですが)、簡単な線形モデルで学習します。
2-1-1. 必要なモジュールのimportとデータセットの準備
import pandas as pdfrom sklearn.preprocessing import StandardScalerfrom sklearn.pipeline import Pipelinefrom sklearn.model_selection import train_test_splitfrom sklearn import linear_modelfrom sklearn.metrics import mean_absolute_error, mean_squared_error, r2_scoreimport wandbfrom joblib import dumpwb_project_name = "concrete-strength-optimization-demo"run = wandb.init(project=wb_project_name)df_train = pd.read_excel("dataset/Concrete_Data.xls")X = df_train.iloc[:, :-1]y = df_train.iloc[:, -1]X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)# 学習データをW&Bのテーブルとして登録しますrun.log({"training_data": wandb.Table(dataframe=pd.concat([X_train, y_train], axis=1).sort_index())})
Run set
1
2-1-2. 学習の実行
リッジ回帰でモデルを作り、後続の最適化時に使用するためアーティファクトでモデルを保存しておきます。
# 学習実行model = Pipeline([('scaler', StandardScaler()), ('ridge', linear_model.Ridge(alpha=0.0))]).fit(X_train, y_train)# モデル出力model_file_path = 'model.joblib'dump(pipe, model_file_path)# モデルをArtifactに保存model_artifact = wandb.Artifact("ridge", type="model",description="Simple Ridge with StandardScaler",metadata=dict(wandb.config))model_artifact.add_file(model_file_path)run.log_artifact(model_artifact)
2-1-3. 精度評価
精度評価結果をログし、使用した検定データをテーブルで保存しておきます。
精度はR2で0.62と高くは無いですが、一旦こちらで進めます。
# 予測実行・精度評価y_test_pred = pipe.predict(X_test)run.log({"RMSE": mean_squared_error(y_test, y_test_pred, squared=False),"MAE": mean_absolute_error(y_test, y_test_pred),"R2": r2_score(y_test, y_test_pred),})# 検定データをW&Bのテーブルで保存df_valid = pd.concat([X_test, y_test, pd.Series(y_test_pred, name="pred", index=X_test.index)], axis=1).sort_index()run.log({"valid_data": wandb.Table(dataframe=df_valid)})
Run set
1
2-2. 最適化/の実行
続いてOptunaを利用した配合最適化を実行します。
OptunaのWandBインテグレーションの機能として、WeightsAndBiasesCallbackを利用します。
2-2-1. 必要なライブラリのImport
from joblib import loadfrom pathlib import Pathimport pandas as pdimport plotly.express as pximport wandbimport optunafrom optuna.integration.wandb import WeightsAndBiasesCallback
2-2-2. アーティファクトに保存していた予測モデルをロード
wb_project_name = "concrete-strength-optimization-demo"def load_model():with wandb.init(project=wb_project_name) as run:artifact = run.use_artifact("ridge:latest", type="model")artifact_dir = artifact.download()return load(Path(artifact_dir) / "model.joblib")model = load_model()
2-2-3. 最適化の探索対象パラメータ・固定パラメータを設定
今回は、最適化の条件として Age(day) を 60 で固定し、その他の材料組成を探索対象とします。
探索の範囲(最大・最小)はlimits変数に格納しておきます。
# 学習データを読み込むdf_train = pd.read_excel("dataset/Concrete_Data.xls")# 学習データの各変数の最大値・最小値の辞書limits = {col: [df_train.min()[col], df_train.max()[col]] for col in df_train.columns}# 目的変数target = 'Concrete compressive strength(MPa, megapascals) '# 目的変数を除く特徴量のリストfeatures = list(df_train.drop(columns=[target]).columns)# 固定パラメータの辞書(今回は'Age (day)'を60で固定)fixed_features = {'Age (day)': 60}# 探索対象パラメータ名のリストcontrol_features = [col for col in features if col not in fixed_features]
2-2-4. 最適化の実行
multirunモードをOn(as_multirun=True)として100イテレーション計算を回します(n_trials=100)。
圧縮強度を最大化するため、評価関数(objectiveの戻り値)は予測結果の符号反転値としています。
def suggest(trial, col):if col in control_features:return trial.suggest_float(col, limits[col][0], limits[col][1])return fixed_features[col]def optimize():wandb_kwargs = {"project": wb_project_name}wandbc = WeightsAndBiasesCallback(wandb_kwargs=wandb_kwargs, as_multirun=True)@wandbc.track_in_wandb()def objective(trial):df_suggest = pd.DataFrame({col: [suggest(trial, col)] for col in features})return - model.predict(df_suggest)study = optuna.create_study()study.optimize(objective, n_trials=100, callbacks=[wandbc])optimize()
multirunモードがOnの場合、計算のイテレーション(Trial)毎にW&Bのrunが生成され、W&Bのダッシュボード上でrun毎の結果をインタラクティブに比較できる事がわかります。
上図:横軸=イテレーション、縦軸=スコア で表示した散布図。52イテレーション目で最適値(-131.212)となった事がわかる
下図:各イテレーションで提案された配合組成の組み合わせを平行軸座標プロットで表示したもの。
Run set
107
3. まとめ
今回はコンクリートの材料配合最適化をテーマに、W&BとOptunaを使った逆問題解析についてご紹介しました。
一般的なW&Bの用途とは少し毛色の異なるテーマではありますが、ログするデータを工夫することで様々な用途にW&Bを利用できるという事がわかりますよね。こちらの記事をご覧になった皆様もぜひご自身のテーマに照らし合わせて応用先を考えていただければ幸いです。
それでは皆様良いクリスマスをお過ごしください!
Add a comment