scipy的指数衰减仅给出阶跃函数 [英] exponential decay with scipy just gives step function

查看:64
本文介绍了scipy的指数衰减仅给出阶跃函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对一组数据进行指数拟合:

 将matplotlib.pyplot导入为plt将numpy导入为np导入scipy.optimize为optdef func(x,a,b,c):返回* np.exp(x/-b)+ cepr_data = np.loadtxt('T2_text',skiprows = 1)时间= epr_data [:, 1]强度= epr_data [:, 2]优化参数,pcov = opt.curve_fit(功能,时间,强度)打印(optimizedParameters)plt.plot(时间,强度,函数(时间,* optimizedParameters),标签=适合")plt.show() 

但是我只是得到了这一步功能和这些参数:

[1.88476367e + 05 1.00000000e + 00 6.49563230e + 03]

具有"fit"的地块

以及此错误消息:

  OptimizeWarning:无法估计参数的协方差warnings.warn('无法估计参数的协方差' 

 将matplotlib.pyplot导入为plt将numpy导入为np导入scipy.optimize为optdef func(x,a,b,c):返回* np.exp(x/-b)+ cepr_data = np.loadtxt('T2_text',skiprows = 1)时间= epr_data [:, 1]强度= epr_data [:, 2]c0 = np.mean(强度[-10:])a0 =强度[0] -c0th =时间[np.searchsorted(-intensity + c0,-0.5 * a0)]b0 = th/np.log(2)优化参数,pcov = opt.curve_fit(函数,时间,强度,p0 =(a0,b0,c0))打印(optimizedParameters)plt.plot(时间,强度,标签='数据')plt.plot(时间,函数(时间,* optimizedParameters),标签=适合")plt.legend()plt.show() 

解决方案

首先,修复您的 plot 函数调用.要一次调用绘制两条曲线,必须为每条曲线给出 x y 值:

  plt.plot(时间,强度,时间,func(时间,* optimizedParameters),label ="fit") 

对于标签,两次调用 plot 可能更简单:

  plt.plot(时间,强度,标签=数据")plt.plot(时间,函数(时间,* optimizedParameters),标签=适合") 

如果我们拥有您的数据,则更容易解决由 curve_fit 生成的警告.但是经验表明,很有可能 curve_fit 使用的参数的默认初始猜测(全为1)只是一个非常糟糕的猜测.

尝试通过为其数值优化例程提供更好的起点来帮助 curve_fit .以下代码显示了如何计算 a b c 的粗略猜测.将这些参数传递给参数 p0 =(a0,b0,c0) curve_fit .

 #假设时间序列足够长,以至于尾部#已变平为大约c附近的随机噪声.c0 = np.mean(强度[-10:])#假设时间[0]为0.a0 =强度[0]-c0#半衰期的粗略猜测.th =时间[np.searchsorted(-intensity + c0,-0.5 * a0)]b0 = th/np.log(2) 

I'm trying to do an exponential fit with a set of data:

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


def func(x, a, b, c):
    return a * np.exp(x / -b) + c


epr_data = np.loadtxt('T2_text', skiprows=1)

time = epr_data[:, 1]
intensity = epr_data[:, 2]


optimizedParameters, pcov = opt.curve_fit(func, time, intensity)
print(optimizedParameters)
plt.plot(time, intensity, func(time, *optimizedParameters), label="fit")

plt.show()

but i just get this step function and these parameters:

[1.88476367e+05 1.00000000e+00 6.49563230e+03]

the plot with "fit"

as well as this error message:

OptimizeWarning: Covariance of the parameters could not be estimated
  warnings.warn('Covariance of the parameters could not be estimated'

EDIT:

https://pastebin.com/GTTGf0ed

i want to plot the time and first row with intensity

the graph after your suggestion

edit 2:

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


def func(x, a, b, c):
    return a * np.exp(x / -b) + c


epr_data = np.loadtxt('T2_text', skiprows=1)

time = epr_data[:, 1]
intensity = epr_data[:, 2]

c0 = np.mean(intensity[-10:])
a0 = intensity[0]-c0
th = time[np.searchsorted(-intensity+c0, -0.5*a0)]
b0 = th / np.log(2)

optimizedParameters, pcov = opt.curve_fit(func, time, intensity, p0=(a0, b0, c0))
print(optimizedParameters)
plt.plot(time, intensity, label='data')
plt.plot(time, func(time, *optimizedParameters), label="fit")
plt.legend()

plt.show()

解决方案

First, fix your plot function call. To plot two curves with one call, you have to give the x and y values for each curve:

plt.plot(time, intensity, time, func(time, *optimizedParameters), label="fit")

For labeling, it might be simpler to call plot twice:

plt.plot(time, intensity, label="data")
plt.plot(time, func(time, *optimizedParameters), label="fit")

It would be easier to address the warning generated by curve_fit if we had your data. Experience shows, however, that it is most likely that the default initial guess of the parameters used by curve_fit (which is all 1s) is just a really bad guess.

Try helping curve_fit by giving it a better starting point for its numerical optimization routine. The following bit of code shows how you can compute rough guesses for a, b and c. Pass these to curve_fit with the argument p0=(a0, b0, c0).

# Assume that the time series is long enough that the tail
# has flattened out to approximately random noise around c.
c0 = np.mean(intensity[-10:])

# This assumes time[0] is 0.
a0 = intensity[0] - c0

# Rough guess of the half-life.
th = time[np.searchsorted(-intensity+c0, -0.5*a0)]
b0 = th / np.log(2)

这篇关于scipy的指数衰减仅给出阶跃函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆