Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 3.x Python3,scipy.optimize:使模型适合多个数据集_Python 3.x_Lmfit_Scipy Optimize - Fatal编程技术网

Python 3.x Python3,scipy.optimize:使模型适合多个数据集

Python 3.x Python3,scipy.optimize:使模型适合多个数据集,python-3.x,lmfit,scipy-optimize,Python 3.x,Lmfit,Scipy Optimize,我有一个模型定义为: m(x,z)=C1*x^2*sin(z)+C2*x^3*cos(z) 对于不同的z(z=1,z=2,z=3),我有多个数据集,其中m(x,z)是x的函数 所有z值的参数C1和C2必须相同 因此,我必须同时将我的模型拟合到三个数据集,否则,对于不同的z值,我将有不同的C1和C2值 这可以通过scipy.optimize实现。 我可以只对z的一个值进行计算,但不知道如何对所有z进行计算 首先,我写下: def my_function(x,C1,C1): z=1 retu

我有一个模型定义为:

m(x,z)=C1*x^2*sin(z)+C2*x^3*cos(z)

对于不同的z(z=1,z=2,z=3),我有多个数据集,其中m(x,z)是x的函数

所有z值的参数C1和C2必须相同

因此,我必须同时将我的模型拟合到三个数据集,否则,对于不同的z值,我将有不同的C1和C2值

这可以通过scipy.optimize实现。 我可以只对z的一个值进行计算,但不知道如何对所有z进行计算

首先,我写下:

def my_function(x,C1,C1):
    z=1
return C1*x**2*np.sin(z)+ C2*x**3*np.cos(z)


data = 'some/path/for/data/z=1'

x= data[:,0]
y= data[:,1]

from lmfit import Model

gmodel = Model(my_function)
result = gmodel.fit(y, x=x, C1=1.1)

print(result.fit_report())

如何对多组数据(即不同的z值)进行拟合?

因此,您要做的是对数据进行多维拟合(在您的情况下为二维拟合);这样,对于整个数据集,您可以得到一组最能描述您的数据的C参数。我认为最好的方法是使用
scipy.optimize.curve\u fit()

因此,您的代码如下所示:

import scipy.optimize as optimize
import numpy as np

def my_function(xz, *par):
    """ Here xz is a 2D array, so in the form [x, z] using your variables, and *par is an array of arguments (C1, C2) in your case """
    x = xz[:,0]
    z = xz[:,1]
    return par[0] * x**2 * np.sin(z) + par[1] * x**3 * np.cos(z)

# generate fake data. You will presumable have this already
x = np.linspace(0, 10, 100)
z = np.linspace(0, 3, 100)
xx, zz = np.meshgrid(x, z) 
xz = np.array([xx.flatten(), zz.flatten()]).T
fakeDataCoefficients = [4, 6.5]
fakeData = my_function(xz, *fakeDataCoefficients) + np.random.uniform(-0.5, 0.5, xx.size)

# Fit the fake data and return the set of coefficients that jointly fit the x and z
# points (and will hopefully be the same as the fakeDataCoefficients
popt, _ = optimize.curve_fit(my_function, xz, fakeData, p0=fakeDataCoefficients)

# Print the results
print(popt)
import lmfit
import numpy as np
# define the model function for each dataset 
def my_function(x, c1, c2, z=1): 
    return C1*x**2*np.sin(z)+ C2*x**3*np.cos(z)

# Then write an objective function like this
def f2min(params, x, data2d, zlist):
    ndata, npts = data2d.shape
    residual = 0.0*data2d[:]
    for i in range(ndata):
        c1 = params['c1_%d' % (i+1)].value
        c2 = params['c2_%d' % (i+1)].value
        residual[i,:] = data[i,:] - my_function(x, c1, c2, z=zlist[i])
    return residual.flatten()

# now build that `data2d`, `zlist` and build the `Parameters`
data2d = []
zlist = []
x = None
for fname in dataset_names:
    d = np.loadtxt(fname)  # or however you read / generate data
    if x is None: x = d[:, 0]
    data2d.append(d[:, 1])
    zlist.append(z_for_dataset(fname)) # or however ...

data2d = np.array(data2d)  # turn list into nd array
ndata, npts = data2d.shape
params = lmfit.Parameters()
for i in range(ndata):
    params.add('c1_%d' % (i+1), value=1.0) # give a better starting value!
    params.add('c2_%d' % (i+1), value=1.0) # give a better starting value!

# now you're ready to do the fit and print out the results:
result = lmfit.minimize(f2min, params, args=(x, data2d, zlist))
print(results.fit_report())
当我进行这种拟合时,我精确地得到了我用来生成函数的
fakedatacoverties
,因此拟合效果很好


因此得出的结论是,您没有独立进行3次拟合,每次都设置
z
的值,而是进行2D拟合,同时取
x
z
的值,以找到最佳系数

您的代码不完整,并且有一些语法错误

但我认为您需要构建一个模型,将不同数据集的模型连接起来,然后将连接的数据拟合到该模型中。在
lmfit
(披露:作者和维护者)的上下文中,我经常发现使用
minimize()
和多数据集拟合的目标函数比使用
模型
类更容易。也许从这样的事情开始:

import scipy.optimize as optimize
import numpy as np

def my_function(xz, *par):
    """ Here xz is a 2D array, so in the form [x, z] using your variables, and *par is an array of arguments (C1, C2) in your case """
    x = xz[:,0]
    z = xz[:,1]
    return par[0] * x**2 * np.sin(z) + par[1] * x**3 * np.cos(z)

# generate fake data. You will presumable have this already
x = np.linspace(0, 10, 100)
z = np.linspace(0, 3, 100)
xx, zz = np.meshgrid(x, z) 
xz = np.array([xx.flatten(), zz.flatten()]).T
fakeDataCoefficients = [4, 6.5]
fakeData = my_function(xz, *fakeDataCoefficients) + np.random.uniform(-0.5, 0.5, xx.size)

# Fit the fake data and return the set of coefficients that jointly fit the x and z
# points (and will hopefully be the same as the fakeDataCoefficients
popt, _ = optimize.curve_fit(my_function, xz, fakeData, p0=fakeDataCoefficients)

# Print the results
print(popt)
import lmfit
import numpy as np
# define the model function for each dataset 
def my_function(x, c1, c2, z=1): 
    return C1*x**2*np.sin(z)+ C2*x**3*np.cos(z)

# Then write an objective function like this
def f2min(params, x, data2d, zlist):
    ndata, npts = data2d.shape
    residual = 0.0*data2d[:]
    for i in range(ndata):
        c1 = params['c1_%d' % (i+1)].value
        c2 = params['c2_%d' % (i+1)].value
        residual[i,:] = data[i,:] - my_function(x, c1, c2, z=zlist[i])
    return residual.flatten()

# now build that `data2d`, `zlist` and build the `Parameters`
data2d = []
zlist = []
x = None
for fname in dataset_names:
    d = np.loadtxt(fname)  # or however you read / generate data
    if x is None: x = d[:, 0]
    data2d.append(d[:, 1])
    zlist.append(z_for_dataset(fname)) # or however ...

data2d = np.array(data2d)  # turn list into nd array
ndata, npts = data2d.shape
params = lmfit.Parameters()
for i in range(ndata):
    params.add('c1_%d' % (i+1), value=1.0) # give a better starting value!
    params.add('c2_%d' % (i+1), value=1.0) # give a better starting value!

# now you're ready to do the fit and print out the results:
result = lmfit.minimize(f2min, params, args=(x, data2d, zlist))
print(results.fit_report())

这个代码真的是一个草图,都是未经测试的,但是希望能给你一个很好的开始基础。

@ MeNeWeld:为什么你喜欢MimeSimple(),而不是模型?FITE()?@ WeSTR,试着把这个例子写成模型。它必须考虑多个数据集,每个数据集都有自己的参数集。对2个数据集执行此操作,然后对10个数据集执行此操作。相比之下,在目标函数中对N个数据集求和很容易。