여러 입력 변수 (24에서 30 사이)가있는 대상 함수를 최적화하려고합니다. 이 변수는 세 가지 다른 통계 변수의 샘플이며 대상 함수 값은 t- 검정 확률 값입니다. 에러 함수는 원하는 t- 테스트 확률과 실제 t- 테스트 확률 사이의 오차 (차이의 제곱의 합)를 나타냅니다. 오류가 1e-8 미만인 경우에만 세 가지 t- 테스트 모두에 대한 해결책을 수락 할 수 있습니다.scipy에서 개별 변수 값을 사용하여 함수를 최소화하는 방법
나는 scipy.optimize.fmin
을 사용하고 있었는데 잘 동작했습니다. 대상 함수가 0이 된 많은 솔루션이 있습니다.
문제는 변수가 0에서 10.0 사이에 있고 정수이거나 소수점 이하 자릿수가 하나 이상없는 해결책을 찾아야한다는 것입니다. 유효한 값의 예는 0 10 3 5.5 6.8
입니다. 잘못된 값의 예 : -3 2.23 30
또는 0.16666667
목표 값이 실제 측정 데이터에서 나오기 때문에 적어도 하나의 솔루션이 있다는 것을 알고 있습니다. 원래 데이터가 손실되었으며, 내 작업은 데이터를 찾는 것입니다. 하지만 어떻게해야할지 모르겠다. 시행 착오를 사용하는 것은 선택 사항이 아닙니다. 왜냐하면 각 변수에 대해 약 100 개의 가능한 값이 있고 변수의 수를 고려할 때 가능한 경우의 수가 100 ** 30이 될 것이기 때문에 너무 많습니다. fmin 사용은 훌륭하지만, 신중한 값에서는 작동하지 않습니다.
해결 방법이 있습니까? 해결책을 찾기 위해 여러 시간 동안 프로그램을 실행해야하는 경우에는 문제가되지 않습니다. 그러나 며칠 내에 약 10 개의 목표 값에 대한 솔루션을 찾아야하며 새로운 아이디어가 없습니다. 여기
는 예 MWE입니다 : 정수 프로그래밍이라고하고 NP-하드입니다 당신이 (내가 당신의 설정을 이해하는 경우) 할 시도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'은 Nelder-Mead 알고리즘을 사용합니다. SciPy 구현은'optimize.py' 파일의'_minimize_neldermead' 함수에 있습니다. 이 함수의 복사본을 가져 와서 함수의 빠른 검사에서 변수에 대한 변경 사항 ('x ...')을 원하는 값 (10 진수로 0에서 10 사이)으로 바꿀 수 있습니다. 변경합니다. (Succes 보장되지 않음) –
당신의 아이디어로, 내가 할 수있는 최선의 방법은 약 t- 테스트 값마다 약 1e-5 차이입니다. 나는 조금 더 나아야한다 : 1e-8. 아직 평가판 모드로 프로그램을 실행 중입니다. 더 나은 해결책을 찾을 수 있습니다. – nagylzs