使用Python进行二维拟合

3
我需要拟合一个函数。
z(u,v) = C u v^p

也就是说,我有一个二维数据集,需要找到两个参数C和p。在numpy或scipy中是否有可以直接完成此任务的函数呢?我查看了scipy.optimize.leastsq,但我不清楚该如何在这里使用它。

2个回答

6
def f(x,u,v,z_data):
  C = x[0]
  p = x[1]
  modelled_z = C*u*v**p
  diffs = modelled_z - z_data
  return diffs.flatten() # it expects a 1D array out. 
       # it doesn't matter that it's conceptually 2D, provided flatten it consistently

result = scipy.optimize.leastsq(f,[1.0,1.0], # initial guess at starting point
                        args = (u,v,z_data) # alternatively you can do this with closure variables in f if you like
                              )
# result is the best fit point

针对您的具体功能,您可能能够更好地完成它 - 例如,对于任何给定的p值,可以通过简单的线性代数确定一个最佳的C值。


几个问题:1)u,v组成一个二维网格。我有每个u,v对应的数据点。难道我不需要像np.outer(u,v ** p)这样的东西吗?2)我很惊讶“modelled_z”是“args”的第三个参数。我不需要在那里使用“observed_z”或类似的东西吗?谢谢。 - bob.sacamento
使用np.outer()函数可以正常工作,因此我接受这个答案。 - bob.sacamento
1
modelled_zz_data之间的区别是我的错误 - 我已经更正了。np.outer实际上取决于如何存储uv。我可能会将u定义为m by 1,将v定义为1 by n,这样就可以按照我编写的方式工作。我假设您已将它们定义为一维数组,在这种情况下,使用np.outer很好。 - DavidW

1
你可以将问题转化为一个简单的线性最小二乘问题,这样你就不需要使用leastsq()了。
z[i] == C * u[i] * v[i]**p

变成了

z[i]/u[i] == C * v[i]**p

然后

log(z[i]/u[i]) == log(C) + p * log(v[i])

更改变量,您可以将其作为简单的线性问题解决:

Z[i] == L + p * V[i]

使用numpy,假设您的数据存储在数组zuv中,渲染结果如下:
Z = log(z/u)
V = log(v)
p, L = np.polyfit(V, Z, 1)
C = exp(L)

你可能需要在代码中加入 try:except: 来处理一些 u 值为零或负数的情况。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接