scipy优化fmin语法

时间:2013-06-24 06:24:08

标签: python optimization scipy

numseq = ['0012000', '0112000', '0212000', '0312000', '1012000', '1112000',                                                                                   '1212000', '1312000', '2012000', '2112000', '2212000', '2312000', '3012000', '3112000',          '3212000', '3312000', '0002000', '0022000', '0032000', '1002000', '1022000', '1032000',     '2002000', '2022000', '2032000', '3002000', '3022000', '3032000', '0010000', '0011000', '0013000', '1010000', '1011000', '1013000', '2010000', '2011000', '2013000', '3010000', '3011000', '3013000', '0012100', '0012200', '0012300', '1012100', '1012200', '1012300', '2012100', '2012200', '2012300', '3012100']
prob = [-0.66474525640568083, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.78361598908750163, -0.66474525640568083, -0.66474525640568083, -0.66474525640568083, -0.66474525640568083, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.66474525640568083, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.66474525640568083, -0.66474525640568083, -0.66474525640568083, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.66474525640568083, -0.66474525640568083, -0.66474525640568083, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.66474525640568083, -0.66474525640568083, -0.66474525640568083, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212, -0.49518440694747212]

numseqprob是每个长度为50的列表。它们是收集的实验数据。 numseq对应于X轴值,prob对应于Y轴值。

我想要最小化的功能是:

def residue(allparams, xdata, ydata):
    chi2 = 0.0
    for i in range(0,len(xdata)):
        x = xdata[i]
        y = 0
        for j in range(len(x)):
            y = y-allparams[int(x[j])][j]
            chi2 = chi2 + (ydata[i]-y)**2
return chi2

所以:

  • allparams是一个4×7矩阵,其中包含要优化的所有参数。
  • xdata是X轴值,即numseq
  • ydata只是一个数字列表,即prob

chi2是实验值和模型值之间的平方差异。这是必须最小化的。

参数的初始猜测由下式给出:

x0 = [[-0.6, -0.6, -0.6, -0.6, -0.6, -0.6, -0.6], [-0.6, -0.6, -0.6, -0.6, -0.6, -0.6, -0.6], [-0.6, -0.6, -0.6, -0.6, -0.6, -0.6, -0.6], [-0.6, -0.6, -0.6, -0.6, -0.6, -0.6, -0.6]]

现在如何在此功能上调用fmin?我试过了

fmin(residue, x0, args=(numseq, prob))

但我一直收到错误:

Traceback (most recent call last):
  File "<pyshell#362>", line 1, in <module>
    fmin(residue, x0, args=(numseq, prob))
  File "C:\Python31\lib\site-packages\scipy\optimize\optimize.py", line 258, in fmin
    fsim[0] = func(x0)
  File "C:\Python31\lib\site-packages\scipy\optimize\optimize.py", line 177, in function_wrapper
    return function(x, *args)
  File "<pyshell#361>", line 7, in residue
    y = y-allparams[int(x[j])][j]
IndexError: invalid index to scalar variable.

为什么会这样?是因为fmin不能接受2D数组作为初始猜测吗?那么我是否必须更改我的整个代码才能处理一维参数数组?

即使你无法解释这个问题,你至少可以告诉我fmin模块究竟是如何运作的吗?即如何实现fmin优化N维数组的语法?你能解释一下args()是什么吗?我是优化的新手,我不知道如何实现它:(

1 个答案:

答案 0 :(得分:2)

“fmin”例程可以接受2d数组作为初始猜测。但它做的第一件事是扁平化这个数组[(4,7) - &gt; (28)]。所以会发生的是你的残差函数将一个(4,7)数组作为输入,而“fmin”例程给它一个长度为28的扁平“x0”。这就是你看到错误的原因:
{{1 }} {
{1}}

See the source code here.

因此,您似乎必须更改残差函数以接受向量而不是数组。然而,这似乎并不太糟糕。我尝试了以下似乎有效(注意:请仔细检查!)

y = y-allparams[int(x[j])][j]

我用它打电话:

IndexError: invalid index to scalar variable.

并收到以下结果:

def residue_alternative(allparams, inshape, xdata, ydata):
    m, n = inshape
    chi2 = 0.0
    for i in range(0,len(xdata)):
        x = xdata[i]
        y = 0
        for j in range(len(x)):
            idx = int(x[j]) * n +  j #Double check this to 
            y = y-allparams[idx]     #make sure it does what you want
            chi2 = chi2 + (ydata[i]-y)**2
    return chi2

您可以将其重塑为4x7阵列。尝试一下,让我知道它是否有效/帮助。