scipy '最小化一组方程的平方和

1 投票
3 回答
6471 浏览
提问于 2025-04-15 14:39

我在使用scipy的'leastsq'优化程序时遇到了一个问题,如果我运行以下程序,它会显示

    raise errors[info][1], errors[info][0]
TypeError: Improper input parameters.

有时候还会出现 数组索引超出范围 的错误...

from scipy import *
import numpy
from scipy import optimize
from numpy import asarray
from math import *

def func(apar):
  apar = numpy.asarray(apar)
  x = apar[0]
  y = apar[1]
  eqn = abs(x-y)
  return eqn

Init = numpy.asarray([20.0, 10.0])
x = optimize.leastsq(func, Init, full_output=0, col_deriv=0, factor=100, diag=None, warning=True)
print 'optimized parameters: ',x
print '******* The End ******'

我不知道我的func optimize.leastsq()调用出了什么问题,请帮帮我。

3 个回答

1

因为你想要最小化一个简单的标量函数(也就是说,func() 只返回一个值,而不是一堆值),所以应该用 fmin 函数中的一个来替代 scipy.optimize.leastsq() 的调用(记得传入合适的参数):

x = optimize.fmin(func, Init)

这样做是正确的!

实际上,leastsq() 是用来最小化一组值的平方和的。它似乎不适合处理只有一个值的情况,就像你例子中的那样(虽然从理论上讲,它是可以的)。

1

刚刚看了一下最小二乘法的文档,可能是你的函数func定义得不太对。你假设总是会收到一个长度至少为2的数组,但优化函数对于你会收到的数组长度并没有明确说明。你可以试着把apar的内容打印出来,看看你实际得到了什么。

如果你在使用像ipython或者Python的命令行,你应该能看到错误的堆栈跟踪,这样可以告诉你错误发生在哪一行,所以可以从这里入手。如果你还是搞不清楚,发一下堆栈跟踪的信息可能会对我们有帮助。

2

leastsq 是处理向量的,所以残差函数 func 需要返回一个长度至少为二的向量。因此,如果你把 return eqn 替换成 return [eqn, 0.],你的例子就能正常工作了。运行后会得到:

optimized parameters:  (array([10., 10.]), 2)

这是绝对差值最小的众多正确答案之一。

如果你想要最小化一个标量函数,使用 fmin 是更好的选择,格式是 optimize.fmin(func, Init)

这里的问题是,这两个函数虽然在处理标量时看起来相似,但它们的目标是不同的。leastsq 用于找到最小平方误差,通常是从一组理想化的曲线中得出的,这是一种“最佳拟合”的方法。而 fmin 则是用来找到标量函数的最小值。

显然,你的例子只是个玩具示例,这两种方法都不太适用,所以你选择哪种方法取决于你的最终目标是什么。

撰写回答