簡體   English   中英

指數曲線擬合的置信區間

[英]Confidence interval for exponential curve fit

我試圖獲得一些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()

產生:

在此輸入圖像描述

如何使用純pythonnumpyscipy (我已安裝的軟件包)獲得95%(或其他值)置信區間?

您可以使用不確定性模塊進行不確定性計算。 uncertainties跟蹤不確定性和相關性。 您可以直接從curve_fit的輸出創建相關的uncertainties.ufloat curve_fit

為了能夠對諸如exp類的非內置操作進行計算,您需要使用uncertainties.unumpy函數exp的函數。

您還應該避免from pylab import * import。 這甚至會覆蓋諸如sum類的python內置函數。

一個完整的例子:

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)

結果如下: 結果

注意 :獲得擬合曲線置信區間的實際答案由Ulrich 在此給出。


經過一些研究(見這里這里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()

加布里埃爾的回答是不正確的。 在這里用紅色顯示他的數據的95%置信區間,由GraphPad Prism計算: 棱鏡信心和預測帶

背景:“擬合曲線的置信區間”通常稱為置信帶 對於95%置信區間,可以95%確信它包含真實曲線。 (這與預測頻段不同,如上所示為灰色。預測頻段與未來數據點有關。有關詳細信息,請參閱,例如,GraphPad曲線擬合指南的此頁面 。)

在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()

dfdp是關於每個參數p(即a,b和c)的模型f = a * e ^(b * x)+ c的偏導數∂f/ dfdp 有關背景信息,請參閱“GraphPad曲線擬合指南”的kmpfit教程或此頁面 (與我的示例代碼不同,kmpfit教程不使用庫中的confidence_band() ,而是使用它自己的略有不同的實現。)

最后,Python圖與Prism圖匹配:

kmpfit信心樂隊

curve_fit()返回協方差矩陣 - pcov - 它保存估計的不確定性(1 sigma)。 這假設錯誤是正常分布的,這有時是有問題的。

你也可以考慮使用lmfit包(純python,建立在scipy之上),它提供了一個圍繞scipy.optimize擬合例程的包裝器(包括leastsq(),這是curve_fit()使用的),並且可以,除其他外,明確計算置信區間。

我一直是簡單引導的粉絲,以獲得置信區間。 如果你有n數據點,那么使用random軟件包從你的數據中選擇n個點進行重新映射(即允許你的程序多次獲得相同的點,如果這是它想做的 - 非常重要)。 完成后,繪制重新采樣點並獲得最佳擬合。 這樣做10,000次,每次都有新的生產線。 然后你的95%置信區間是包含95%最佳擬合線的一對線。

在Python中編程是一種非常簡單的方法,但從統計的角度來看,這有點不清楚。 有關您為什么要這樣做的更多信息可能會為您的任務帶來更合適的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM