python - 用 scipy 拟合多条参数曲线

标签 python curve-fitting

我有一组(至少 3 条)曲线(xy 数据)。对于每条曲线,参数 E 和 T 是常数但不同。我正在搜索系数 a、n 和 m 以获得所有曲线的最佳拟合。

y= x/E + (a/n+1)*T^(n+1)*x^m

我尝试了 curve_fit,但我不知道如何将参数 E 和 T 放入 函数 f(参见 curve_fit 文档)。此外,我不确定我是否正确理解 xdata。 Doc says: M-length sequence or an (k,M)-shaped array for functions with 函数 k 个预测变量。什么是预测器? 由于 ydata 只有一维,我显然不能将多条曲线输入到例程中。

所以 curve_fit 可能是错误的方法,但我什至不知道搜索正确方法的魔法词。我不可能是第一个处理这个问题的人。

最佳答案

一种方法是使用 scipy.optimize.leastsq 代替(curve_fitleastsq 的便捷包装)。

一维堆叠x数据; y 数据也是如此。 3 个单独数据集的长度甚至无关紧要;我们称它们为 n1n2n3,因此您的新 xy将具有形状 (n1+n2+n3,)

在要优化的函数内,您可以根据需要拆分数据。它不会是最好的功能,但它可以工作:

def function(x, E, T, a, n, m):
    return x/E + (a/n+1)*T^(n+1)*x^m

def leastsq_function(params, *args):
    a = params[0]
    n = params[1]
    m = params[2]
    x = args[0]
    y = args[1]
    E = args[2]
    T = args[3]
    n1, n2 = args[2]

    yfit = np.empty(x.shape)
    yfit[:n1] = function(x[:n1], E[0], T[0], a, n, m)
    yfit[n1:n2] = function(x[n1:n2], E[1], T[1], a, n, m)
    yfit[n2:] = function(x[n2:], E[2], T[2], a, n, m)

    return y - yfit


params0 = [a0, n0, m0]
args = (x, y, (E0, E1, E2), (T0, T1, T2), (n1, n1+n2))
result = scipy.optimize.leastsq(leastsq_function, params0, args=args)

这个我没有测试过,但是原理是这样的。您现在将数据分成 3 个不同的调用要优化的函数中。

请注意,scipy.optimize.leastsq 只需要一个函数来返回您想要最小化的任何值,在这种情况下,您的实际 y 数据之间的差异和拟合函数数据。 leastsq 中实际重要的变量是您想要拟合的参数,而不是 xy 数据。后者作为额外参数与三个独立数据集的大小一起传递(我没有使用 n3,为了方便起见,我对 n1+n2 做了一些处理;请记住leastsq_function中的n1n2是局部变量,不是原来的。

因为这是一个很难拟合的函数(例如,它可能不会有一个平滑的导数),所以非常有必要

  • 提供良好的起始值(params0,所以所有的 ...0 值)。

  • 没有跨越多个数量级的数据或参数。一切越接近 1(几个数量级肯定没问题)越好。

关于python - 用 scipy 拟合多条参数曲线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26242979/

相关文章:

r - 使用变量作为 R 中的列名拟合 glm

python - x 和 y 坐标不确定的 python 线性拟合

python - 如何使用 python 将此 XML 文件转换为 CSV?

python - 我如何设置 Scrapy 来处理验证码

python - 如何使用numpy计算向量滚动窗口的相关系数?

python - 合并索引上的两个数据帧,去掉 key_0

python - 为什么二进制文字中需要前导 0,例如 '0b10101000'?

python - 二维的 Scipy curve_fit 不起作用 - 对象太深?

r - 散点图内核平滑: ksmooth() does not smooth my data at all

python - TypeError : Improper input: N=3 must not exceed M=1, 不确定我的尺寸有什么问题?