Python: scipy.optimize.minimize fails with "ValueError: setting an array element with a sequence." when calling on a function with x and y args
Python: scipy.optimize.minimize fails with "ValueError: setting an array element with a sequence." when calling on a function with x and y args
如标题所述,scipy.optimize.minimize 在调用最小化时失败并返回 "ValueError: setting an array element with a sequence."。
我正在将 scipy.optimize.minimize 应用于使用变量 coef(我正在优化的系数)以及 xData 和 yData(数据变量)的函数。
我将在下面提供示例代码。通过搜索如何使用最小化,我知道错误源于被最小化的函数 returning 一个数组,而它应该 return 一个标量。不过,我不确定 为什么 它是 return 数组。
重要的是,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、最小化和 fmin,它们的页面只要求 args=()。我不确定在 least_squares 对格式非常满意时发生 "ValueError: setting an array element with a sequence." 错误时调用 minimize 和 fmin 出了什么问题。
我也希望避免过多的函数定义 - 干净简单的 lambda 函数应该能够处理这种简单的情况。
least_squares
和minimize
对objective函数的要求不同
least_squares
期望您的函数 return 一个向量。文档字符串将此向量描述为 "vector of residuals"。 least_squares
取此向量并对元素的平方求和以形成最小化的 actual objective 函数。
minimize
期望您的 objective 函数为 return 一个 标量 。它会尝试找到最小化函数标量输出的矢量输入。
您可以使用 minimize
解决最小二乘优化问题,方法是修改现有函数,使其计算 return 残差平方和:
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
将 funError
与 least_squares
结合使用,并将 funErrorSSR
与 minimize
(或 fmin
)结合使用。
如标题所述,scipy.optimize.minimize 在调用最小化时失败并返回 "ValueError: setting an array element with a sequence."。
我正在将 scipy.optimize.minimize 应用于使用变量 coef(我正在优化的系数)以及 xData 和 yData(数据变量)的函数。
我将在下面提供示例代码。通过搜索如何使用最小化,我知道错误源于被最小化的函数 returning 一个数组,而它应该 return 一个标量。不过,我不确定 为什么 它是 return 数组。
重要的是,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、最小化和 fmin,它们的页面只要求 args=()。我不确定在 least_squares 对格式非常满意时发生 "ValueError: setting an array element with a sequence." 错误时调用 minimize 和 fmin 出了什么问题。
我也希望避免过多的函数定义 - 干净简单的 lambda 函数应该能够处理这种简单的情况。
least_squares
和minimize
对objective函数的要求不同
least_squares
期望您的函数 return 一个向量。文档字符串将此向量描述为 "vector of residuals"。 least_squares
取此向量并对元素的平方求和以形成最小化的 actual objective 函数。
minimize
期望您的 objective 函数为 return 一个 标量 。它会尝试找到最小化函数标量输出的矢量输入。
您可以使用 minimize
解决最小二乘优化问题,方法是修改现有函数,使其计算 return 残差平方和:
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
将 funError
与 least_squares
结合使用,并将 funErrorSSR
与 minimize
(或 fmin
)结合使用。