为何SciPy在最小化平方误差和均方根误差时返回不同解?

1 投票
1 回答
58 浏览
提问于 2025-04-12 12:09

我正在使用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 个回答

2

你一开始的猜测非常不准确。如果你设定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的值。

初始猜测和范围对你的最小化过程非常重要。不幸的是,这两者都和具体的问题有关。

撰写回答