用Python拟合参数曲线

7
我有一组实验数据,形式为(X,Y),以及一个理论模型,形式为(x(t;*params),y(t;*params)),其中t是一个物理(但不可观测)变量,*params是我想要确定的参数。 t是连续的变量,在模型中xt之间以及yt之间存在1:1的关系。
在一个完美的世界中,我将知道T(参数的真实世界值),并能够进行极其基本的最小二乘拟合,以找到*params的值。(请注意,我不是像3124300231464345中那样尝试“连接”我的绘图中xy的值。)我无法保证在我的真实数据中,潜在值T是单调的,因为我的数据是跨多个周期收集的。
我没有很多手动进行曲线拟合的经验,并且必须使用极其粗糙的方法,而且很难访问基本的scipy函数。我的基本方法包括:
  1. 选择一些*params的值并将其应用于模型
  2. 取一个t值的数组,并将其放入模型中,以创建一个model(*params) = (x(*params),y(*params))的数组
  3. X(数据值)插值到model中以获得Y_predicted
  4. YY_predicted之间运行最小二乘(或其他)比较
  5. 为新的一组*params再做一次
  6. 最终,选择最佳的*params

这种方法存在几个明显的问题。

1)我对编程经验不足,无法开发出很好的“再试一次”的方法,除了“尝试解决方案空间中的所有问题”,或者“在粗略网格中尝试所有内容”,然后“在粗略网格的热点中稍微细化网格并重新尝试所有内容”。我尝试过使用MCMC方法,但我从未找到任何最优值,主要是因为问题2

2)步骤2-4本身非常低效。

我尝试了类似以下的代码(伪代码;实际函数是虚构的)。在A、B上使用广播可能会有许多细微的争议,但这些问题不如需要为每个步骤插值的问题重要。
我认识的人推荐使用某种期望最大化算法,但我对此不够了解,无法从头开始编写一个。我真的希望有一些很棒的scipy(或其他开源)算法可以覆盖我的整个问题,但现在我并不抱有希望。
import numpy as np
import scipy as sci
from scipy import interpolate

X_data
Y_data

def x(t,A,B):
    return A**t + B**t
def y(t,A,B):
    return A*t + B

def interp(A,B):
    ts = np.arange(-10,10,0.1)
    xs = x(ts,A,B)
    ys = y(ts,A,B)
    f = interpolate.interp1d(xs,ys)
    return f

N = 101
lsqs = np.recarray((N**2),dtype=float)

count = 0
for i in range(0,N):
    A = 0.1*i            #checks A between 0 and 10
    for j in range(0,N):
        B = 10 + 0.1*j   #checks B between 10 and 20

        f = interp(A,B)
        y_fit = f(X_data)
        squares = np.sum((y_fit - Y_data)**2)

        lsqs[count] = (A,b,squares) #puts the values in place for comparison later
        count += 1        #allows us to move to the next cell

i = np.argmin(lsqs[:,2])

A_optimal = lsqs[i][0]
B_optimal = lsqs[i][1]

1
你应该查看 scipy.interpolate.splprep - rth
1
很不幸,这只对我的(X,Y)数据连接有用,而不能用于拟合以找到*params - Necarion
1个回答

0
如果我理解问题正确的话,params是每个样本中都相同的常量,但t会因样本而异。例如,您可能有一堆点,您认为这些点已从一个圆中采样。
x = a+r cos(t)   
y = b+r sin(t)

在不同的t值下。

在这种情况下,我会消除变量t,以得到xy之间的关系--在这种情况下,(x-a)^2+(y-b)^2 = r^2。如果您的数据完全符合模型,您将在每个数据点上都有(x-a)^2+(y-b)^2 = r^2。通过一些误差,您仍然可以找到(a,b,r)来最小化

sum_i ((x_i-a)^2 + (y_i-b)^2 - r^2)^2.

Mathematica的Eliminate命令可以自动化某些情况下消除t的过程。

PS:您可能会在stats.stackexchange、math.stackexchange或mathoverflow.net上做得更好。我知道最后一个网站有一个可怕的声誉,但我们真的不会咬人!


谢谢您的反馈。我正在尝试按照您的建议找到a和b的等效物。然而,这些方程并不总是能解析地求出t,即使它们能够解析求解,也会得到许多奇异点。当我保持它以“t”为条件时,我只有在“t=0”处有奇异点。然而,当我消除“t”时,我得到了一些看起来像下面这样的方程(为简单起见,取出了一些常数)y - x + c' = y/x + (y/(x-y))^(1/3)这意味着相对较小的“x”误差可能会压倒拟合过程。 - Necarion

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