scipy

2013-07-25 15 views
8

में अलग परिवर्तनीय मानों के साथ फ़ंक्शन को कम करने के लिए कैसे करें मैं एक लक्ष्य फ़ंक्शन को अनुकूलित करने का प्रयास कर रहा हूं जिसमें एकाधिक इनपुट चर (24 और 30 के बीच) हैं। ये चर तीन अलग-अलग सांख्यिकीय चर के नमूने हैं, और लक्ष्य फ़ंक्शन मान टी-टेस्ट संभाव्यता मान हैं। एक त्रुटि फ़ंक्शन वांछित और वास्तविक टी-टेस्ट संभावनाओं के बीच त्रुटि (अंतर के वर्गों का योग) का प्रतिनिधित्व करता है। मैं केवल उन समाधानों को स्वीकार कर सकता हूं जहां तीनों टी-टेस्ट के लिए त्रुटि 1e-8 से कम है।scipy

मैं scipy.optimize.fmin का उपयोग कर रहा था और यह बहुत अच्छा काम करता था। ऐसे कई समाधान हैं जहां लक्ष्य कार्य शून्य हो गया।

समस्या यह है कि मुझे एक समाधान खोजने की आवश्यकता है जहां चर 0 और 10.0 के बीच हैं, और पूरे नंबर हैं या एक से अधिक अंकों का अंश भाग नहीं है। मान्य मानों के उदाहरण 0 10 3 5.5 6.8 हैं। अमान्य मानों के उदाहरण: -3 2.23 30 या 0.16666667

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

क्या इसे हल करने का कोई तरीका है? अगर कोई समाधान खोजने के लिए मुझे कई घंटों तक प्रोग्राम चलाने की ज़रूरत है तो यह कोई समस्या नहीं है। लेकिन मुझे कुछ दिनों के भीतर लगभग 10 लक्ष्य मूल्यों के समाधान ढूंढने की ज़रूरत है, और मैं नए विचारों से बाहर हूं।

यहाँ एक उदाहरण मेगावाट है:

import math 
import numpy 
import scipy.optimize 
import scipy.stats 
import sys 

def log(s): 
    sys.stdout.write(str(s)) 
    sys.stdout.flush() 

# List of target T values: TAB, TCA, TCB 
TARGETS = numpy.array([ 
    [0.05456834, 0.01510358, 0.15223353 ], # task 1 to solve 
    [0.15891875, 0.0083665,  0.00040262 ], # task 2 to solve 
]) 
MAX_ERR = 1e-10 # Maximum error in T values 
NMIN,NMAX = 8,10 # Number of samples for T probes. Inclusive. 

def fsq(x, t, n): 
    """Returns the differences between the target and the actual values.""" 
    a,b,c = x[0:n],x[n:2*n],x[2*n:3*n] 
    results = numpy.array([ 
     scipy.stats.ttest_rel(a,b)[1], # ab 
     scipy.stats.ttest_rel(c,a)[1], # ca 
     scipy.stats.ttest_rel(c,b)[1] # cb 
    ]) 
    # Sum of squares of diffs 
    return (results - t) 

def f(x, t, n): 
    """This is the target function that needs to be minimized.""" 
    return (fsq(x,t,n)**2).sum() 

def main(): 
    for tidx,t in enumerate(TARGETS): 
     print "=============================================" 
     print "Target %d/%d"%(tidx+1,len(TARGETS)) 
     for n in range(NMIN,NMAX+1): 
      log(" => n=%s "%n) 
      successful = False 
      tries = 0 
      factor = 0.1 
      while not successful: 
       x0 = numpy.random.random(3*n) * factor 
       x = scipy.optimize.fmin(f,x0, [t,n], xtol=MAX_ERR, ftol=MAX_ERR) 
       diffs = fsq(x,t,n) 
       successful = (numpy.abs(diffs)<MAX_ERR).all() 
       if successful: 
        log(" OK, error=[%s,%s,%s]\n"%(diffs[0],diffs[1],diffs[2])) 
        print " SOLUTION FOUND " 
        print x 
       else: 
        tries += 1 
        log(" FAILED, tries=%d\n"%tries) 
        print diffs 
        factor += 0.1 
        if tries>5: 
         print "!!!!!!!!!!!! GIVING UP !!!!!!!!!!!" 
         break 
if __name__ == "__main__": 
    main() 
+0

'scipy.optimize.fmin' नेल्डर-मीड एल्गोरिदम का उपयोग करता है, इसका साइपी कार्यान्वयन फ़ाइल 'optimize.py' में' _minimize_neldermead' फ़ंक्शन में है। आप इस फ़ंक्शन की एक प्रतिलिपि ले सकते हैं और जब भी फ़ंक्शन (0 और 10 के बीच एक दशमलव के साथ) वेरिएबल्स में परिवर्तन को गोल करने के लिए ('x ...' फ़ंक्शन के त्वरित निरीक्षण से) उन्हें बदलता है। (Succes की गारंटी नहीं है) –

+0

अपने विचार के साथ, मैं सबसे अच्छा कर सकता था हर टी-टेस्ट मूल्य के लिए लगभग 1e-5 अंतर था। मुझे थोड़ा बेहतर चाहिए: 1e-8। अभी भी परीक्षण मोड में प्रोग्राम चला रहा है। यह एक बेहतर समाधान मिल सकता है। – nagylzs

उत्तर

2

आप क्या करना (अगर मैं अपने सेटअप समझा) प्रयास कर रहे हैं पूर्णांक प्रोग्रामिंग कहा जाता है और यह एनपी कठिन है; http://en.wikipedia.org/wiki/Integer_programming। मुझे एहसास है कि आप पूर्णांक समाधान की तलाश नहीं कर रहे हैं, लेकिन यदि आप अपने सभी इनपुट 10 से गुणा करते हैं और अपने लक्ष्य फ़ंक्शन को 100 तक विभाजित करते हैं, तो आप एक समतुल्य समस्या प्राप्त करते हैं जहां इनपुट सभी पूर्णांक होते हैं। मुद्दा यह है कि, आपके इनपुट अलग हैं।

लक्ष्य कार्य जो आप काम कर रहे हैं वह एक उत्तल, वर्गबद्ध कार्य है, और वहां अच्छी बाधा अनुकूलन एल्गोरिदम हैं जो अंतराल [0, 10] में वास्तविक मूल्यवान इनपुट के लिए इसे शीघ्रता से हल करेंगे। इससे आप आस-पास के सभी स्वीकार्य बिंदुओं को गोल करने या जांचने का प्रयास कर सकते हैं, लेकिन उनमें से 2^एन हैं, जहां एन इनपुट की संख्या है। यहां तक ​​कि यदि आप ऐसा करते हैं, तो इष्टतम समाधान इन बिंदुओं में से एक होने की गारंटी नहीं है।

पूर्णांक प्रोग्रामिंग समस्याओं के लिए अनुमानित एल्गोरिदम हैं और आप पाते हैं कि कभी-कभी उनमें से एक आपको इष्टतम बिंदु पर लाने के लिए पर्याप्त रूप से पर्याप्त काम करता है। मेरे द्वारा उद्धृत विकिपीडिया आलेख में उन चीजों की एक सूची है जो आप कोशिश कर सकते हैं, लेकिन मुझे नहीं पता कि आप इस समस्या को हल करने की कोशिश कर खुश होंगे।

+0

इस समाधान को स्वीकार किया क्योंकि इसमें बड़ी संख्या में एल्गोरिदम शामिल हैं जिनका उपयोग समाधान खोजने के लिए किया जा सकता है। यह भी वर्णन करता है कि इसे खोजने का कोई आसान और सटीक तरीका नहीं है। – nagylzs

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