やりたいこと
研究開発におけるパラメタの探索や、API化を見据えたPython上でのアルゴリズム開発において、
以下のような実験用パラメタの管理を考えます。
config = {
"param_0": [0.01, 0.1, 1.0],
"param_1": ["l1", "l2"],
"param_2": [0, 10, 20, 30]
}
params_ex = {
"param_0": 0.01.
"param_1": "l1",
"param_2": 0
}
params
の各要素の組み合わせでparams_ex
のような実験条件を表す辞書オブジェクトを全通り生成します。
もし要素数が決まっていれば、以下のようにハードコーディングできます。
params_list = []
for p2 in config["param_2"]:
for p1 in config["param_1"]:
for p0 in config["param_0"]:
params = {
"param_0": p0,
"param_1": p1,
"param_2": p2
}
params_list.append(params)
>python gen_paramslist.py
[{'param_0': 0.01, 'param_1': 'l1', 'param_2': 0},
{'param_0': 0.1, 'param_1': 'l1', 'param_2': 0},
{'param_0': 1.0, 'param_1': 'l1', 'param_2': 0},
{'param_0': 0.01, 'param_1': 'l2', 'param_2': 0},
{'param_0': 0.1, 'param_1': 'l2', 'param_2': 0},
{'param_0': 1.0, 'param_1': 'l2', 'param_2': 0},
{'param_0': 0.01, 'param_1': 'l1', 'param_2': 10},
{'param_0': 0.1, 'param_1': 'l1', 'param_2': 10},
{'param_0': 1.0, 'param_1': 'l1', 'param_2': 10},
{'param_0': 0.01, 'param_1': 'l2', 'param_2': 10},
{'param_0': 0.1, 'param_1': 'l2', 'param_2': 10},
{'param_0': 1.0, 'param_1': 'l2', 'param_2': 10},
{'param_0': 0.01, 'param_1': 'l1', 'param_2': 20},
{'param_0': 0.1, 'param_1': 'l1', 'param_2': 20},
{'param_0': 1.0, 'param_1': 'l1', 'param_2': 20},
{'param_0': 0.01, 'param_1': 'l2', 'param_2': 20},
{'param_0': 0.1, 'param_1': 'l2', 'param_2': 20},
{'param_0': 1.0, 'param_1': 'l2', 'param_2': 20},
{'param_0': 0.01, 'param_1': 'l1', 'param_2': 30},
{'param_0': 0.1, 'param_1': 'l1', 'param_2': 30},
{'param_0': 1.0, 'param_1': 'l1', 'param_2': 30},
{'param_0': 0.01, 'param_1': 'l2', 'param_2': 30},
{'param_0': 0.1, 'param_1': 'l2', 'param_2': 30},
{'param_0': 1.0, 'param_1': 'l2', 'param_2': 30}]
しかし、開発中にパラメタを追加することを考えると現実的ではありません。
検討内容:要素の多分木構造で表現・生成
表現方法
実験条件を以下のような多分木で考えると、全ての経路をたどることで
全ての実験条件を生成することができます。

実装
params_list = [{}]
for p_key, p_values in config.items():
tmp = []
for v in p_values:
for pl in params_list:
tmp.append( dict({p_key: v}, **pl) )
params_list = tmp
もう少しまとめると、
def make_recipe(config, params_list = [{}]):
for p_key, p_values in config.items():
params_list = [dict({p_key: v}, **pl) for v in p_values for pl in params_list]
return params_list
まとめ
とりあえず、全ての実験条件を辞書オブジェクトとして生成しリストへ格納できました。
しかし、パラメタ数・範囲が非常に大きい場合にはリソースの無駄遣いになってしまいます。
理想としては、多分木データ構造に格納し、実験時もその多分木オブジェクトを探索して様々な実験条件を評価するのがよいと思いました。