2012-11-13 5 views
14

मेरे पास एक ऐसा फ़ंक्शन है जिसमें पैरामीटर का एक गुच्छा है। मैन्युअल रूप से सभी पैरामीटर सेट करने की बजाय, मैं एक ग्रिड खोज करना चाहता हूं। मेरे पास प्रत्येक पैरामीटर के लिए संभावित मानों की एक सूची है। पैरामीटर के हर संभव संयोजन के लिए, मैं अपना फ़ंक्शन चलाने के लिए चाहता हूं जो उन पैरामीटर पर मेरे एल्गोरिदम के प्रदर्शन की रिपोर्ट करता है। मैं इसके परिणाम को कई आयामी मैट्रिक्स में संग्रहीत करना चाहता हूं, ताकि बाद में मैं अधिकतम प्रदर्शन की अनुक्रमणिका पा सकूं, जो बदले में मुझे सर्वोत्तम पैरामीटर दे।पायथन/numpy में सुरुचिपूर्ण ग्रिड खोज

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! 

मैं पहले भाग है, जहां मैं सूचियां निर्धारित, के रूप में-है के बाद से मैं आसानी से मान जिस पर मैं खोज में हेरफेर करने में सक्षम होना चाहते रखना चाहते हैं: यहां बताया गया कोड अब लिखा जाता है।

मैं भी परिणाम मैट्रिक्स के साथ समाप्त करना चाहता हूं, क्योंकि मैं कल्पना कर रहा हूं कि अलग-अलग पैरामीटर कैसे बदलते हैं एल्गोरिदम के प्रदर्शन को प्रभावित करते हैं।

मध्य में थोड़ा, हालांकि, काफी दोहराव और भारी है (विशेष रूप से क्योंकि मेरे पास बहुत सारे पैरामीटर हैं, और मैं पैरामीटर जोड़ना या निकालना चाहता हूं), और मुझे लगता है कि एक और संक्षिप्त/सुरुचिपूर्ण तरीका होना चाहिए परिणाम मैट्रिक्स को आरंभ करने के लिए, सभी सूचकांक पर पुनरावृत्त करें, और उचित पैरामीटर सेट करें।

तो, क्या वहां है?

+2

ऐसा लगता है कि आप 'itertools.product' –

+0

अहह, वास्तव में देख रहे हैं! यह चीजों को थोड़ा सा सरल बना देगा! – dlants

+0

इसलिए अनिवार्य रूप से, यहां एक डुप्लिकेट है: http://stackoverflow.com/questions/1316068/pythonic-way-of-iterating-over-3d-array –

उत्तर

8

मुझे लगता है कि 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 है, मूल्यांकन ग्रिड लौटा दी जाएगी।

+0

मैंने थोड़ा ऊपर की स्थिति को सरल बना दिया। मैं वास्तव में आउटपुट (कई मूल्यांकन कार्यों) के रूप में कई मानों की रिपोर्ट कर रहा हूं, इसलिए मेरी परिणाम पंक्ति परिणाम [p1idx, p2idx, ...,:,:,:] = आउटपुट मानों के 3 डी मैट्रिक्स है। मुझे नहीं लगता कि मैं इस वजह से ब्रूटफोर्स की खोज का उपयोग कर सकता हूं। आपका समाधान ऊपर पोस्ट की गई समस्या के लिए सख्ती से सही है, लेकिन मैं मौजूदा ग्रिडसेर्च फ़ंक्शन का उपयोग किए बिना परिणाम मैट्रिक्स बनाने के लिए उस कोड को सरल बनाने के तरीकों की तलाश में हूं। – dlants

+0

क्या यह मामला है कि आप कई स्केलर आउटपुट में से एक के लिए सर्वश्रेष्ठ इनपुट पैरामीटर ढूंढने का प्रयास कर रहे हैं, उदाहरण के लिए, "मुझे इनपुट कम करें [i]" इनपुट दें, या आपके पास "भलाई" का मूल्यांकन करने का कोई तरीका है सभी परिणामों में से एक बार, योग, या एल 1 या एल 2 मानदंड की तरह? –

+1

मूल्य विभिन्न वस्तुओं के लिए सटीकता, सटीकता और याद हैं। मैं प्रत्येक ऑब्जेक्ट श्रेणी, और ऑब्जेक्ट्स के भीतर सटीकता का सख्त मिनट लेगा, और परिशुद्धता को जोड़ता हूं और विभिन्न तरीकों से उपायों को याद करता हूं। – dlants

6

John Vinyard का समाधान सही लगता है; लेकिन यदि आप अधिक लचीलापन की तलाश में हैं, तो आप प्रसारण + vectorize का उपयोग कर सकते हैं। mean_grid के लिए

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 
निम्न परिणाम के साथ

: ix_ का प्रयोग मानकों का एक broadcastable सेट का उत्पादन करने, और फिर समारोह के एक vectorized संस्करण के लिए उन पारित (लेकिन चेतावनी नीचे देखें)

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 आसान है, लेकिन यह इसे पारित समारोह की गति से सीमित है, और पायथन फ़ंक्शन धीमे हैं। यदि आप का उपयोग करने के लिए my_func को फिर से लिख सकते हैं, तो यदि आप परवाह करते हैं तो आप अपने ग्रिड को तेज़ी से प्राप्त कर सकते हैं।कुछ इस तरह:

>>> 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.  ]]]) 
7

आप sklearn मॉड्यूल से ParameterGrid उपयोग कर सकते हैं

http://scikit-learn.org/stable/modules/generated/sklearn.grid_search.ParameterGrid.html

उदाहरण

from sklearn.grid_search import ParameterGrid 
param_grid = {'param1': [value1, value2, value3], 'paramN' : [value1, value2, valueM]} 

grid = ParameterGrid(param_grid) 

for params in grid: 
    your_function(params['param1'], params['param2']) 
+0

मॉड्यूल का नया संस्करण: 'sklearn.model_selection आयात पैरामीटर ग्रिड से' – Abramodj

1

आप numpy meshgrid इस के लिए उपयोग कर सकते हैं:

import numpy as np 

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

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

ध्यान दें कि आपका कार्य numpy.array एस के साथ काम करने में सक्षम होना चाहिए।