【问题标题】:Trouble with least squares in PythonPython中的最小二乘问题
【发布时间】:2015-02-03 18:02:27
【问题描述】:

我正在从事一个分析数据的项目,并尝试使用最小二乘法(内置)来做到这一点。我找到了一个提供代码作为示例的教程,并且效果很好:

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 值。我已经标记了代码当前失败的行。任何帮助都将不胜感激,因为我已经在这个问题上停留了一个多月。

【问题讨论】:

  • listRelativeCount 是一个列表吗?
  • 能否请您包含完整的回溯?
  • 你能给出residualslistRelativeCountlistTime的样本数据吗?

标签: python numpy least-squares


【解决方案1】:

在您调用#Point of error 的行中发生了三件事:您正在乘以值、添加值并应用sin() 函数。 “不支持的操作数类型”表示这些操作之一有问题。这意味着您需要验证操作数的类型,并确保您知道正在应用什么函数。

  • 你确定你知道所有操作数的类型(和dtypes,对于ndarrays),包括pixthetaA
  • 您确定您使用的是哪个sin 函数吗? math.sinnp.sin 不同,它们接受不同的操作数。
  • 将列表乘以标量(如果您的 listTime 变量确实是列表)与将标量乘以 ndarray 完全不同。

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

err1 = 2*pi*k
err2 = err1*x
err3 = err2 +  theta
err4 = sin(err3)
err5 = A*err4
err = y - err5

这应该澄清什么操作引发了异常。

这是一个示例,说明为什么使用显式包名称通常是一个更好的主意,例如 np.sin() 而不是 sin()

【讨论】:

  • 我检查了我正在使用的所有数据的类型,x 是一个 ndarray,你看到的其他所有数据都是一个 numpy.float64 。我已经重试了确保明确使用 numpy sin 的代码,但我仍然得到相同的结果。回溯显示: 回溯(最近一次调用最后一次):文件“C:\Users\~~~~~~~~~~”,第 66 行,残差 err = y - Anp.sin(2* pik*x+theta) TypeError: unsupported operand type(s) for *: 'numpy.float64' and 'numpy.ndarray'edited for length
  • 接下来我会尝试,因为您有错误的行号,所以将表达式分解为单个操作表达式,并查看哪一行产生错误。我会相应地编辑答案。
  • 我把它分解成单独的表达式,它不喜欢将 x(一个 ndarray)乘以 k(一个 numpy.float64,但让我感到困惑的是示例中没有出现相同的错误而且我看不出它们两者之间有什么区别。在我看来,该示例似乎是在为 x 中的每个值重新计算 err。
  • 我接下来要看的地方是检查xk 的范围。例如,当您检查type(k) 时,它可能与函数所乘的k 不同。尝试两个简单的事情:尝试更改变量的名称,或尝试明确的 global 声明(如果您打算这样管理变量)。
  • 我已将所有变量设为全局变量,就像示例中一样,并将关联函数移到主函数之外,以便它们也具有全局范围。我仍然遇到同样的错误。
猜你喜欢
  • 1970-01-01
  • 2022-11-13
  • 2017-09-22
  • 2019-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 2021-09-15
相关资源
最近更新 更多