31

たくさんのパラメーターを持つ関数があります。すべてのパラメーターを手動で設定するのではなく、グリッド検索を実行したいと考えています。各パラメーターの可能な値のリストがあります。パラメータのすべての可能な組み合わせについて、それらのパラメータでのアルゴリズムのパフォーマンスを報告する関数を実行したいと考えています。この結果を多次元マトリックスに保存したいので、あとがきで最大パフォーマンスのインデックスを見つけることができます。これにより、最適なパラメーターが得られます。コードの記述方法は次のとおりです。

param1_list = [p11, p12, p13,...]
param2_list = [p21, p22, p23,...] # not necessarily the same number of values
...

results_size = (len(param1_list), len(param2_list),...)
results = np.zeros(results_size, dtype = np.float)

for param1_idx in range(len(param1_list)):
  for param2_idx in range(len(param2_list)):
    ...
    param1 = param1_list[param1_idx]
    param2 = param2_list[param2_idx]
    ...
    results[param1_idx, param2_idx, ...] = my_func(param1, param2, ...)

max_index = np.argmax(results) # indices of best parameters!

検索する値を簡単に操作できるようにしたいので、リストを定義する最初の部分をそのままにしておきたいと思います。

また、さまざまなパラメーターの変更がアルゴリズムのパフォーマンスにどのように影響するかを視覚化するため、結果マトリックスをそのままにしたいと思います。

ただし、中間のビットは非常に反復的でかさばります (特に、多くのパラメーターがあり、パラメーターを追加または削除したい場合があるため)、結果を初期化するためのより簡潔でエレガントな方法が必要だと思います。マトリックス、すべてのインデックスを反復処理し、適切なパラメーターを設定します。

それで、ありますか?

4

4 に答える 4

11

scipy.optimize.bruteはあなたが求めているものだと思います。

>>> from scipy.optimize import brute
>>> a,f,g,j = brute(my_func,[param1_list,param2_list,...],full_output = True)

full_output引数がの場合True、評価グリッドが返されることに注意してください。

于 2012-11-13T23:33:07.030 に答える
10

John VinyardSibelius Seraphiniのソリューションは組み込みの優れたオプションですが、より柔軟性を求める場合は、ブロードキャスト + を使用できますvectorize。ブロードキャスト可能なパラメーターのセットを生成するために使用ix_し、それらを関数のベクトル化されたバージョンに渡します (ただし、以下の警告を参照してください)。

a, b, c = range(3), range(3), range(3)
def my_func(x, y, z):
    return (x + y + z) / 3.0, x * y * z, max(x, y, z)

grids = numpy.vectorize(my_func)(*numpy.ix_(a, b, c))
mean_grid, product_grid, max_grid = grids

の結果は次のとおりですmean_grid

array([[[ 0.        ,  0.33333333,  0.66666667],
        [ 0.33333333,  0.66666667,  1.        ],
        [ 0.66666667,  1.        ,  1.33333333]],

       [[ 0.33333333,  0.66666667,  1.        ],
        [ 0.66666667,  1.        ,  1.33333333],
        [ 1.        ,  1.33333333,  1.66666667]],

       [[ 0.66666667,  1.        ,  1.33333333],
        [ 1.        ,  1.33333333,  1.66666667],
        [ 1.33333333,  1.66666667,  2.        ]]])

product grid:

array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]],

       [[0, 0, 0],
        [0, 1, 2],
        [0, 2, 4]],

       [[0, 0, 0],
        [0, 2, 4],
        [0, 4, 8]]])

max grid:

array([[[0, 1, 2],
        [1, 1, 2],
        [2, 2, 2]],

       [[1, 1, 2],
        [1, 1, 2],
        [2, 2, 2]],

       [[2, 2, 2],
        [2, 2, 2],
        [2, 2, 2]]])

これは最速のアプローチではない可能性があることに注意してください。vectorize便利ですが、渡される関数の速度によって制限され、python 関数は遅いです。my_funcnumpy ufuncsを使用するように書き直すことができれば、グリッドをより速く取得できます。このようなもの:

>>> def mean(a, b, c):
...     return (a + b + c) / 3.0
... 
>>> mean(*numpy.ix_(a, b, c))
array([[[ 0.        ,  0.33333333,  0.66666667],
        [ 0.33333333,  0.66666667,  1.        ],
        [ 0.66666667,  1.        ,  1.33333333]],

       [[ 0.33333333,  0.66666667,  1.        ],
        [ 0.66666667,  1.        ,  1.33333333],
        [ 1.        ,  1.33333333,  1.66666667]],

       [[ 0.66666667,  1.        ,  1.33333333],
        [ 1.        ,  1.33333333,  1.66666667],
        [ 1.33333333,  1.66666667,  2.        ]]])
于 2012-11-14T01:48:03.940 に答える
1

meshgridこれには numpy を使用できます。

import numpy as np

x = range(1, 5)
y = range(10)

xx, yy = np.meshgrid(x, y)
results = my_func(xx, yy)

関数は s で動作できる必要があることに注意してくださいnumpy.array

于 2015-01-22T15:31:15.787 に答える