我想用scipy.odr
执行多维ODR。我阅读了API文档,它说多维度是可能的,但我无法使其工作。我在互联网上找不到工作的例子,API真的很粗糙,没有提示如何继续。
这是我的MWE:
import numpy as np
import scipy.odr
def linfit(beta, x):
return beta[0]*x[:,0] + beta[1]*x[:,1] + beta[2]
n = 1000
t = np.linspace(0, 1, n)
x = np.full((n, 2), float('nan'))
x[:,0] = 2.5*np.sin(2*np.pi*6*t)+4
x[:,1] = 0.5*np.sin(2*np.pi*7*t + np.pi/3)+2
e = 0.25*np.random.randn(n)
y = 3*x[:,0] + 4*x[:,1] + 5 + e
print(x.shape)
print(y.shape)
linmod = scipy.odr.Model(linfit)
data = scipy.odr.Data(x, y)
odrfit = scipy.odr.ODR(data, linmod, beta0=[1., 1., 1.])
odrres = odrfit.run()
odrres.pprint()
它引发了以下异常:
scipy.odr.odrpack.odr_error: number of observations do not match
这似乎与我的矩阵形状有关,但我不知道如何正确塑造它。有谁知道吗?
答案 0 :(得分:4)
首先,根据我的经验,scipy.odr主要使用数组,而不是矩阵。该库似乎在整个过程中进行了大量的大小检查,并使其与多个变量一起工作似乎非常麻烦。
这是我通常工作的工作流程(至少在python 2.7上工作):
import numpy as np
import scipy.odr
n = 1000
t = np.linspace(0, 1, n)
def linfit(beta, x):
return beta[0]*x[0] + beta[1]*x[1] + beta[2] #notice changed indices for x
x1 = 2.5*np.sin(2*np.pi*6*t)+4
x2 = 0.5*np.sin(2*np.pi*7*t + np.pi/3)+2
x = np.row_stack( (x1, x2) ) #odr doesn't seem to work with column_stack
e = 0.25*np.random.randn(n)
y = 3*x[0] + 4*x[1] + 5 + e #indices changed
linmod = scipy.odr.Model(linfit)
data = scipy.odr.Data(x, y)
odrfit = scipy.odr.ODR(data, linmod, beta0=[1., 1., 1.])
odrres = odrfit.run()
odrres.pprint()
因此,使用相同的(1D?)数组,使用row_stack和单个索引号的地址似乎可行。