首页 > 解决方案 > 同时最小化两个函数

问题描述

我正在尝试优化一个模型,该模型涉及在共享变量的同时同时拟合数据的两个函数。我目前在最小化这个模型时遇到问题,因为 scipy.optimize 需要传递一个函数,但我需要将两者一起最小化。

简化的代码块(在 symfit 中执行)

dictionary = ({y1: 3x**4 + 0.5y**3 + 2z**2 + w,
               y2: x*y * exp(z**2 - w)})
mixed_model = CallableNumericalModel(dictionary, 
                connectivity_mapping = {y1:{x,y,z,w}, 
                                       y2:{x,y,z,w}})

model_sim = mixed_model(x=xdata, y=y, z=z, w=w)
res = minimize(mixed_model.ravel(), x0=2, 
               args=(y,z,w),
               options={'eps':1e-3})
fit = Fit(res,x=xdata, y1=rhoxx_exp, y2=rhoxy_exp)    
fit_result = fit.execute()
print(fit_result) 

当我使用数据运行真实模型时,出现以下属性错误:

ValueError: `f0` passed has more than 1 dimension.

回溯表明该错误发生在该行中:

res = minimize(mixed_model.ravel(), x0=2, 

正如我所说,这是因为当它必须是一个函数时我已经将一个模型传递给了最小化函数但是我不确定如何同时最小化 y1 和 y2 以适应它。

任何建议将不胜感激,在此先感谢您!

按照以下建议进行编辑,但具有实际功能:

def y1(B,n_1,n_2,n_3,n_4,mu_1,mu_2,mu_3,mu_4):
    for i in range(len(dictionary)):
        return (np.exp(B[i]/f)+np.exp(-B[i]/f))
    return ( (rho1 / (rho1**2 + (R1*B)**2) + rho2 / (rho2**2 + (R2*B)**2) 
    
    + rho3 / (rho3**2 + (R3*B)**2) + rho4 / (rho4**2 + (R4*B)**2)) 
    
    / ((rho1 / (rho1**2 + (R1*B)**2) + rho2 / (rho2**2 + (R2*B)**2) 
    
    + rho3 / (rho3**2 + (R3*B)**2) + rho4 / (rho4**2 + (R4*B)**2))**2
       
       + ((-R1*B)/(rho1**2+(R1*B)**2) + (-R2*B)/(rho2**2+(R2*B)**2)
                                                
       + (-R3*B)/(rho3**2+(R3*B)**2) + (-R4*B)/(rho4**2+(R4*B)**2))**2)
    
    + (a/(np.exp(B/f)+np.exp(-B/f))/2)*((rho1 / (rho1**2 + (R1*B)**2) + rho2 / (rho2**2 + (R2*B)**2) 
    
    + rho3 / (rho3**2 + (R3*B)**2) + rho4 / (rho4**2 + (R4*B)**2)) 
    
    / ((rho1 / (rho1**2 + (R1*B)**2) + rho2 / (rho2**2 + (R2*B)**2) 
    
    + rho3 / (rho3**2 + (R3*B)**2) + rho4 / (rho4**2 + (R4*B)**2))**2
       
       + ((-R1*B)/(rho1**2+(R1*B)**2) + (-R2*B)/(rho2**2+(R2*B)**2)
                                                
       + (-R3*B)/(rho3**2+(R3*B)**2) + (-R4*B)/(rho4**2+(R4*B)**2))**2)) )

def y2(B,n_1,n_2,n_3,n_4,mu_1,mu_2,mu_3,mu_4):
    return  ( - ((-R1*B)/(rho1**2+(R1*B)**2) + (-R2*B)/(rho2**2+(R2*B)**2)
                                                
       + (-R3*B)/(rho3**2+(R3*B)**2) + (-R4*B)/(rho4**2+(R4*B)**2)) / 
    
  ((rho1 / (rho1**2 + (R1*B)**2) + rho2 / (rho2**2 + (R2*B)**2) 
    
    + rho3 / (rho3**2 + (R3*B)**2) + rho4 / (rho4**2 + (R4*B)**2))**2
       
       + ((-R1*B)/(rho1**2+(R1*B)**2) + (-R2*B)/(rho2**2+(R2*B)**2)
                                                
       + (-R3*B)/(rho3**2+(R3*B)**2) + (-R4*B)/(rho4**2+(R4*B)**2))**2)  )
    
def f(x0):
    B,n_1,n_2,n_3,n_4,mu_1,mu_2,mu_3,mu_4 = x0
    error = []
    expected_output = [(1,2), (3,4)]
    for i in expected_output :
        error += [y1(B,n_1,n_2,n_3,n_4,mu_1,mu_2,mu_3,mu_4) - i[0],
                  y2(B,n_1,n_2,n_3,n_4,mu_1,mu_2,mu_3,mu_4) - i[1],
                 ]
    return error
x0 = (0, 1.51e27, -1.519e27, 0.915e27, -1.047e27, 1.41, 0.64, 0.087, 0.09)
result = scipy.optimize.leastsq( f, x0, epsfcn = 1e-3)

显示错误:

IndexError: invalid index to scalar variable.

在与指数一致的函数 y1 中找到

任何进一步的建议都会令人惊讶,在此先感谢您!

标签: python-3.xsympyscipy-optimize-minimizesymfit

解决方案


你必须很狡猾,但欺骗最小化并不难。关键是它minimize仅适用于标量成本函数,但leastsq可以接受元组作为参数。因此,如果您可以以某种方式使用 usingleastsq来最小化您的功能。该方法将是这样的。

  • 定义您希望最小化的函数 y1(w,x,y,z), y2(w,x,y,z), ...

  • 将要最小化的函数定义为 f(),其中 x0 扩展为参数元组。

  • 函数 f 返回离散测量样本与单个函数 y1、y2 等之间的差异向量。

  • 让 SciPy 最小化这个函数,从合理选择的初始参数向量开始。

出于某种原因,我无法在 Stackoverflow 上真正获得正确的格式。

所以这是pastebin上的代码。

https://pastebin.com/YxhkJgzD


推荐阅读