假设我有 3 个具有实值的数据点 a、b、c。我有两个方程, b_mod = c1 * a_mod + c2 和 c_mod = c3 * a_mod + c4 ,其中 c1,c2,c3,c4 是实值
我们如何以最小的变化修改 a -> a_mod 、 b -> b_mod 、 c -> c_mod ,使其适合给定的方程?
我想不出解决这个问题的方法。任何帮助将不胜感激。
这是一个“线性最小二乘”问题。
这意味着约束方程是线性的,目标可以写为
minimise (a_mod - a)**2 + (b_mod -b)**2 + (c_mod - c)**2
。
在Python中可以使用numpy.linalg.lstsq来解决。 Numpy 是一个比较标准的 python 库。
从文档页面中,您可以看到函数
lstsq
解决了以下形式的问题:
minimise U**2
such that A U = B
其中
U
是要求解的向量,A
和 B
分别是维度一致的矩阵和向量。
但是,您的问题具有以下形式:
minimise (X - X0)**2
such that A' X = B'
哪里
X = (a_mod) X0 = (a) A' = (c1 -1 0) B' = (-c2)
(b_mod) (b) (c3 0 -1) (-c4)
(c_mod) (c)
这两个问题是等价的;只要让
U = X - X0
、A = A'
和 B = B' - A X0
。
这给了我们代码:
from numpy.linalg import lstsq
# minimise (a_mod - a)**2 + (b_mod - b)**2 + (c_mod - c)**2
# such that:
# c1 * a_mod - b_mod + 0 = -c2
# c3 * a_mod + 0 - c_mod = -c4
def fit_minimal(a, b, c, c1, c2, c3, c4):
A = np.array([[c1, -1, 0], [c3, 0, -1]])
B = np.array([-c2, -c4])
X0 = np.array([a, b, c])
U = lstsq(A, B - A @ X0)[0]
a_mod, b_mod, c_mod = U + X0
return (a_mod, b_mod, c_mod)