質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

900閲覧

defの引数に、def内で定義された関数を格納する方法(Define by Runの関数化)

MagMag

総合スコア80

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/03/27 01:30

編集2020/03/27 01:55

機械学習のハイパパラメータ調整において、Define by RunスタイルのOptunaというライブラリーを使おうと思っています。ただ、このハイパパラメータ調整を一つの操作単位として、パラメータ探索範囲を変えたり、機械学習モデルを変えたりしたく、この操作単位そのものを関数化してfor文で回したいと思っています。

ただ、Defineパートのdefをさらにdefで囲ってしまう方法をとると、実行時、引数に未定義関数が入ってしまってエラーになります。

辞書やDataFrameなりを使って、未定義関数を使わない引数を使ることはできるのですが、(自分の実装力だと)構造がややこしくなるので、シンプルに設計したいのですが、いい方法があれば教えていただけないでしょうか?

Optunaの説明
for文を使わない場合のOptunaの実行例

↓は動きます

# Defineパート def objective(trial): # 探索パラメータの設定。trial.suggestでパラメータの探索範囲を指定 param_grid = { "max_depth": trial.suggest_int("max_depth", 1, 15), "min_samples_leaf": trial.suggest_int("min_samples_leaf", 1, 5), 'bootstrap': trial.suggest_categorical('bootstrap', [True, False]) } # 機械学習手法の指定 model = RandomForestRegressor(**param_grid) scores = cross_validate(model, X=X, y=y, cv=5, scoring={"neg_mean_squared_error"}) # 最適化するのはscore平均値と指定 return scores['test_neg_mean_squared_error'].mean() # Runパート study = optuna.create_study(direction='maximize') study.optimize(objective, n_trials=20)

↓はtrialが定義されていないとエラーが出て動きません。

# 学習全体の関数 def optimization(param_grid): # Defineパート def objective(trial): # 機械学習手法の指定 model = RandomForestRegressor(**param_grid) scores = cross_validate(model, X=X, y=y, cv=5, scoring={"neg_mean_squared_error"}) # 最適化するのはscore平均値と指定 return scores['test_neg_mean_squared_error'].mean() # Runパート study = optuna.create_study(direction='maximize') study.optimize(objective, n_trials=20) # trialが定義されていないとエラーが出る param_grid = { "max_depth": trial.suggest_int("max_depth", 1, 15), "min_samples_leaf": trial.suggest_int("min_samples_leaf", 1, 5), 'bootstrap': trial.suggest_categorical('bootstrap', [True, False]) } optimization(param_grid)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t_obara

2020/03/27 04:15

trialの内容がobjective関数の呼び出し毎に変化するので、それを外だしするためには、どのように変化するのかを把握する必要があります。それについては、ご理解されていますか?理解されているとすると、それをどのように実現する予定なのでしょうか? それらを踏まえ、構造がややこしくなると思われるご自身のコードをご提示されると回答が得られやすくなるかと思います。
MagMag

2020/03/27 05:39 編集

t_obara様 アドバイスありがとうございます。一応理解しているつもりです。 >構造がややこしくなると思われるご自身のコードをご提示されると回答が得られやすくなるかと思います。 まだ、うまく動作していないですが、引数を以下のように定義し、 params = {"init": ["max_depth", 1, 15], "init": ["min_samples_leaf", 1, 5], "categorical": ["bootstrap", True, False]} 関数の中でfor key, value in params.items()でループさせ、keyに"init"があれば、tirail.suggest_init()を通し、"categorical"であれば、trial.suggest_categorical()を通す、といったイメージで考えています。そんなの大変じゃないレベルです、というのであれば、おっしゃる通りかと思います、、、。 ただ、例えば、tiral.suggets_initを例えばそのまま文字列として関数に入れて、関数の中で文字列を解いて関数化する(例えば、"print("Hello")"を引数にして、関数の中でprint("Hello")を実行する)方法があれば、元のparam_gridの構造をそのまま使えて便利だな、と思った次第です。 param_gridが1種類ならいいのですが、これが十種類程度あるので、もとの構造をそのまま使いたいという希望です。
t_obara

2020/03/27 05:48

すでに回答されている通りなのですが、`study.optimize`が実行される際に、`objective`がパラメータ`trial`が変更されながら呼び出されるので、trialの内容との関連をうまく紐付けるようにしないと、同じ処理にならないという懸念です。これらの関係を伝えるようにしないと、回答が得られにくいかと思いました。結局すでに回答されている通りの対処しかできないという回答しか出てこないと思われます。 > (例えば、"print("Hello")"を引数にして、関数の中でprint("Hello")を実行する) これ自体はevalを利用できそうですし、関数自体を変数にすることもできますので、関連性が分かればなんとかなるのかもしれません。(なんともできないかもしれませんが)
MagMag

2020/03/27 06:23

ありがとうございました!素直にDataFrameから作るようにしました。
guest

回答1

0

ベストアンサー

そのライブラリ自体はよくわかっていないのですが、普通に考えるとobjectiveのスコープの中でparam_gridを定義しないと駄目なのでは。

python

1 def objective(trial): 2 # 機械学習手法の指定 3 param_grid = { 4 "max_depth": trial.suggest_int("max_depth", 1, 15), 5 "min_samples_leaf": trial.suggest_int("min_samples_leaf", 1, 5), 6 'bootstrap': trial.suggest_categorical('bootstrap', [True, False]) 7 } 8 9 model = RandomForestRegressor(**param_grid) 10 scores = cross_validate(model, X=X, y=y, cv=5, scoring={"neg_mean_squared_error"}) 11 12 # 最適化するのはscore平均値と指定 13 return scores['test_neg_mean_squared_error'].mean() 14 15

投稿2020/03/27 05:21

hayataka2049

総合スコア30935

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MagMag

2020/03/27 06:24

やはりそうですよね。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問