如何在Python中调用scipy.optimize.fmin_cg(func)的函数

时间:2013-10-28 20:40:58

标签: python numpy scipy

我将简单地解释一下这个问题。此问题与scipy.doc中显示的完全相似。问题在于错误发生,因为需要浮点参数,而不是numpy.ndarray

我有什么:

  • 功能: y = s * z ^ t

可变长度/尺寸

  • t - 1 ... m,
  • s - 1 ... m和1 ... n。所以,m是行号,n - 列号。
  • z - 1 ... n。
  • y - 这可以是y 1,y [2],y [3],...,y [m],
  • T - s [m,n]矩阵

喜欢这个

  1. y[1] = s[1][1]*z[1]^t[1]+s[1][2]*z[2]^t[1]+...s[1][n]*z[n]^t[1])

  2. y[2] = s[2][1]*z[1]^t[2]+s[2][2]*z[2]^t[2]+...s[2][n]*z[n]^t[2])

    ...

  3. y[m] = s[m][1]*z[1]^t[m]+s[m][2]*z[2]^t[2]+...s[m][n]*z[n]^t[m])

  4. 问题:发生错误。

    Optimization terminated successfully.
    
    Traceback (most recent call last):
        solution = optimize.fmin_cg(func, z, fprime=gradf, args=args)
      File "C:\Python27\lib\site-packages\scipy\optimize\optimize.py", line 952, in fmin_cg
        res = _minimize_cg(f, x0, args, fprime, callback=callback, **opts)
      File "C:\Python27\lib\site-packages\scipy\optimize\optimize.py", line 1072, in _minimize_cg
        print "         Current function value: %f" % fval
    TypeError: float argument required, not numpy.ndarray
    

    以下是代码

    import numpy as np
    import scipy as sp
    import scipy.optimize as optimize
    
    def func(z, *args):
        y,T,t = args[0]
        return y - counter(T,z,t)
    
    def counter(T, z, t):
        rows,cols = np.shape(T)
        res = np.zeros(rows)
        for i,row_val in enumerate(T):
            res[i] = np.dot(row_val, z**t[i])
        return res
    
    
    def gradf(z, *args):
        y,T,t = args[0]
        return np.dot(t,counter(T,z,t-1))
    
    def main():
        # Inputs
        N = 30
        M = 20
        z0 = np.zeros(N) # initial guess
        y = 30*np.random.random(M)
        T = 10*np.random.random((M,N))
        t = 5*np.random.random(M)
        args = [y, T, t]
    
        solution = optimize.fmin_cg(func, z0, fprime=gradf, args=args)
        print 'solution: ', solution
    
    if __name__ == '__main__':
        main()
    

    我也试图找到类似的例子,但找不到非常相似的东西。以下是供您考虑的代码。提前谢谢。

1 个答案:

答案 0 :(得分:4)

问题的根源是fmin_cg期望函数返回错误匹配而不是数组的单个标量值。

基本上,你想要一些模糊的东西:

def func(z, y, T, t):
    return np.linalg.norm(y - counter(T,z,t))

我在这里使用np.linalg.norm因为numpy中没有内置函数用于均方根。实际的RMS为norm(x) / sqrt(x.size),但为了最小化,常数乘数不会产生任何差异。

您的代码中还存在其他一些小问题(例如args[0]将是单个项目。您想要y, T, t = args或更好,只需func(z, y, T, t))。你的渐变函数对我没有任何意义,但无论如何它都是可选的。此外,解决方案目前无法产生合理的值,因为您正在测试纯噪声。我认为这些只是意味着占位符值。

但是,你有一个更大的问题。你试图在30维空间中最小化。大多数非线性求解器不能很好地处理那么高的维数。它可能工作正常,但你很可能会遇到问题。

所有这一切,你可能会发现使用scipy.optimize.curve_fit界面而不是使用其他界面更直观,如果你对LM而不是CG(它们是相当类似的方法)没有问题。 / p>


最后一件事:你试图通过20次观察来解决30个模型参数。这是一个未确定的问题。此问题没有唯一的解决方案。您将需要应用一些先验知识来获得合理的答案。