2

我有一组点。基本上,我有 P = f(t)。

比方说,我有 50 个测量值。P的50个值,时间的函数。这些价值观遵循既定规律。

我要做的就是找到规律中参数的值,仅此而已。基本上,我必须用最佳曲线拟合点。这是法律:

P = V.t - ((V - W)(1 - exp(-k.t)) / k)

我需要做的是找到 V、W 和 k 的数值。我有 t 和 P。你知道怎么做吗?

编辑:

这是我想要获得的截图:

在此处输入图像描述

图片上:

  • V 是 V
  • W 是 Vi
  • k 是 k

这就是我在 reptilicus 的帮助下得到的:

http://i.imgur.com/f59Eo29.png

import numpy as np
from scipy.optimize import curve_fit
from matplotlib.pyplot import *
import xlrd

def myFunc(t, V, W, k):

    y = V * t - ((V - W) * (1 - np.exp(-k * t)) / k)

    return y

classeur = xlrd.open_workbook(path)
names_sheets = classeur.sheet_names()

sheet = classeur.sheet_by_name(names_sheets[0])

row_start = 2

time = sheet.col_values(0, row_start)
fluo = feuille.col_values(4, row_start)

time = [ index for index in time if index ]
fluo = [ index for index in fluo if index ]

# this generates some fake data to fit. For youm just read in the 
# data in CSV or whatever you've
x = np.array(time)
y = np.array(fluo)

#fit the data, return the best fit parameters and the covariance matrix
#popt, pcov = curve_fit(myFunc, x, yn)
popt, pcov = curve_fit(myFunc, x, y)
print(popt)
print(pcov)

#plot the data
clf() #matplotlib
plot(x, y, "rs")
#overplot the best fit curve
plot(x, myFunc(x, popt[0], popt[1], popt[2]))
grid(True)
show()

不错。我设法提取了我的 excel 工作簿的数据,并绘制了它。但正如你所看到的,我得到了一个线性回归,这是我不想要的。我的目标是不重现他们在 Origin 8 中的匹配度。

编辑:

我有一些消息。我团队中最后一个这样做的人告诉我他是如何使用 Origin 的。事实上,他们也使用最小二乘法,但是他们找到了 chi 2 最小化的参数。该软件进行了一些迭代,并优化了参数。

编辑2:

因为我花了很长时间才弄清楚,我在这里分享我的研究结果。我面临的主要问题是我的价值观“太小”。事实上,我的 y 值大约是 10^-7。正如这里所解释的拟合曲线:为什么小数字更好?, 1 数量级的数字更适合拟合。

此外,至少在我的情况下,由于我的数据是这个顺序的,我不需要给出一些初始参数(默认情况下,它们设置为 1)。所以我只是“标准化”了我的价值观。例如,我将时间值从秒转换为小时,然后乘以 10^7 我的 y 值,其数量级为 10^-7。然后,我将获得的参数转换回所需的单位。这是我的代码:

import numpy as np
from scipy.optimize import curve_fit, leastsq
from matplotlib.pyplot import *

def myFunc(t, Vs, Vi, k):

    y = Vs * t - ((Vs - Vi) * (1 - np.exp(-k * t)) / k)

    return y

raw_x = some_input 
raw_y = some_input 

# scaling data
time = [ index /3600 for index in raw_x if index or index==0 ]
fluo = [ index*10**7 for index in raw_y if index or index==0 ]

x = np.array(temps)
y = np.array(fluo)

popt, pcov = curve_fit(myFunc, x, y, maxfev=3000)

# Good unities
popt2 = list()
popt2 = [ popt[0] / 3600 * 10**-7, popt[1] / 3600 * 10**-7, popt[2] / 3600 ]

#plot the data
clf() #matplotlib
plot(raw_x, raw_y, "rp")
plot(raw_x, myFunc(raw_x, popt2[0], popt2[1], popt2[2]), 'b')
grid(True)
show()

这是一张说明差异的图片:

http://i.imgur.com/YXkJG5j.png

蓝色图是使用通过单位重新缩放(并转换回良好单位)获得的参数的拟合曲线。绿色的是通过拟合原始单位获得的曲线。

感谢大家的帮助。

4

2 回答 2

6

只需curve_fit使用scipy.optimize

import numpy as np
from scipy.optimize import curve_fit
from pylab import *

def myFunc(t, V, W, k):
    y = V * t - ((V - W) * (1 - np.exp(-k * t)) / k)
    return y

# this generates some fake data to fit. For youm just read in the 
# data in CSV or whatever you've
x = np.linspace(0,4,50)
y = myFunc(x, 2.5, 1.3, 0.5)
# add some noise to the fake data to make it more realistic. . .
yn = y + 0.2*np.random.normal(size=len(x))

#fit the data, return the best fit parameters and the covariance matrix
popt, pcov = curve_fit(myFunc, x, yn)
print popt
print pcov

#plot the data
clf()
plot(x, yn, "rs")
#overplot the best fit curve
plot(x, myFunc(x, popt[0], popt[1], popt[2]))
grid(True)
show()

这给出了如下图所示的内容。红点是(噪声)数据,蓝线是最佳拟合曲线,具有以下特定数据的最佳拟合参数:

[ 2.32751132, 1.27686053, 0.65986596]

这非常接近 2.5、1.3、0.5 的预期参数。差异是由于我添加到假数据中的噪声。

适合的例子

于 2013-09-04T16:48:14.280 回答
0

Since you have more points than unknown coefficients, you'll want to do a least squares fit. This calculation will give you the coefficients that minimize the mean square error between the function and all the points.

So substitute your 50 points into the assumed equation and get 50 equations for 3 coefficients. This is easily expressed as a matrix:

Ax = b

where the unknown vector x are your coefficients.

Premultiply both sides by the transpose of A and solve using a matrix solver.

Start by plotting the data you have. The choice of equation you start with will make your job easier or harder. Are you certain about that leading term? If that wasn't appropriate, you could take the natural log of both sides and it's a simple linear equation. The leading term makes that harder to tease out the coefficient for k. It's a nonlinear solution in that case. Choose wisely.

于 2013-09-04T16:29:11.260 回答