Tôi đang cố gắng tối ưu hóa hàm mục tiêu có nhiều biến đầu vào (từ 24 đến 30). Các biến này là các mẫu của ba biến thống kê khác nhau, và các giá trị hàm đích là các giá trị xác suất t-test. Hàm lỗi biểu thị lỗi (tổng các bình phương của sự khác biệt) giữa xác suất t và test thực tế mong muốn. Tôi chỉ có thể chấp nhận các giải pháp mà lỗi nhỏ hơn 1e-8, cho tất cả ba bài kiểm tra t.cách giảm thiểu một hàm có giá trị biến riêng biệt trong scipy
Tôi đã sử dụng scipy.optimize.fmin
và nó hoạt động tốt. Có rất nhiều giải pháp mà hàm đích đã trở thành 0.
Vấn đề là tôi cần tìm giải pháp trong đó các biến nằm trong khoảng từ 0 đến 10,0, và là số nguyên hoặc không có nhiều hơn một phần phân số. Ví dụ về các giá trị hợp lệ là 0 10 3 5.5 6.8
. Ví dụ về các giá trị không hợp lệ: -3 2.23 30
hoặc 0.16666667
.
Tôi tình cờ biết rằng có ít nhất một giải pháp, vì giá trị đích đến từ dữ liệu đo thực tế. Dữ liệu gốc đã bị mất và nhiệm vụ của tôi là tìm chúng. Nhưng tôi không biết làm thế nào. Sử dụng thử/lỗi không phải là một lựa chọn, bởi vì có khoảng 100 giá trị có thể cho mỗi biến, và với số lượng biến, số lượng trường hợp có thể là 100 ** 30 là quá nhiều. Sử dụng fmin là tuyệt vời, tuy nhiên nó không hoạt động với các giá trị kín đáo.
Có cách nào để giải quyết vấn đề này không? Nó không phải là một vấn đề nếu tôi cần phải chạy một chương trình trong nhiều giờ để tìm một giải pháp. Nhưng tôi cần phải tìm các giải pháp cho khoảng 10 giá trị mục tiêu trong vòng một vài ngày và tôi không có ý tưởng mới.
Dưới đây là một ví dụ MWe:
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' sử dụng thuật toán Nelder-Mead, việc triển khai SciPy này nằm trong hàm' _minimize_neldermead' trong tệp 'optimize.py'. Bạn có thể lấy một bản sao của hàm này và viết lại nó, để làm tròn các thay đổi cho các biến ('x ...' từ việc kiểm tra nhanh hàm) tới các giá trị bạn muốn (từ 0 đến 10 với một số thập phân) bất cứ khi nào hàm thay đổi chúng. (Succes không được bảo đảm) –
Với ý tưởng của bạn, tốt nhất tôi có thể làm là khoảng 1e-5 sự khác biệt cho mỗi giá trị t-test. Tôi cần một chút tốt hơn: 1e-8. Vẫn chạy chương trình ở chế độ dùng thử. Nó có thể tìm thấy một giải pháp tốt hơn. – nagylzs