首页 文章

Python:scipy.optimize.minimize在使用x和y args调用函数时失败并显示“ValueError:设置带序列的数组元素 . ”

提问于
浏览
0

如 Headers 中所述,scipy.optimize.minimize失败并显示“ValueError:使用序列设置数组元素” . 当调用最小化时 .

我正在将scipy.optimize.minimize应用于使用变量coef(我正在优化的系数)和xData和yData(数据变量)的函数 .

我'll provide an example code below. I am aware through searching on how to use minimize that the error stems from the function being minimized returning an array when it should return a scalar. I'我不知道为什么它会返回一个数组 .

重要的是,scipy.optimize.least_squares可以工作,它似乎与scipy.optimize.minimize共享相同的语法 . scipy.optimize.fmin也不起作用,它也包括在内 - 它与Nelder-Mead方法的最小化相同,我正在调用它 .

这是一些在Python 3上有错误的通用示例代码:

import numpy as np
from scipy.optimize import least_squares
from scipy.optimize import minimize
from scipy.optimize import fmin
import matplotlib.pyplot as plt

xData = np.linspace(50,94,334);
yData = (xData-75)**2 + (np.random.random((334,))-.5)*600;

fun = lambda coef, x : coef[0] + coef[1]*x + coef[2]*x**2 ; #create a "lambda" function whatever that is that has a tuple for the polynomial coefficients in it
#function is y = coef0 + coef1*x + coef2*x^2 where y is lambda

funError = lambda coef, x, y: fun(coef,x) - y; #create a "lambda" function for the error between the real data y and the fit data y
#function is yError = y(coef,x) - yReal where yError is the lambda now
#expanded fully: yError = coef0 + coef1*x + coef2*x^2 - yReal

coef_init = (5,10,15); #initial coefficient guess
#coef0 is const (order 0)
#coef1 is order 1 coef
#coef2 is order 2 coef

coef = least_squares(funError,coef_init, args=(xData,yData) ); #calculate the polynomial coefficients to fit the data
yFit_lq = fun(coef.x,xData); #calc the guessed values 
plt.figure();
plt.scatter( xData , yData , 20 , "r" );
plt.scatter( xData , yFit_lq , 20 );
plt.title("Least Squares");
plt.show();

coef = minimize(funError,coef_init, args=(xData,yData),method="Nelder-Mead" ); #calculate the polynomial coefficients to fit the data
yFit_min = fun(coef.x,xData); #calc the guessed values 
plt.figure();
plt.scatter( xData , yData , 20 , "r" );
plt.scatter( xData , yFit_min , 20 );
plt.title("Minimize with Nelder-Mead");
plt.show();

coef = fmin(funError,coef_init, args=(xData,yData) ); #calculate the polynomial coefficients to fit the data
yFit_fmin = fun(coef.x,xData); #calc the guessed values 
plt.figure();
plt.scatter( xData , yData , 20 , "r" );
plt.scatter( xData , yFit_fmin , 20 );
plt.title("fmin, equiv to min. w/ neldy");
plt.show();

我以相同的方式调用least_squares,minimize和fmin,他们的页面只需要args =() . 我不确定在调用minim和fmin时出现的错误是“ValueError:用一个序列设置一个数组元素” . 当least_squares对格式化完全满意时会发生错误 .

我也希望避免过多的函数defs - 干净简单的lambda函数应该能够处理这个简单的情况 .

1 回答

  • 0

    least_squaresminimize 对目标函数有不同的要求 .

    least_squares希望你的函数返回一个向量 . docstring将此向量描述为"vector of residuals" . least_squares 获取此向量并对元素的平方求和,以形成最小化的实际目标函数 .

    minimize期望你的目标函数返回一个标量 . 它试图找到最小化函数标量输出的向量输入 .

    您可以通过修改现有函数来解决 minimize 的最小二乘优化问题,以便计算并返回平方残差的总和:

    def funError(coef, x, y):
        residuals = fun(coef,x) - y
        objective = (residuals**2).sum()
        return objective
    

    但是,该功能未设置为与 least_squares 一起使用 . 因此,您可以使用两个函数:

    def funError(coef, x, y):
        residuals = fun(coef,x) - y
        return residuals
    
    def funErrorSSR(coef, x, y):
        residuals = funError(coef, x, y)
        objective = (residuals**2).sum()
        return objective
    

    funErrorleast_squares 一起使用,将 funErrorSSRminimize (或 fmin )一起使用 .

相关问题