在Python中使用最小二乘麻烦

时间:2015-02-03 18:02:27

标签: python numpy least-squares

我正在开发一个分析数据的项目,并尝试使用最小二乘法(内置)来实现这一目标。我找到了一个提供代码作为示例的教程,它运行正常:

x = arange(0, 6e-2, 6e-2/30)
A, k, theta = 10, 1.0/3e-2, pi/6
y_true = A*sin(2*pi*k*x+theta)
y_meas = y_true+2*random.randn(len(x))

def residuals(p, y, x):
    A, k, theta = p
    print "A type" + str(type(A))
    print "k type" + str(type(k))
    print "theta type" + str(type(theta))
    print "x type" + str(type(x))
    err = y - A*sin(2*pi*k*x+theta)
    return err

def peval(x, p):
    return p[0]*sin(2*pi*p[1]*x+p[2])

p0 = [8,1/2.3e-2,pi/3]

plsq = leastsq(residuals, p0, args=(y_meas, x))
print(plsq[0])

然而,当我尝试将其转移到我自己的代码时,它会不断抛出错误。我已经研究了一段时间,并且设法消除了我早期困扰我的所有类型不匹配问题。据我所知,目前这两段代码几乎相同,但我收到了错误 '不支持的操作数类型'并且无法弄清楚下一步该做什么。以下是我的代码中与此问题相关的部分:

if (ls is not None):
        from scipy.optimize import leastsq
        p0 = [8, 1/2.3e-2,pi/3]
        def residuals(p, y, x):
            A,k,theta = p
            if (type(x) is list):
                x = asarray(x)
            err = y - A*sin(2*pi*k*x+theta) #Point of error
            return err
        def peval(x, p):
            return p[0]*sin(2*pi*p[1]*x+p[2])
        plsq = leastsq(residuals, p0, args=(listRelativeCount, listTime))
        plsq_0 = peval(listTime, plsq[0])

其中listTime是listRelativeCount中找到的数据的x值。我已经标记了代码当前失败的行。任何帮助将不胜感激,因为我已经坚持这个问题超过一个月。

1 个答案:

答案 0 :(得分:2)

您调用的行#Point of error中发生了三件事:您正在乘以值,添加值并应用sin()函数。 "不支持的操作数类型"意味着其中一个操作出错。这意味着您需要验证操作数的类型,并确保您知道正在应用的函数。

  • 您确定知道所有操作数的类型(和dtype s),包括ndarraypixtheta
  • 您确定使用的是哪个A功能吗? sinmath.sin不同,它们接受不同的操作数。
  • 通过标量多余的列表(如果您的np.sin变量确实是一个列表)与标量乘法和listTime完全不同。

如果不清楚哪个操作导致错误,请尝试分解表达式:

ndarray

这应该澄清什么操作会抛出异常。

这是为什么使用显式包名称(例如err1 = 2*pi*k err2 = err1*x err3 = err2 + theta err4 = sin(err3) err5 = A*err4 err = y - err5 而非np.sin())通常更好的主意。