简体   繁体   English

如何将 scipy.optimize.fmin 与向量而不是标量一起使用

[英]How to use scipy.optimize.fmin with a vector instead of a scalar

When using Scipy's fmin function, I keep encountering the error message: ValueError: setting an array element with a sequence I have seen that this question has been asked already some times, and I have read interesting posts such as:在使用 Scipy 的 fmin function 时,我一直遇到错误消息:ValueError: setting an array element with a sequence 我已经看到这个问题已经被问过几次了,我读过一些有趣的帖子,例如:

..and have tried implementing the suggested solutions, such as adding '*args' to the cost function, appending the variables in the cost function to a list and vectorizing the variables. ..并尝试实施建议的解决方案,例如将“*args”添加到成本 function,将成本 function 中的变量附加到列表并将变量矢量化。 But nothing has worked for me so far.但到目前为止,没有什么对我有用。

I am quite new to programming in Python, so it is possible that I have read the solution and not known how to apply it.我对 Python 中的编程非常陌生,所以我可能已经阅读了解决方案,但不知道如何应用它。

A simplified version of the code, which I used to try to find the problem, is as follows:我用来找问题的简化版代码如下:

import numpy as np
import scipy.optimize
from scipy.optimize import fmin
fcm28=40
M_test=np.array([32.37,62.54,208,410,802])
R_test=np.array([11.95,22.11,33.81,39.18,50.61])
startParams=np.array([fcm28,1,1])

def func(xarray):
   x=xarray[0]
   y=xarray[1]
   z=xarray[2]
   expo3=x*np.exp(-(y/M_test)**z)
   cost=expo3-R_test
   return cost 
### If I write the following lines of code:
# xarray=(100,290,0.3)
# print(func(xarray))
# >> [ 2.557 -1.603 -0.684 1.423 -2.755] #I would obtain this output

func_optimised=fmin(func,x0=[fcm28,1,1],xtol=0.000001)

Objective: I am trying to obtain an exponential function 'expo3' (that takes 5 adjustment points, defined by vector 'M_test' on the horizontal axis and 'R_test' in the vertical axis.目标:我正在尝试获得指数 function 'expo3'(需要 5 个调整点,由水平轴上的向量'M_test'和垂直轴上的'R_test'定义。 调整点 (M_test,R_test) What I am trying to minimise is the difference between the function 'expo3' and the adjustment points.我试图最小化的是 function 'expo3' 和调整点之间的差异。 So, the exponential graph is meant to go as close as possible to the adjustment points, such as:所以,指数图的意思是go尽量靠近调整点,比如: 实现“expo3-R_test”最小化的指数曲线

I obtain the following error message:我收到以下错误消息:

File "Example2.py", line 20, in <module>
   func_optimised=fmin(func,x0=[fcm28,1,1],xtol=0.000001)
File "/home/.../python3.6/site-packages/scipy/optimize/optimize.py", line 443, in fmin
 res=_minimize_neldermead(func,x0,args,callback=callback,**opts)
File "/home/.../python3.6/site-packages/scipy/optimize/optimize.py" line 586, in _minimize_neldermead
   fsim[k] = func(sim[k])
ValueError: setting an array element with a sequence.

Can fmin be used to accomplish this task? fmin 可以用来完成这个任务吗? Are there any viable alternatives?有没有可行的替代方案? Any help on how to solve this would be really appreciated.任何有关如何解决此问题的帮助将不胜感激。

As noted in the commments, your function must return a single value.如评论中所述,您的 function 必须返回单个值。 Assuming that you want to perform a classic least squares fit, you could modify func to return just that:假设您要执行经典的最小二乘拟合,您可以修改func以返回:

  def func(...):
      # ... identical lines skipped
      cost = sum((expo3-R_test)**2)
      return cost

With that change, func_optimised becomes:随着这一变化, func_optimised变为:

  array([1.10633369e+02, 3.85674857e+02, 2.97121854e-01])
  # or approximately (110.6, 385.6, 0.3)

Just as a pointer: you could alternatively use scipy.optimize.curve_fit for basically doing the same thing, but with a nicer API that allows you to directly provide the function skeleton + the sample points to fit.就像一个指针:您也可以使用scipy.optimize.curve_fit基本上做同样的事情,但使用更好的 API 允许您直接提供 ZC1C425268E68385D1AB5074C17A94F 的样本点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM