为何SciPy在最小化平方误差和均方根误差时返回不同解?
我正在使用scipy.optimize.minimize来拟合数据曲线。为此,我定义了一个目标函数,这个函数会根据我指定的输出返回平方误差的总和或者均方根误差。我认为这个指标不应该对找到的最小值产生重大影响,因为均方根误差应该会得到一个与平方误差相似的最小值,但事实并非如此(见附图)。为了确保最小值的差异不是由于最小化方法造成的,我手动将我的最小化方法定义为BFGS(这是最小化函数的三种默认方法之一)。需要注意的是,当我使用平方误差作为目标函数指标时,我收到了三个运行时警告,内容如下:
C:\Users\Admin\AppData\Local\Temp\ipykernel_33104\472201149.py:23: RuntimeWarning: overflow encountered in square
SSE = np.sum(np.abs(y - y_pred)**2)
C:\Users\Admin\AppData\Roaming\Python\Python39\site-packages\scipy\optimize_numdiff.py:576: RuntimeWarning: invalid value encountered in subtract
df = fun(x) - f0
C:\Users\Admin\AppData\Local\Temp\ipykernel_33104\472201149.py:23: RuntimeWarning: overflow encountered in square
SSE = np.sum(np.abs(y - y_pred)**2)
下面是我的代码示例。
import numpy as np
from scipy.optimize import minimize
# Generate data
A = -6.899 # Parameter 1 (scale)
B = 0.0221 # Parameter 2 (concavity)
C = 9.909 # Parameter 3 (intercept)
x = np.linspace(0, 100, 101) # A bunch of evenly spaced points
y = A*np.exp(B*x) + C
# Function to calculate SSE or RMSE between function and data
def loss_func(parameters, x, y):
A, B, C = parameters
y_pred = A*np.exp(B*x) + C
SSE = np.sum(np.abs(y - y_pred)**2)
RMSE = np.sqrt(SSE / len(y))
return RMSE # Change this to SSE or RMSE as desired
guess = [1, 1, 1]
# Optimize the function
sol = minimize(loss_func, guess, args=(x, y), method = 'BFGS', bounds=None, constraints=None)
print("Optimized parameters:", sol.x)
有没有人知道为什么我在调整参数时,使用不同的指标会导致目标函数的最小值不同?我希望能得到一些解释,说明我可能犯的错误、scipy.optimize.minimize中的细微差别,或者平方误差和均方根误差之间的差异,导致找到的最小值不同。
编辑:
在进一步调查我的最小化解决方案后,我发现当使用平方误差作为目标函数指标时,根本没有达到收敛。然而,使用均方根误差作为目标函数指标也会导致“成功:假”的消息。现在我的问题是,为什么我没有达到成功的解决方案,而使用均方根误差的结果却比使用平方误差更接近目标?
fun: 54279.23221060659
hess_inv: array([[ 9.99899697e-01, -1.00146569e-02, 2.07889631e-88],
[-1.00146569e-02, 1.00303413e-04, 2.07564554e-86],
[ 2.07889631e-88, 2.07564554e-86, 1.00000000e+00]])
jac: array([ 1668.19189453, 117747.58496094, 3464.14257812])
message: 'Desired error not necessarily achieved due to precision loss.'
nfev: 34
nit: 1
njev: 6
status: 2
success: False
x: array([ 0.98988469, -0.00994935, 1. ])
1 个回答
你一开始的猜测非常不准确。如果你设定A=B=C=1,那么当x等于100时,你预测的y值是exp(100)+1。我的计算器对此完全不买账。
对于同样的x值,你在和一个数据值进行比较,这个数据值是-6.899.exp(2.21)+9.909,结果是-52.98。
然后你把这个巨大的差值平方,再加上其他类似的差值。
如果你从初始猜测[0,0,0]开始,这两种方法都会得到你最初设定的A、B、C的值。
初始猜测和范围对你的最小化过程非常重要。不幸的是,这两者都和具体的问题有关。