में अलग परिवर्तनीय मानों के साथ फ़ंक्शन को कम करने के लिए कैसे करें मैं एक लक्ष्य फ़ंक्शन को अनुकूलित करने का प्रयास कर रहा हूं जिसमें एकाधिक इनपुट चर (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()
'scipy.optimize.fmin' नेल्डर-मीड एल्गोरिदम का उपयोग करता है, इसका साइपी कार्यान्वयन फ़ाइल 'optimize.py' में' _minimize_neldermead' फ़ंक्शन में है। आप इस फ़ंक्शन की एक प्रतिलिपि ले सकते हैं और जब भी फ़ंक्शन (0 और 10 के बीच एक दशमलव के साथ) वेरिएबल्स में परिवर्तन को गोल करने के लिए ('x ...' फ़ंक्शन के त्वरित निरीक्षण से) उन्हें बदलता है। (Succes की गारंटी नहीं है) –
अपने विचार के साथ, मैं सबसे अच्छा कर सकता था हर टी-टेस्ट मूल्य के लिए लगभग 1e-5 अंतर था। मुझे थोड़ा बेहतर चाहिए: 1e-8। अभी भी परीक्षण मोड में प्रोग्राम चला रहा है। यह एक बेहतर समाधान मिल सकता है। – nagylzs