同时最小化两个函数

问题描述

我正在尝试优化一个模型,该模型涉及在共享变量的同时同时拟合数据的两个函数。由于 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,w}})

model_sim = mixed_model(x=xdata,y=y,z=z,w=w)
res = minimize(mixed_model.ravel(),x0=2,args=(y,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(),

正如我所说,这是因为我已经将模型传递给了最小化函数,而它必须是一个函数,但我不确定如何同时最小化 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,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,mu_4 = x0
    error = []
    expected_output = [(1,2),(3,4)]
    for i in expected_output :
        error += [y1(B,mu_4) - i[0],y2(B,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 中找到的指数线

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

解决方法

您必须要狡猾,但要使技巧最小化并没有那么难。关键是 minimize 仅适用于 scalar cost functions,但 leastsq 可以接受元组作为参数。所以,如果你能以某种方式使用 leastsq 来最小化你的函数。这种方法应该是这样的。

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

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

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

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

出于某种原因,我无法在 Stackoverflow 上正确设置格式。

这是关于 pastebin 的代码。

https://pastebin.com/YxhkJgzD