通过优化单个参数最小化模型和观测值之间的差异

2024-04-26 00:39:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我承认我不确定这个问题是否更适合这里的StackOverflow或其他地方,因为我不确定这是编程还是我需要理解的整个概念。如果离题,我道歉。在

在Python中,我创建了一个相当简单的模型。这个函数需要一个数组x,几个系数c1c2等,以及我要优化的参数P。 我想通过改变参数P来最小化测量值和建模值之间的差异,作为输出,我希望得到结果参数(标量)以及模型和测量值(数组)之间的结果差异。在

我一直在研究scipy.optimize.minimizedocumentation,但我似乎不明白。尤其是,我不明白:

  1. 如何定义进入最小化的标量函数,以便只修改P。在
  2. 在这种情况下,哪种最小化方法是最好的(我假设了最小二乘法,但是看了文档中有太多其他方法,我甚至不知道如果推荐另一种方法,我愿意接受这个选项,只要建议中有解释)。在
  3. 如何获得所需的输出(因为优化结果似乎是一个整体的python对象,但我只想要上面提到的非常具体的输出)

示例:

import numpy as np

array1 = np.random.rand(10)
array2 = np.arange(5.,55,5)

from scipy.optimize import minimize

def model(c1, c2, c3, x, P):
    modelY = x*c1 + c2*x*P + c3 # some random function for which I need to optimize P
    return modelY

现在,如果我想要的函数的最小值是np.abs(measured - modelY),并且我想更改的唯一参数是P,它是model函数的一个参数,并使用测量的数据作为初始猜测,那么我将对scipy.optimize.minimize使用什么语法?还是我应该把它们放在一个函数中?但是我如何指定不修改函数的所有其他参数,除了一个参数? 我如何从最小化结果中提取差异和结果{}?在


Tags: 方法函数模型import参数nprandomscipy
1条回答
网友
1楼 · 发布于 2024-04-26 00:39:16

你的问题,imho,在描述和参数名称上受到了很大的影响,但是我想我现在得到了你想要的结果。在

我稍微简化了一下,并用两种方法给出了一些代码,好的坏的。好的一个:通过对单个变量(minimize_scalar)使用优化器来优化一个变量!坏的一个:使用任何多变量优化器(minimize)。在

也许有人会谈论如何使用scipy的优化器,但我不会这么做。我只想说:跟着医生!最重要的是(这里是从最小化文档中摘录的内容):

The callable is called as method(fun, x0, args, **kwargs, **options) where kwargs corresponds to any other parameters passed to minimize (such as callback, hess, etc.), except the options dict, which has its contents also passed as method parameters pair by pair. Also, if jac has been passed as a bool type, jac and fun are mangled so that fun returns just the function values and jac is converted to a function returning the Jacobian. The method shall return an OptimizeResult object.

这意味着:p是函数中给scipy优化器的第一个参数(在这两种情况下)。其他的,您可以使用python的作用域规则(函数可用的变量)或使用args。在

代码:

import numpy as np
from scipy.optimize import minimize, minimize_scalar
np.random.seed(1)                                            # make this demo deterministic

# Let's define some random-data and use names people can understand!
f_x = np.random.rand(10)
f_y = np.arange(5.,55,5)
c1, c2, c3 = 2, 1.5, 0.321

# Simple loss-function
def loss(P, c1, c2, c3, f_x, f_y):
    modelY = f_x*c1 + f_x*c2*P + c3                                    # prediction (vector)
    return np.linalg.norm(f_y - modelY, 1)                             # l1-loss (scalar)

# GOOD APPROACH: minimize_scalar
result = minimize_scalar(loss, args=(c1, c2, c3, f_x, f_y))
p_at_minimum = result.x  # i'm a scalar!
print('minimize_scalar result: ', p_at_minimum)

# BAD APPROACH: minimize (multivariate) -> need guess / initial value!
result = minimize(loss, np.zeros(1), args=(c1, c2, c3, f_x, f_y))
p_at_minimum = result.x   # i'm a vector!!!
print('minimize result: ', p_at_minimum)

输出:

^{pr2}$

编辑:刚刚认识到,我的var名称也不好。f_x不是某个函数的某种求值,应该只调用x,但要小心:x通常是要优化的参数!在

备注:并始终检查结果!在

例如

result = minimize_scalar(loss, args=(c1, c2, c3, f_x, f_y))
p_at_minimum = result.x  # i'm a scalar!
print('minimize_scalar result: ', p_at_minimum)
print('success: ', result.success)
# True

result = minimize(loss, np.zeros(1), args=(c1, c2, c3, f_x, f_y))
p_at_minimum = result.x   # i'm a vector!!!
print('minimize result: ', p_at_minimum)
print('success: ', result.success)
# False (precision-loss -> you can check result.message

这就是为什么我推荐minimize\u scalar,它使用更多的假设,因此更健壮(不需要太多的调优)!在

相关问题 更多 >