同时拟合python参数共享

同时拟合python参数共享,python,curve-fitting,least-squares,data-fitting,Python,Curve Fitting,Least Squares,Data Fitting,我有六个数据集,我希望同时拟合所有六个数据集,六个数据集之间有两个共同参数,一个单独拟合 我计划将一个简单的ax**2+bx+c多项式拟合到数据集,其中a和b在六个数据集之间共享,偏移量c在六个数据集之间不共享 因此,我在数据集之间拟合一个公共斜率,但偏移量可变 我完全有能力单独拟合它们,但是由于每个数据集之间的斜率相似,使用同步拟合,偏移量c上的误差将大大改善 我通常使用scipy.optmize.curve_拟合 import numpy as np from scipy.optimize

我有六个数据集,我希望同时拟合所有六个数据集,六个数据集之间有两个共同参数,一个单独拟合

我计划将一个简单的ax**2+bx+c多项式拟合到数据集,其中a和b在六个数据集之间共享,偏移量c在六个数据集之间不共享

因此,我在数据集之间拟合一个公共斜率,但偏移量可变

我完全有能力单独拟合它们,但是由于每个数据集之间的斜率相似,使用同步拟合,偏移量c上的误差将大大改善

我通常使用scipy.optmize.curve_拟合

import numpy as np
from scipy.optimize import curve_fit

def func(x,a,b,c):
    return (a*(x**2)+b*x+c)
def fit(x,y,yerr):
    popt, pcov = curve_fit(func,x,y,p0=[-0.6,5,-12],sigma=yerr)
    chi=np.sum( ((func(x, *popt) - y) / yerr)**2)
    redchi=(chi-1)/len(y)
    return popt,pcov,redchi,len(y)
我处理6套:x,XER,y,YER len(x)和len(y)对于每一组都是不同的

我知道我必须连接数据集并以这种方式进行拟合


如果有人能提供任何建议或帮助,我相信这对我和社区都是有益的。

一种可能是更改要安装的函数,以便每个数据集都有自己的“a”和“b”参数,并带有一个公共的“c”,类似于下面这个粗糙的代码片段:

def func(x,a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6, c):
    if x in data_set_1:
        return (a1*(x**2)+b1*x+c)
    if x in data_set_2:
        return (a2*(x**2)+b2*x+c)
    if x in data_set_3:
        return (a3*(x**2)+b3*x+c)
    if x in data_set_4:
        return (a4*(x**2)+b4*x+c)
    if x in data_set_5:
        return (a5*(x**2)+b5*x+c)
    if x in data_set_6:
        return (a6*(x**2)+b6*x+c)
    raise Exception('Data outside fitting range') # just in case

一种可能性是更改要安装的函数,以便每个数据集都有自己的“a”和“b”参数,带有一个公共的“c”,类似于此原始代码段:

def func(x,a1,b1,a2,b2,a3,b3,a4,b4,a5,b5,a6,b6, c):
    if x in data_set_1:
        return (a1*(x**2)+b1*x+c)
    if x in data_set_2:
        return (a2*(x**2)+b2*x+c)
    if x in data_set_3:
        return (a3*(x**2)+b3*x+c)
    if x in data_set_4:
        return (a4*(x**2)+b4*x+c)
    if x in data_set_5:
        return (a5*(x**2)+b5*x+c)
    if x in data_set_6:
        return (a6*(x**2)+b6*x+c)
    raise Exception('Data outside fitting range') # just in case

因为我有类似的拟合问题,所以我决定处理这种情况。所以我很抱歉无耻地提出我自己的方案,但我认为这将对你非常有帮助。它包装了曲线拟合,但提供了一个符号界面,使事情更容易

您的问题可以这样解决:

查看文档了解更多信息:

p、 为了对参数进行初始猜测,每个
参数
对象都带有一个
属性,该属性保存初始猜测。例如,
a.value=-0.6

编辑:
以前需要一些额外的解决方法,这解释了下面的一些讨论。但是,我现在发布了一个新的
symfit
版本,上面的代码按预期运行。

因为我有类似的安装问题,我决定处理这种情况。所以我很抱歉无耻地提出我自己的方案,但我认为这将对你非常有帮助。它包装了曲线拟合,但提供了一个符号界面,使事情更容易

您的问题可以这样解决:

查看文档了解更多信息:

p、 为了对参数进行初始猜测,每个
参数
对象都带有一个
属性,该属性保存初始猜测。例如,
a.value=-0.6

编辑:
以前需要一些额外的解决方法,这解释了下面的一些讨论。但是,我现在发布了一个新的
symfit
版本,上面的代码按预期运行。

感谢所有的建议,我似乎找到了一种方法,可以同时将a、b和c1、c2、c3、c4、c5、c6作为参数进行拟合,其中a和b是共享的

下面是我最后使用的代码:

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

x=[vt,bt,ut,w1t,m2t,w2t]
y=[vmag,bmag,umag,w1mag,m2mag,w2mag]
xerr=[vterr,uterr,bterr,w1terr,m2terr,w2terr]
yerr=[vmagerr,umagerr,bmagerr,w1magerr,m2magerr,w2magerr]

def poly(x_, a, b, c1, c2, c3, c4, c5, c6):
    #all this is just to split x_data into the original parts of x
    l= len(x[0])
    l1= len(x[1])
    l2= len(x[2])
    l3= len(x[3])
    l4= len(x[4])
    l5= len(x[5])
    s=l+l1
    s1=l2+s
    s2=l3+s1
    s3=l4+s2
    s4=l5+s3


    a= np.hstack([
a*x_[:l]**2 + b*x_[:l] +c1,
a*x_[l:(s)]**2 + b*x_[l:(s)] +c2,
a*x_[(s):(s1)]**2 + b*x_[(s):(s1)] +c3,
a*x_[(s1):(s2)]**2 + b*x_[(s1):(s2)] +c4,
a*x_[(s2):(s3)]**2 + b*x_[(s2):(s3)] +c5,
a*x_[(s3):(s4)]**2 + b*x_[(s3):(s4)] +c6
])       
    print a
    return a 
x_data = np.hstack([x[0],x[1],x[2],x[3],x[4],x[5]])
y_data = np.hstack([y[0],y[1],y[2],y[3],y[4],y[5]])

(a, b, c1, c2, c3, c4, c5, c6), _ = curve_fit(poly, x_data, y_data)
如果这是糟糕的编码,我道歉!我的方法很粗糙!然而,它确实做得很好

下面是我的结果


感谢所有的建议,我似乎找到了一种方法来同时拟合它们,将a、b和c1、c2、c3、c4、c5、c6作为参数,其中a和b是共享的

下面是我最后使用的代码:

import matplotlib.pyplot as plt
import numpy as np
from scipy.optimize import curve_fit

x=[vt,bt,ut,w1t,m2t,w2t]
y=[vmag,bmag,umag,w1mag,m2mag,w2mag]
xerr=[vterr,uterr,bterr,w1terr,m2terr,w2terr]
yerr=[vmagerr,umagerr,bmagerr,w1magerr,m2magerr,w2magerr]

def poly(x_, a, b, c1, c2, c3, c4, c5, c6):
    #all this is just to split x_data into the original parts of x
    l= len(x[0])
    l1= len(x[1])
    l2= len(x[2])
    l3= len(x[3])
    l4= len(x[4])
    l5= len(x[5])
    s=l+l1
    s1=l2+s
    s2=l3+s1
    s3=l4+s2
    s4=l5+s3


    a= np.hstack([
a*x_[:l]**2 + b*x_[:l] +c1,
a*x_[l:(s)]**2 + b*x_[l:(s)] +c2,
a*x_[(s):(s1)]**2 + b*x_[(s):(s1)] +c3,
a*x_[(s1):(s2)]**2 + b*x_[(s1):(s2)] +c4,
a*x_[(s2):(s3)]**2 + b*x_[(s2):(s3)] +c5,
a*x_[(s3):(s4)]**2 + b*x_[(s3):(s4)] +c6
])       
    print a
    return a 
x_data = np.hstack([x[0],x[1],x[2],x[3],x[4],x[5]])
y_data = np.hstack([y[0],y[1],y[2],y[3],y[4],y[5]])

(a, b, c1, c2, c3, c4, c5, c6), _ = curve_fit(poly, x_data, y_data)
如果这是糟糕的编码,我道歉!我的方法很粗糙!然而,它确实做得很好

下面是我的结果


这是一个Python问题还是一个数学问题?你是说你将有六个
c
(比如
c_1
c_6
)的值,并且
a
b
各有一个值,这样数据集_i的模型将是
a*x**2+b*x+c_i
,a和b在所有6个数据集中都是相同的拟合值,而c将有6个拟合值。@Laurent LAPORTE,目前主要是python的问题。是否有适合共享参数的方法?你能把数据集放在一个矩阵中同时拟合它们吗?我不知道如何用
scipy.curve\u fit
来做这件事,但我可以写一个简单的两染色体遗传算法来做,这是Python问题还是数学问题?你是说你将有六个
c
(说
CU1
CU6
a
b
各有一个值,这样数据集_i的模型将是
a*x**2+b*x+c_i
?@inspectorG4dget是的,所有6个数据集的a和b都是相同的拟合值,并且将有6个c的拟合值。@Laurent LAPORTE,这目前主要是python的问题。有什么方法适合sh吗ared参数?你能将数据集放在一个矩阵中同时拟合它们吗?我不知道如何使用
scipy.curve\u fit
,但我可以编写一个简单的两染色体遗传算法来实现这一点。我已经检查了你的python包,它看起来非常整洁!我会看看我将来是否也能使用它:-!)!对于“Fit”函数:我给出了x1、x2、x3中的数据集。。y1,y2,y3。。但是,似乎每个数组的大小都需要相同,否则我会得到经典的“操作数不能与形状(25,)(46,)一起广播”。配件的形状是否需要相同?谢谢。很高兴你喜欢它!如果我的工作做得正确,它们就不必是同样大小的。您确定您的
x\u i
y\u i
sigma\u y\u i
具有相同的形状吗?在模型的每个组件中,它们必须具有相同的形状。如果是,您可以尝试手动调用模型,如下所示:
fit.model([此处的数据]、a=-0.6、b=5、c_1=12等)
。这应该单独评估模型的每个组件,并且这个调用应该