首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用多个数据集(scipy.minimize / scipy.optimise、pymoo或??)优化数值模型

使用多个数据集(scipy.minimize / scipy.optimise、pymoo或??)优化数值模型
EN

Stack Overflow用户
提问于 2020-10-28 00:31:48
回答 1查看 163关注 0票数 1

所以我有一个问题,在这一点上我有点迷茫。因此,任何意见都将非常感谢,因为我现在真的在努力^^!

我有一个模型,我想用我得到的一些实验数据来检查/优化。

一般来说,我的模型有两个输入(比如时间和温度),有8个变量(x0-x7)。该模型生成两个输出(out1和out2)。

每组实验数据为我提供了4组可用于优化的信息:2个输入(时间和温度)和2个实验结果(result1和result2)。

最终,我想最小化result1 & out1和result2 & out2之间的区别。因此,基本上最小化具有几组数据的两个残差,这些数据受8个参数的影响,这些参数都有共同的(x0-x7)。

我对参数x0-x7有一些限制,这可能会有所帮助,但除此之外,没有实际的约束。

到目前为止,我已经尝试使用scipy.minimize对我的实验结果数据集进行迭代,如下所示(非常简单):

代码语言:javascript
复制
import numpy as np
from scipy.optimize import minimize

Experiment=[['Set 1','Set 2',
             'Set 3','Set 4'],
                   [Out 1-1,Out 1-2,
                    Out 1-3,Out 1-4],
                   [Out 2-1,Out 2-2,
                    Out 2-3,Out 2-4],
            ]
global curr_case
curr_case=0 #just for debugging in the first place

def objective_fcn(x):
    
    SetFitParameters(x) #x0-x7
    
    #---------probably totally dumb: iteration-----------
    global curr_case    #number of experimental set
        curr_case=curr_case+1
    if curr_case==len(Experiment):
        curr_case=0
    #----------------------------------------------------
    
    getTemp(curr_case) # function that gets time and temperature from experimental data as two arrays - time and temperature
    
    RefVariables(x) #sets some global variabales needed for ModelCal using x0-x7
    
    ModelCal(time,Temperature)  #gives Out1 and Out2
    
    f1 = abs(Out1[Upper_index-1]-Experiment[1][curr_case]) #compares Out1 with result1 (from experimental data)
    f2 = abs(Out2[Upper_index-1]-Experiment[2][curr_case]) #compares Out2 with result2 (from experimental data)
    
    # some weighting factors for the future - maybe?
    A=1
    B=1
    
    return A*f1+B*f2
   
bounds_x1=(1450,1700) #upper and lower bonds of x0
bounds_x2=(0.1,1)
bounds_x3=(1450,1700)
bounds_x4=(0.1,7)
bounds_x5=(1450,1700)
bounds_x6=(0.1,7)
bounds_x7=(1450,1700)
bounds_x8=(0.1,7)

bounds=[bounds_x1,bounds_x2,bounds_x3,bounds_x4,bounds_x5,bounds_x6,bounds_x7,bounds_x8]

x0=[1663,0.156,1523,6.37,1663,4.38,1523,2.2] #some initial guesses

result=minimize(objective_fcn, x0,bounds=bounds)

这显然不起作用,因为我只是迭代了不同的案例。搜索Stackoverflow得到了一些结果,但是它们似乎都优化了给定的函数,这是我没有的!

第一个问题是:你会推荐什么样的优化?这是否接近于有用的东西呢?

第二个问题:如何在优化时考虑多个实验数据集?我获取输入的方法似乎相当粗糙。我还尝试用已经实现为数组元素的数据创建两个列表,但也没有用。

最后:正如任何有一点优化知识的人都已经看到的那样,我在这个领域相当生疏-所以我很抱歉,但如果有人能给我指出正确的方向或提供帮助-将不胜感激!

我已经找到的资源:-Fitting multiple data sets using scipy.optimize with the same parameters -Fit plane to a set of points in 3D: scipy.optimize.minimize vs scipy.linalg.lstsq

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-29 16:07:25

共享目标函数的基本思想很好。我真的不会深入到操作尝试的细节,因为这可能会产生误导。该过程将定义可以在最小二乘拟合中使用的适当的残差函数。在Python中有几种可能性可以做到这一点。我将展示scipy.optimize.leastsq和密切相关的scipy.optimize.least_squares

代码语言:javascript
复制
import numpy as np
from scipy.optimize import least_squares ## allows bounds and has given loss functions but provides only Jacobian
from scipy.optimize import leastsq ## provides scaled covariance matrix


"""
some arbitrary test function taking two inputs and providing
two correlated outputs with shared parameters - only three for testing.
"""
def test_function( time, temp, x0, x1, x2 ):
    s = np.sqrt( time/x0 ) * np.log( ( temp - x1 ) / x2 )
    t = np.exp( - time/x0 ) * np.sqrt( (time/x0)**2 + ( ( temp - x1 ) / x2 )**2 )
    return s, t

### make some data with noise
indata = list()
for _ in range( 60 ):
    a = 50 * np.random.random()
    b = 10 + 25 * np.random.random()
    indata.append( [a,b] )

outdata = list()
for a,b in indata:
    s,t = test_function( a, b, 3.78, 5.33, 12.88 )
    noise1 = np.random.normal( scale=0.01 )
    noise2 = np.random.normal( scale=0.01 )
    outdata.append( [s + noise1, t + noise2 ] )

indata = np.array( indata)
outdata = np.array( outdata)

#########################################################################
### define the residulas function for fitting This is the important part!
#########################################################################

def residuals( params, xdata, ydata, weightA=1, weightB=1 ):
    x0, x1, x2 = params
    diff = list()
    for ab, st in zip( indata, outdata ):
        a, b = ab
        s, t = st
        sf, tf = test_function( a, b, x0,x1, x2 )
        diff.append( weightA * ( s - sf ) )
        diff.append( weightB * ( t - tf ) )
    return diff

### Fit
solx, cov, info, msg, ier = leastsq( 
    residuals, [ 3.8, 5.0, 12.5],
    args=( indata, outdata ), full_output=True
)
print solx
print cov
sol = least_squares( residuals, [ 3.8, 5.0, 12.5 ], args=( indata, outdata ))
print sol.x

根据OP的需要对其进行修改应该很容易。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64558862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档