【问题标题】:Getting completely wrong fit from python scipy.optimize.curve_fit从 python scipy.optimize.curve_fit 得到完全错误的拟合
【发布时间】:2014-02-22 02:08:42
【问题描述】:

更新:已解决! 它现在正在生成具有正确符号的参数,并且它们确实符合曲线。问题是定义 func(a,b,c,x) 但 curve_fit 需要先读取 x:func(x,a,b,c)。感谢大家的帮助!我今天和老板见面的时候会做定量分析:)

以下是一些新的配合:http://imgur.com/NHnzR2A

(我仍然收到运行时错误:

RuntimeWarning: overflow encountered in power
return a*(math.e**(b*(math.e**(c*x))))

)


谁能帮我弄清楚这段代码有什么问题?我是 scipy 的新手。 我试图用Gompertz equation 模拟细菌生长,但我的代码产生了一个完全错误的curve_fit。您可以在this imgur album 中看到我的真实数据、模型方程和此代码生成的拟合的图像 谢谢!


固定代码:

#!/usr/bin/python
from numpy import *
from scipy.optimize import curve_fit

values = numpy.asarray(values)  
y = values[:2000//5].astype(numpy.float)
y - y[0] #subtracting blank value
x = numpy.arange(len(y))*5

def Function(x,a,b,c):
  #a = upper asymptote
  #b = negative = x axis displacement
  #c = negative = growth rate
  return a*(math.e**(b*(math.e**(c*x))))

parameters, pcov = curve_fit(Function, x, y, p0=[0.1,-1300,-0.0077])

#Graph data and fit to compare
yaj = Function(  numpy.asarray(x), parameters[0], parameters[1], parameters[2] )
figure(1, figsize=(8.5,11))
subplot(211)
plot(x,y,'g-')
xlim(min(x),max(x))
ylim(min(y),max(y))
subplot(212)
plot(x,yaj,'r-')
xlim(min(x),max(x))
ylim(min(yaj),max(yaj))
savefig('tempgraph.pdf')

return parameters

【问题讨论】:

  • 它是一个非线性求解器,因此它对初始猜测本质上是敏感的。您是否尝试过做出更好的初始猜测?此外,如果您的模型参数变化超过几个数量级(例如a=0.0001, b=-20, c=40000000),那么您需要对事物进行规范化。否则,通过有限差分计算雅可比将非常不准确,并且解将无法正确收敛。此外,如果您可以在某处发布数据样本(例如 pastebin 等),这将有助于诊断问题(可能每 100 个样本或类似的东西,如果它非常大)。
  • 如何进行初步猜测?实际上,a、b 和 c 是未定义的。模型参数应该都是相同的数量级。它们的符号与预期值相反。
  • curve_fit 将初始猜测作为参数 (p0)。默认情况下,都是一个。如果a=1, b=1, c=1 与 a、b 和 c 的可能值相差甚远,那么您需要提供更合理的值。
  • 这是我的数据集之一:pastebin.com/YfJXaNB9
  • 来自docs:模型函数,f(x, ...)。它必须将自变量作为第一个参数,并将适合的参数作为单独的剩余参数。

标签: python numpy scipy curve-fitting data-fitting


【解决方案1】:

进口:

import numpy as np
import matplotlib.pyplot as plt
import scipy.optimize as opt

示例值:

values = np.array('0.400    0.400   0.397   0.395   0.396   0.394   0.392   0.390   0.395   0.393   0.392   0.392   0.390   0.388   0.390   0.388   0.385   0.383   0.388   0.387   0.387   0.387   0.385   0.386   0.387   0.379   0.379   0.378   0.375   0.376   0.374   0.373   0.372   0.368   0.373   0.370   0.371   0.370   0.370   0.370   0.367   0.368   0.368   0.365   0.365   0.366   0.364   0.361   0.361   0.356   0.355   0.357   0.354   0.353   0.350   0.351   0.353   0.355   0.350   0.354   0.352   0.351   0.348   0.348   0.347   0.345   0.346   0.343   0.348   0.346   0.344   0.343   0.342   0.341   0.346   0.346   0.345   0.343   0.348   0.345   0.346   0.342   0.344   0.344   0.340   0.341   0.345   0.345   0.343   0.339   0.343   0.344   0.343   0.346   0.344   0.344   0.345   0.347   0.344   0.344   0.338   0.340   0.343   0.340   0.342   0.336   0.334   0.336   0.337   0.338   0.338   0.343   0.342   0.342   0.336   0.334   0.336   0.330   0.325   0.324   0.323   0.319   0.323   0.322   0.318   0.314   0.314   0.319   0.315   0.316   0.313   0.315   0.314   0.314   0.315   0.313   0.308   0.312   0.311   0.310   0.312   0.311'
                  ' 0.311   0.309   0.309   0.316   0.317   0.312   0.309   0.311   0.308   0.310   0.312'.split('\t'), dtype=float)

旧数据准备:

x=[]
y=[]
x_val = 0
for i in values: #values is a list of several thousand experimental data points
  if x_val < 100:
    x.append(float(x_val))
    y.append(float(i))
  x_val += 5
x = np.asarray(x)
y = np.asarray(y)

更轻松的数据准备:

y1 = values[:100//5]
x1 = np.arange(len(y1))*5

检查是否相同:

print np.allclose(y, y1)
print np.allclose(x, x1)

使用numpy定义拟合函数:

def function(x, a,b,c):
    #a = upper asymptote
    #b = negative = x axis displacement
    #c = negative = growth rate
    return a*(np.exp(b*(np.exp(c*x))))

使用起点 p0 拟合:

pars, pcov = opt.curve_fit(function, x1, y1, p0=[0.1, -10, 0.1])

画:

yaj = function(x1, *pars)
plt.figure(1, figsize=(8.5, 11))
plt.plot(x1, y1, 'g-', x1, yaj, 'r-')
plt.xlim(min(x1), max(x1))
plt.ylim(min(y1), max(y1))
plt.show()

【讨论】:

  • 您好,感谢您的帮助!问题是我定义了 function(a,b,c,x) 而 x 必须首先出现,curve_fit 才能工作。
  • 是的,这就是我在评论中写的:-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-31
  • 2016-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-31
相关资源
最近更新 更多