循环以最小化 python 中的数组函数
Loops to minimize function of arrays in python
我有一些大数组,每个数组都有 i 个元素,称它们为 X、Y、Z,为此我需要找到一些值 a、b——其中 a 和 b 是 0 到 1 之间的实数——这样即,对于以下功能,
r = X - a*Y - b*Z
r_av = Sum(r)/i
rms = Sum((r - r_av)^2), summing over the i pixels
我想最小化均方根。基本上我希望最小化 r 中的散点,因此需要找到正确的 a 和 b 来做到这一点。到目前为止,我一直想通过以下两种方式之一在嵌套循环中执行此操作:1) 只是循环遍历可能的 a、b 范围,然后选择最小的 rms,或者 2) 插入一个 while 语句,以便循环将例如,一旦 rms 停止随着 a、b 的减小而减小,则终止。这是这些的一些伪代码:
1) List
for a = 1
for b = 1
calculate m
b = b - .001
a = a - .001
loop 1000 times
sort m values, from smallest
print (a,b) corresponding to smallest m
2) Terminate
for a = 1
for b = 1
calculate m
while m > previous step,
b = b - .001
a = a - .001
其中之一更可取吗?或者还有另一种更好的方法来解决这个问题吗?任何提示将非常感谢。
已经有一个 handy formula 用于最小二乘拟合。
我想出了两种不同的方法来解决你的问题。
对于第一个,考虑矩阵K
:
L = len(X)
K = np.identity(L) - np.ones((L, L)) / L
在您的例子中,A
和 B
定义为:
A = K.dot(np.array([Y, Z]).transpose())
B = K.dot(np.array([X]).transpose())
应用公式找到使误差最小化的 C A * C - B
:
C = np.linalg.inv(np.transpose(A).dot(A))
C = C.dot(np.transpose(A)).dot(B)
那么结果是:
a, b = C.reshape(2)
此外,请注意 numpy 已经提供了 linalg.lstsq 做完全相同的事情:
a, b = np.linalg.lstsq(A, B)[0].reshape(2)
更简单的方法是将 A 定义为:
A = np.array([Y, Z, [1]*len(X)]).transpose()
然后根据X
求解得到系数和平均值:
a, b, mean = np.linalg.lstsq(A, X)[0]
如果您需要此结果的证明,请查看 this post。
示例:
>>> import numpy as np
>>> X = [5, 7, 9, 5]
>>> Y = [2, 0, 4, 1]
>>> Z = [7, 2, 4, 6]
>>> A = np.array([Y, Z, [1] * len(X)]).transpose()
>>> a, b, mean = np.linalg.lstsq(A, X)[0]
>>> print(a, b, mean)
0.860082304527 -0.736625514403 8.49382716049
我有一些大数组,每个数组都有 i 个元素,称它们为 X、Y、Z,为此我需要找到一些值 a、b——其中 a 和 b 是 0 到 1 之间的实数——这样即,对于以下功能,
r = X - a*Y - b*Z
r_av = Sum(r)/i
rms = Sum((r - r_av)^2), summing over the i pixels
我想最小化均方根。基本上我希望最小化 r 中的散点,因此需要找到正确的 a 和 b 来做到这一点。到目前为止,我一直想通过以下两种方式之一在嵌套循环中执行此操作:1) 只是循环遍历可能的 a、b 范围,然后选择最小的 rms,或者 2) 插入一个 while 语句,以便循环将例如,一旦 rms 停止随着 a、b 的减小而减小,则终止。这是这些的一些伪代码:
1) List
for a = 1
for b = 1
calculate m
b = b - .001
a = a - .001
loop 1000 times
sort m values, from smallest
print (a,b) corresponding to smallest m
2) Terminate
for a = 1
for b = 1
calculate m
while m > previous step,
b = b - .001
a = a - .001
其中之一更可取吗?或者还有另一种更好的方法来解决这个问题吗?任何提示将非常感谢。
已经有一个 handy formula 用于最小二乘拟合。
我想出了两种不同的方法来解决你的问题。
对于第一个,考虑矩阵K
:
L = len(X)
K = np.identity(L) - np.ones((L, L)) / L
在您的例子中,A
和 B
定义为:
A = K.dot(np.array([Y, Z]).transpose())
B = K.dot(np.array([X]).transpose())
应用公式找到使误差最小化的 C A * C - B
:
C = np.linalg.inv(np.transpose(A).dot(A))
C = C.dot(np.transpose(A)).dot(B)
那么结果是:
a, b = C.reshape(2)
此外,请注意 numpy 已经提供了 linalg.lstsq 做完全相同的事情:
a, b = np.linalg.lstsq(A, B)[0].reshape(2)
更简单的方法是将 A 定义为:
A = np.array([Y, Z, [1]*len(X)]).transpose()
然后根据X
求解得到系数和平均值:
a, b, mean = np.linalg.lstsq(A, X)[0]
如果您需要此结果的证明,请查看 this post。
示例:
>>> import numpy as np
>>> X = [5, 7, 9, 5]
>>> Y = [2, 0, 4, 1]
>>> Z = [7, 2, 4, 6]
>>> A = np.array([Y, Z, [1] * len(X)]).transpose()
>>> a, b, mean = np.linalg.lstsq(A, X)[0]
>>> print(a, b, mean)
0.860082304527 -0.736625514403 8.49382716049