Gab*_*iel 11 python numpy scipy confidence-interval
我试图获得一些指数适合某些x,y数据的置信区间(此处可用).这是MWE我必须找到最适合数据的指数:
from pylab import *
from scipy.optimize import curve_fit
# Read data.
x, y = np.loadtxt('exponential_data.dat', unpack=True)
def func(x, a, b, c):
'''Exponential 3-param function.'''
return a * np.exp(b * x) + c
# Find best fit.
popt, pcov = curve_fit(func, x, y)
print popt
# Plot data and best fit curve.
scatter(x, y)
x = linspace(11, 23, 100)
plot(x, func(x, *popt), c='r')
show()
Run Code Online (Sandbox Code Playgroud)
产生:

如何在这个拟合上获得95%(或其他一些值)的置信区间,最好使用pure python,numpy或者scipy(我已经安装过的软件包)?
加百列的答案不正确。在这里用红色表示GraphPad Prism计算出的他的数据的95%置信带:

背景:“拟合曲线的置信区间”通常称为置信带。对于95%的置信带,可以95%的置信度包含真实曲线。(这与上面以灰色显示的预测带不同。预测带与将来的数据点有关。有关更多详细信息,请参见例如GraphPad Curve Fitting Guide的本页。)
在Python中,kmpfit可以计算非线性最小二乘法的置信带。以下是加百列的例子:
from pylab import *
from kapteyn import kmpfit
x, y = np.loadtxt('_exp_fit.txt', unpack=True)
def model(p, x):
a, b, c = p
return a*np.exp(b*x)+c
f = kmpfit.simplefit(model, [.1, .1, .1], x, y)
print f.params
# confidence band
a, b, c = f.params
dfdp = [np.exp(b*x), a*x*np.exp(b*x), 1]
yhat, upper, lower = f.confidence_band(x, dfdp, 0.95, model)
scatter(x, y, marker='.', s=10, color='#0000ba')
ix = np.argsort(x)
for i, l in enumerate((upper, lower, yhat)):
plot(x[ix], l[ix], c='g' if i == 2 else 'r', lw=2)
show()
Run Code Online (Sandbox Code Playgroud)
的dfdp是偏导数?F /?模型的F P = A * E 1(B * X)+ C相对于每个参数p(即,A,B,和C)。有关背景,请参见kmpfit教程或GraphPad曲线拟合指南的本页。(与我的示例代码不同,kmpfit教程不使用confidence_band()库中的内容,而是使用其自己的实现,但略有不同)。
最后,Python图与Prism匹配:
您可以使用不确定性模块进行不确定性计算.
uncertainties跟踪不确定性和相关性.您可以uncertainties.ufloat直接从输出创建相关curve_fit.
能够对非内置操作进行计算,例如exp需要使用函数uncertainties.unumpy.
您还应该避免from pylab import *导入.这甚至会覆盖python内置函数,例如sum.
一个完整的例子:
import numpy as np
from scipy.optimize import curve_fit
import uncertainties as unc
import matplotlib.pyplot as plt
import uncertainties.unumpy as unp
def func(x, a, b, c):
'''Exponential 3-param function.'''
return a * np.exp(b * x) + c
x, y = np.genfromtxt('data.txt', unpack=True)
popt, pcov = curve_fit(func, x, y)
a, b, c = unc.correlated_values(popt, pcov)
# Plot data and best fit curve.
plt.scatter(x, y, s=3, linewidth=0, alpha=0.3)
px = np.linspace(11, 23, 100)
# use unumpy.exp
py = a * unp.exp(b * px) + c
nom = unp.nominal_values(py)
std = unp.std_devs(py)
# plot the nominal value
plt.plot(px, nom, c='r')
# And the 2sigma uncertaintie lines
plt.plot(px, nom - 2 * std, c='c')
plt.plot(px, nom + 2 * std, c='c')
plt.savefig('fit.png', dpi=300)
Run Code Online (Sandbox Code Playgroud)
注意:获得拟合曲线置信区间的实际答案由 Ulrich here给出。
经过一些研究(请参阅此处、此处和1.96),我想出了自己的解决方案。
它接受任意 X% 置信区间并绘制上下曲线。

这是 MWE:
from pylab import *
from scipy.optimize import curve_fit
from scipy import stats
def func(x, a, b, c):
'''Exponential 3-param function.'''
return a * np.exp(b * x) + c
# Read data.
x, y = np.loadtxt('exponential_data.dat', unpack=True)
# Define confidence interval.
ci = 0.95
# Convert to percentile point of the normal distribution.
# See: https://en.wikipedia.org/wiki/Standard_score
pp = (1. + ci) / 2.
# Convert to number of standard deviations.
nstd = stats.norm.ppf(pp)
print nstd
# Find best fit.
popt, pcov = curve_fit(func, x, y)
# Standard deviation errors on the parameters.
perr = np.sqrt(np.diag(pcov))
# Add nstd standard deviations to parameters to obtain the upper confidence
# interval.
popt_up = popt + nstd * perr
popt_dw = popt - nstd * perr
# Plot data and best fit curve.
scatter(x, y)
x = linspace(11, 23, 100)
plot(x, func(x, *popt), c='g', lw=2.)
plot(x, func(x, *popt_up), c='r', lw=2.)
plot(x, func(x, *popt_dw), c='r', lw=2.)
text(12, 0.5, '{}% confidence interval'.format(ci * 100.))
show()
Run Code Online (Sandbox Code Playgroud)