Ben*_*min 6 python numpy scipy model-fitting
我有一些实验数据(对于y,x,t_exp,m_exp),并且想要使用受约束的多变量BFGS方法找到该数据的"最优"模型参数(A,B,C,D,E).参数E必须大于0,其他参数不受约束.
def func(x, A, B, C, D, E, *args):
return A * (x ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * x) / numpy.cos(t_exp))) + numpy.exp((-2 * B * x) / numpy.cos(t_exp)) * C + (D * m_exp)
initial_values = numpy.array([-10, 2, -20, 0.3, 0.25])
mybounds = [(None,None), (None,None), (None,None), (None,None), (0, None)]
x,f,d = scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(m_exp, t_exp), bounds=mybounds)
Run Code Online (Sandbox Code Playgroud)
几个问题:
func包含我的自变量,x还是应该从实验数据x_exp中提供*args?func() takes at least 6 arguments (3 given),我假设是x,我的两个*args ...我该如何定义func?编辑:感谢@ zephyr的回答,我现在明白,目标是最小化残差平方和,而不是实际函数.我得到了以下工作代码:
def func(params, *args):
l_exp = args[0]
s_exp = args[1]
m_exp = args[2]
t_exp = args[3]
A, B, C, D, E = params
s_model = A * (l_exp ** E) * numpy.cos(t_exp) * (1 - numpy.exp((-2 * B * l_exp) / numpy.cos(t_exp))) + numpy.exp((-2 * B * l_exp) / numpy.cos(theta_exp)) * C + (D * m_exp)
residual = s_exp - s_model
return numpy.sum(residual ** 2)
initial_values = numpy.array([-10, 2, -20, 0.3, 0.25])
mybounds = [(None,None), (None,None), (None,None), (None,None), (0,None)]
x, f, d = scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(l_exp, s_exp, m_exp, t_exp), bounds=mybounds, approx_grad=True)
Run Code Online (Sandbox Code Playgroud)
我不确定边界是否正常工作.当我为E指定(0,None)时,我得到一个运行标志2,异常终止.如果我将其设置为(1e-6,None),它运行正常,但选择1e-6作为E.我是否正确指定了边界?
so1*_*311 12
我不想试图弄清楚你所使用的模型代表什么,所以这是一个适合一行的简单例子:
x_true = arange(0,10,0.1)
m_true = 2.5
b_true = 1.0
y_true = m_true*x_true + b_true
def func(params, *args):
x = args[0]
y = args[1]
m, b = params
y_model = m*x+b
error = y-y_model
return sum(error**2)
initial_values = numpy.array([1.0, 0.0])
mybounds = [(None,2), (None,None)]
scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(x_true,y_true), approx_grad=True)
scipy.optimize.fmin_l_bfgs_b(func, x0=initial_values, args=(x_true, y_true), bounds=mybounds, approx_grad=True)
第一个优化是无界的,并给出正确的答案,第二个优先考虑阻止它到达正确参数的界限.
重要的是你几乎所有的优化函数,'x'和'x0'指的是你优化的参数 - 其他一切都作为参数传递.您的拟合函数返回正确的数据类型也很重要 - 这里我们需要一个值,一些例程需要一个错误向量.您还需要approx_grad = True标志,除非您想要分析地计算梯度并提供它.