2012-03-26 13 views
21

मैं scipy/numpy के भीतर एक अनुकूलन दिनचर्या की तलाश कर रहा हूं जो एक गैर-रैखिक कम-वर्ग प्रकार की समस्या को हल कर सकता है (उदाहरण के लिए, एक बड़े डेटासेट में पैरामीट्रिक फ़ंक्शन को फ़िट करना) लेकिन सीमाएं और बाधाओं (उदाहरण के लिए पैरामीटर के लिए न्यूनतम और maxima अनुकूलित)। फिलहाल मैं mpfit के पाइथन संस्करण का उपयोग कर रहा हूं (idl से अनुवादित ...): यह स्पष्ट रूप से इष्टतम नहीं है हालांकि यह बहुत अच्छी तरह से काम करता है।scipy.optimize.leastsq बाध्य बाधाओं के साथ

पायथन/एससीपी/आदि में एक कुशल दिनचर्या बहुत अच्छा हो सकता है! कोई इनपुट यहां बहुत स्वागत है :-)

धन्यवाद!

उत्तर

9

scipy scipy.optimize में कई constrained optimization routines है। कम से कम वर्ग संस्करण scipy.optimize.fmin_slsqp

+0

धन्यवाद! मेरी समस्या के लिए आने वाले दिनों में इस बनाम mpfit का परीक्षण करेगा और Asap की रिपोर्ट करेगा! – user1293231

+0

बस slsqp की कोशिश की। मैं इसे ठीक से उपयोग नहीं कर सकता लेकिन मूल रूप से यह बहुत अच्छा नहीं करता है। बहुत कम ईपीएसलॉन मानों का उपयोग करते समय यह क्रैश प्रतीत होता है। और अन्यथा मेरे इनपुट पैरामीटर में कुछ भी (या लगभग) नहीं बदलता है। मैं कुछ डीबगिंग करूँगा, लेकिन ऐसा लगता है कि इसका उपयोग करना इतना आसान नहीं है (अब तक)। आगे की कोशिश करेंगे। – user1293231

+0

असल में मुझे बस निम्न त्रुटि ==> लाइनशर्च के लिए सकारात्मक दिशात्मक व्युत्पन्न प्राप्त होता है (निकास मोड 8)। यही कारण है कि मैं कहीं भी नहीं मिल रहा हूं .... बहुत उपयोगी नहीं। कोई संकेत? – user1293231

20

scipy.optimize.least_squares scipy 0.17 (जनवरी 2016) हैंडल सीमाओं में है; इसका उपयोग करें, यह हैक नहीं।


बाउंड की कमी को आसानी से द्विघात बनाया जा सकता है और बाकी के साथ leastsq द्वारा कम से कम।
आप 10 वर्गों Σ f_i (पी)^2 की राशि कम करना चाहते हैं कहो, तो अपने समारोह (पी) एक 10 वेक्टर [f0 (पी) ... F9 (पी)],
और भी है 0 पैरामीटर के लिए 0 < = p_i < = 1 चाहते हैं।
"टब फ़ंक्शन" अधिकतम (- पी, 0, पी -1), पर विचार करें जो 0 के अंदर 0 है .. 1 और बाहर सकारात्मक, \ \_____/टब की तरह।
अगर हम leastsq 13-लंबे वेक्टर

[ f0(p), f1(p), ... f9(p), w*tub(p0), w*tub(p1), w*tub(p2) ] 
w के साथ

= 100 कहना देते हैं, यह बहुत कुछ के वर्गों का योग कम कर देंगे: टब विवश होगा 0 < = पी < = 1. जनरल लो < = पी < = हाय समान है।
निम्नलिखित कोड सिर्फ एक रैपर है जो leastsq चलाता है उदा। कम करने के लिए इस तरह के 13-लंबे वेक्टर।

# leastsq_bounds.py 
# see also test_leastsq_bounds.py on gist.github.com/denis-bz 

from __future__ import division 
import numpy as np 
from scipy.optimize import leastsq 

__version__ = "2015-01-10 jan denis" # orig 2012 


#............................................................................... 
def leastsq_bounds(func, x0, bounds, boundsweight=10, **kwargs): 
    """ leastsq with bound conatraints lo <= p <= hi 
    run leastsq with additional constraints to minimize the sum of squares of 
     [func(p) ...] 
     + boundsweight * [max(lo_i - p_i, 0, p_i - hi_i) ...] 

    Parameters 
    ---------- 
    func() : a list of function of parameters `p`, [err0 err1 ...] 
    bounds : an n x 2 list or array `[[lo_0,hi_0], [lo_1, hi_1] ...]`. 
     Use e.g. [0, inf]; do not use NaNs. 
     A bound e.g. [2,2] pins that x_j == 2. 
    boundsweight : weights the bounds constraints 
    kwargs : keyword args passed on to leastsq 

    Returns 
    ------- 
    exactly as for leastsq, 
http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.leastsq.html 

    Notes 
    ----- 
    The bounds may not be met if boundsweight is too small; 
    check that with e.g. check_bounds(p, bounds) below. 

    To access `x` in `func(p)`, `def func(p, x=xouter)` 
    or make it global, or `self.x` in a class. 

    There are quite a few methods for box constraints; 
    you'll maybe sing a longer song ... 
    Comments are welcome, test cases most welcome. 

""" 
    # Example: test_leastsq_bounds.py 

    if bounds is not None and boundsweight > 0: 
     check_bounds(x0, bounds) 
     if "args" in kwargs: # 8jan 2015 
      args = kwargs["args"] 
      del kwargs["args"] 
     else: 
      args =() 
#............................................................................... 
     funcbox = lambda p: \ 
      np.hstack((func(p, *args), 
         _inbox(p, bounds, boundsweight))) 
    else: 
     funcbox = func 
    return leastsq(funcbox, x0, **kwargs) 


def _inbox(X, box, weight=1): 
    """ -> [tub(Xj, loj, hij) ... ] 
     all 0 <=> X in box, lo <= X <= hi 
    """ 
    assert len(X) == len(box), \ 
     "len X %d != len box %d" % (len(X), len(box)) 
    return weight * np.array([ 
     np.fmax(lo - x, 0) + np.fmax(0, x - hi) 
      for x, (lo,hi) in zip(X, box)]) 

# def tub(x, lo, hi): 
#  """ \___/ down to lo, 0 lo .. hi, up from hi """ 
#  return np.fmax(lo - x, 0) + np.fmax(0, x - hi) 

#............................................................................... 
def check_bounds(X, box): 
    """ print Xj not in box, loj <= Xj <= hij 
     return nr not in 
    """ 
    nX, nbox = len(X), len(box) 
    assert nX == nbox, \ 
     "len X %d != len box %d" % (nX, nbox) 
    nnotin = 0 
    for j, x, (lo,hi) in zip(range(nX), X, box): 
     if not (lo <= x <= hi): 
      print "check_bounds: x[%d] %g is not in box %g .. %g" % (j, x, lo, hi) 
      nnotin += 1 
    return nnotin 
+0

मुझे यह त्रुटि मिली है जब मैंने इसे कार्यान्वित करने का प्रयास किया है (पायथन 2.7): 'फ़ाइल "[...]/leastsq_bounds.py", लाइन 49, leastsq_bounds वापसी leastsq (funcbox, x0, ** kwargs) फ़ाइल "[...]/minpack.py", लाइन 36 9, leastsq आकार, dtype = _check_func ('leastsq', 'func', func, x0, args, n) फ़ाइल "[... ] /minpack.py ", लाइन 20, _check_func res = atleast_1d (thefunc (* ((x0 [: numinputs],) + args)) टाइप एरर: () बिल्कुल 1 तर्क (5 दिया गया)' –

+1

लेता है @f_ficarola, क्षमा करें, args = छोटी गाड़ी थी; कृपया कट/पेस्ट करें और इसे फिर से प्रयास करें – denis

+0

त्वरित उत्तर, डेनिस के लिए धन्यवाद। हालांकि, इस बीच, मुझे यह मिला है: 'scipy.optimize.minimize (अवशेष मॉडल, x0, args = (arg1, arg2, ...), विधि = 'SLSQP', सीमाएं = [(xmin, xmax)]) '। क्या आपके कोड में कोई अंतर है? –

3

पर एक नज़र डालें: http://lmfit.github.io/lmfit-py/, यह आपकी समस्या का समाधान करना चाहिए।

+0

टिप के लिए धन्यवाद: एक मुद्दा यह है कि मैं एक संगत पायथन मॉड्यूल प्राप्त करने में सक्षम होना चाहता हूं जिसमें बाध्य गैर-लिन कम-वर्ग भाग शामिल है। इसका मतलब है कि उपयोगकर्ता को भी lmfit इंस्टॉल करना होगा या मैं अपने मॉड्यूल में पूरा पैकेज शामिल करना होगा। इस प्रकार मैं पहले fmin_slsqp कोशिश करूँगा क्योंकि यह पहले से ही एक एकीकृत कार्य है।लेकिन lmfit बिल्कुल वही करना प्रतीत होता है जो मुझे चाहिए! – user1293231

+0

मान लें कि आप पहले से ही साइपी पर भरोसा करते हैं, जो मानक पुस्तकालय में नहीं है। lmfit pypi पर है और अधिकांश उपयोगकर्ताओं के लिए स्थापित करना आसान होना चाहिए। – chthonicdaemon

+0

लिंक टूटा हुआ है! – denfromufa

4

एमपीपी के रूप में इष्टतम तरीके से, सीमाओं के साथ nonlinear कम से कम वर्ग समस्या को हल करने की क्षमता, Scipy से लंबे समय से गायब है।

इस कार्यवाही की कार्यक्षमता अंततः Scipy 0.17 में नई फ़ंक्शन scipy.optimize.least_squares के साथ पेश की गई थी।

यह नया फ़ंक्शन बाध्य बाधाओं से निपटने के लिए उचित ट्रस्ट क्षेत्र एल्गोरिदम का उपयोग कर सकता है, और अनुकूलित करने के लिए nonlinear फ़ंक्शन की समतुल्य-वर्ग की प्रकृति का इष्टतम उपयोग करता है।

नोट्स:

समाधान @denis द्वारा प्रस्तावित एक असंतत "टब समारोह" शुरू करने की बड़ी समस्या है। यह scipy.optimize.leastsq ऑप्टिमाइज़ेशन प्रस्तुत करता है, जो सीमा पार होने पर चिकनी फ़ंक्शंस, बहुत अक्षम, और संभवतः अस्थिर के लिए डिज़ाइन किया गया है।

method='SLSQP' साथ scipy.optimize.minimize के उपयोग (के रूप में @f_ficarola सुझाव) या scipy.optimize.fmin_slsqp (के रूप में @matt सुझाव दिया),-के-योग वर्ग समारोह की प्रकृति का इस्तेमाल कर रही नहीं की बड़ी समस्या को कम से कम किया जाना है। इन कार्यों को स्केलर फ़ंक्शंस को कम करने के लिए डिज़ाइन किया गया है (भ्रामक नाम के बावजूद fmin_slsqp के लिए भी सत्य)। ये दृष्टिकोण कम कुशल और कम सटीक से कम सटीक हो सकते हैं।

संबंधित मुद्दे