scipy.optimize.minimize 找不到最小二乘解

scipy.optimize.minimize can't find least square solution

我的意图是按照 L1 norm instead of L2 norm for cost function in regression model 中的建议使用 scipy.optimize 解决 l1 误差拟合问题,但我一直得到错误的解决方案,所以我使用我们知道如何获得的最小二乘法进行调试封闭式表达式:

n=10
d=2
A = np.random.rand(n,d)
x = np.random.rand(d,1)
b = np.dot(A, x)
x_hat = np.linalg.lstsq(A, b)[0]
print(np.linalg.norm(np.dot(A, x_hat)-b))


def fit(X, params):
    return X.dot(params)

def cost_function(params, X, y):
    return np.linalg.norm(y - fit(X, params))

x0 = np.zeros((d,1))

output = minimize(cost_function, x0, args=(A, b))

y_hat = fit(A, output.x)
print(np.linalg.norm(y_hat-b))
print(output)

输出为:

4.726604209672303e-16
2.2714597315189407
      fun: 2.2714597315189407
 hess_inv: array([[ 0.19434496, -0.1424377 ],
       [-0.1424377 ,  0.16718703]])
      jac: array([ 3.57627869e-07, -2.98023224e-08])
  message: 'Optimization terminated successfully.'
     nfev: 32
      nit: 4
     njev: 8
   status: 0
  success: True
        x: array([0.372247  , 0.32633966])

这看起来超级奇怪,因为它甚至不能解决 l2 回归问题?我在这里犯了愚蠢的错误吗?

错误是由于形状不匹配造成的。 Minimizex0 和迭代具有 (n,) 的形状。因此,当 params 的形状为 (n,) 时,fit(X,params) 的形状为 (n,),而你的 y 的形状为 (n,1)。因此,由于 numpy 的隐式广播,表达式 y-fit(X,params) 的形状为 (n,n)。因此 np.linalg.norm returns frobenius 矩阵范数而不是欧氏向量范数。

解决方案:将成本函数更改为:

def cost_function(params, X, y):
    return np.linalg.norm(y - fit(X, params.reshape(d,1)))