使用 python 中的 Optimize.leastsq 方法获取拟合参数的标准误差

2023-11-24

我有一组数据(位移与时间),我使用 optimization.leastsq 方法将其拟合到几个方程中。我现在正在寻找拟合参数的误差值。查看文档,输出的矩阵是雅可比矩阵,我必须将其乘以残差矩阵才能得到我的值。不幸的是,我不是统计学家,所以我有点被术语淹没了。

据我了解,我需要的是与我的拟合参数相匹配的协方差矩阵,因此我可以对对角线元素求平方根,以获得拟合参数的标准误差。我有一个模糊的记忆,读到协方差矩阵是 optimize.leastsq 方法的输出。它是否正确?如果不是,你将如何获得残差矩阵,将输出的雅可比行列式乘以得到我的协方差矩阵?

任何帮助将不胜感激。我对 python 很陌生,因此如果问题是一个基本问题,我深表歉意。

拟合代码如下:

fitfunc = lambda p, t: p[0]+p[1]*np.log(t-p[2])+ p[3]*t # Target function'

errfunc = lambda p, t, y: (fitfunc(p, t) - y)# Distance to the target function

p0 = [ 1,1,1,1] # Initial guess for the parameters


  out = optimize.leastsq(errfunc, p0[:], args=(t, disp,), full_output=1)

args t 和 disp 是时间和位移值的数组(基本上只有 2 列数据)。我已经在代码顶部导入了所需的所有内容。输出提供的拟合值和矩阵如下:

[  7.53847074e-07   1.84931494e-08   3.25102795e+01  -3.28882437e-11]

[[  3.29326356e-01  -7.43957919e-02   8.02246944e+07   2.64522183e-04]
 [ -7.43957919e-02   1.70872763e-02  -1.76477289e+07  -6.35825520e-05]
 [  8.02246944e+07  -1.76477289e+07   2.51023348e+16   5.87705672e+04]
 [  2.64522183e-04  -6.35825520e-05   5.87705672e+04   2.70249488e-07]]

无论如何,我怀疑目前的契合度还有些可疑。当我能够排除错误时,这一点将得到确认。


更新于 4/6/2016

在大多数情况下,获得拟合参数的正确错误可能很微妙。

让我们考虑拟合一个函数y=f(x)您有一组数据点(x_i, y_i, yerr_i), where i是一个遍历每个数据点的索引。

在大多数物理测量中,误差yerr_i是测量设备或程序的系统不确定度,因此可以将其视为不依赖于的常数i.

使用哪个拟合函数,如何获取参数误差?

The optimize.leastsq方法将返回分数协方差矩阵。将该矩阵的所有元素乘以残差方差(即减少的卡方)并取对角线元素的平方根,即可估算出拟合参数的标准差。我已将执行此操作的代码包含在下面的函数之一中。

另一方面,如果你使用optimize.curvefit,上述过程的第一部分(乘以减少的卡方)是在幕后为您完成的。然后,您需要取协方差矩阵对角线元素的平方根,以获得拟合参数标准差的估计值。

此外,optimize.curvefit提供可选参数来处理更一般的情况,其中yerr_i每个数据点的值都不同。来自文档:

sigma : None or M-length sequence, optional
    If not None, the uncertainties in the ydata array. These are used as
    weights in the least-squares problem
    i.e. minimising ``np.sum( ((f(xdata, *popt) - ydata) / sigma)**2 )``
    If None, the uncertainties are assumed to be 1.

absolute_sigma : bool, optional
    If False, `sigma` denotes relative weights of the data points.
    The returned covariance matrix `pcov` is based on *estimated*
    errors in the data, and is not affected by the overall
    magnitude of the values in `sigma`. Only the relative
    magnitudes of the `sigma` values matter.

我如何确定我的错误是正确的?

确定拟合参数中标准误差的正确估计是一个复杂的统计问题。协方差矩阵的结果,由以下方法实现optimize.curvefit and optimize.leastsq实际上依赖于关于误差概率分布和参数之间相互作用的假设;可能存在的相互作用,具体取决于您的特定拟合函数f(x).

在我看来,处理复杂问题的最好方法是f(x)是使用 bootstrap 方法,该方法概述于这个链接.

让我们看一些例子

首先,一些样板代码。让我们定义一个波浪线函数并生成一些带有随机误差的数据。我们将生成一个具有较小随机误差的数据集。

import numpy as np
from scipy import optimize
import random

def f( x, p0, p1, p2):
    return p0*x + 0.4*np.sin(p1*x) + p2

def ff(x, p):
    return f(x, *p)

# These are the true parameters
p0 = 1.0
p1 = 40
p2 = 2.0

# These are initial guesses for fits:
pstart = [
    p0 + random.random(),
    p1 + 5.*random.random(), 
    p2 + random.random()
]

%matplotlib inline
import matplotlib.pyplot as plt
xvals = np.linspace(0., 1, 120)
yvals = f(xvals, p0, p1, p2)

# Generate data with a bit of randomness
# (the noise-less function that underlies the data is shown as a blue line)

xdata = np.array(xvals)
np.random.seed(42)
err_stdev = 0.2
yvals_err =  np.random.normal(0., err_stdev, len(xdata))
ydata = f(xdata, p0, p1, p2) + yvals_err

plt.plot(xvals, yvals)
plt.plot(xdata, ydata, 'o', mfc='None')

fig01

现在,让我们使用各种可用的方法来拟合该函数:

`优化.leastsq`

def fit_leastsq(p0, datax, datay, function):

    errfunc = lambda p, x, y: function(x,p) - y

    pfit, pcov, infodict, errmsg, success = \
        optimize.leastsq(errfunc, p0, args=(datax, datay), \
                          full_output=1, epsfcn=0.0001)

    if (len(datay) > len(p0)) and pcov is not None:
        s_sq = (errfunc(pfit, datax, datay)**2).sum()/(len(datay)-len(p0))
        pcov = pcov * s_sq
    else:
        pcov = np.inf

    error = [] 
    for i in range(len(pfit)):
        try:
          error.append(np.absolute(pcov[i][i])**0.5)
        except:
          error.append( 0.00 )
    pfit_leastsq = pfit
    perr_leastsq = np.array(error) 
    return pfit_leastsq, perr_leastsq 

pfit, perr = fit_leastsq(pstart, xdata, ydata, ff)

print("\n# Fit parameters and parameter errors from lestsq method :")
print("pfit = ", pfit)
print("perr = ", perr)


# Fit parameters and parameter errors from lestsq method :
pfit =  [  1.04951642  39.98832634   1.95947613]
perr =  [ 0.0584024   0.10597135  0.03376631]


`优化.curve_fit`

def fit_curvefit(p0, datax, datay, function, yerr=err_stdev, **kwargs):
    """
    Note: As per the current documentation (Scipy V1.1.0), sigma (yerr) must be:
        None or M-length sequence or MxM array, optional
    Therefore, replace:
        err_stdev = 0.2
    With:
        err_stdev = [0.2 for item in xdata]
    Or similar, to create an M-length sequence for this example.
    """
    pfit, pcov = \
         optimize.curve_fit(f,datax,datay,p0=p0,\
                            sigma=yerr, epsfcn=0.0001, **kwargs)
    error = [] 
    for i in range(len(pfit)):
        try:
          error.append(np.absolute(pcov[i][i])**0.5)
        except:
          error.append( 0.00 )
    pfit_curvefit = pfit
    perr_curvefit = np.array(error)
    return pfit_curvefit, perr_curvefit 

pfit, perr = fit_curvefit(pstart, xdata, ydata, ff)

print("\n# Fit parameters and parameter errors from curve_fit method :")
print("pfit = ", pfit)
print("perr = ", perr)


# Fit parameters and parameter errors from curve_fit method :
pfit =  [  1.04951642  39.98832634   1.95947613]
perr =  [ 0.0584024   0.10597135  0.03376631]


`引导程序`

def fit_bootstrap(p0, datax, datay, function, yerr_systematic=0.0):

    errfunc = lambda p, x, y: function(x,p) - y

    # Fit first time
    pfit, perr = optimize.leastsq(errfunc, p0, args=(datax, datay), full_output=0)


    # Get the stdev of the residuals
    residuals = errfunc(pfit, datax, datay)
    sigma_res = np.std(residuals)

    sigma_err_total = np.sqrt(sigma_res**2 + yerr_systematic**2)

    # 100 random data sets are generated and fitted
    ps = []
    for i in range(100):

        randomDelta = np.random.normal(0., sigma_err_total, len(datay))
        randomdataY = datay + randomDelta

        randomfit, randomcov = \
            optimize.leastsq(errfunc, p0, args=(datax, randomdataY),\
                             full_output=0)

        ps.append(randomfit) 

    ps = np.array(ps)
    mean_pfit = np.mean(ps,0)

    # You can choose the confidence interval that you want for your
    # parameter estimates: 
    Nsigma = 1. # 1sigma gets approximately the same as methods above
                # 1sigma corresponds to 68.3% confidence interval
                # 2sigma corresponds to 95.44% confidence interval
    err_pfit = Nsigma * np.std(ps,0) 

    pfit_bootstrap = mean_pfit
    perr_bootstrap = err_pfit
    return pfit_bootstrap, perr_bootstrap 

pfit, perr = fit_bootstrap(pstart, xdata, ydata, ff)

print("\n# Fit parameters and parameter errors from bootstrap method :")
print("pfit = ", pfit)
print("perr = ", perr)


# Fit parameters and parameter errors from bootstrap method :
pfit =  [  1.05058465  39.96530055   1.96074046]
perr =  [ 0.06462981  0.1118803   0.03544364]


观察结果

我们已经开始看到一些有趣的事情,所有三种方法的参数和误差估计几乎一致。那很好!

现在,假设我们想告诉拟合函数,我们的数据中存在一些其他不确定性,也许是系统不确定性,它会产生额外误差,其误差是err_stdev。那是a lot事实上,如果我们模拟一些带有这种错误的数据,它会看起来像这样:

enter image description here

在这种水平的噪声下,我们当然没有希望恢复拟合参数。

首先,让我们意识到leastsq甚至不允许我们输入这个新的系统错误信息。让我们看看是什么curve_fit当我们告诉它错误时:

pfit, perr = fit_curvefit(pstart, xdata, ydata, ff, yerr=20*err_stdev)

print("\nFit parameters and parameter errors from curve_fit method (20x error) :")
print("pfit = ", pfit)
print("perr = ", perr)


Fit parameters and parameter errors from curve_fit method (20x error) :
pfit =  [  1.04951642  39.98832633   1.95947613]
perr =  [ 0.0584024   0.10597135  0.03376631]

什么??这肯定是错误的!

这曾经是故事的结局,但最近curve_fit添加了absolute_sigma可选参数:

pfit, perr = fit_curvefit(pstart, xdata, ydata, ff, yerr=20*err_stdev, absolute_sigma=True)

print("\n# Fit parameters and parameter errors from curve_fit method (20x error, absolute_sigma) :")
print("pfit = ", pfit)
print("perr = ", perr)


# Fit parameters and parameter errors from curve_fit method (20x error, absolute_sigma) :
pfit =  [  1.04951642  39.98832633   1.95947613]
perr =  [ 1.25570187  2.27847504  0.72600466]

这稍微好一些,但仍然有点可疑。curve_fit认为我们可以拟合出该噪声信号,误差水平为 10%p1范围。让我们看看是什么bootstrap不得不说:

pfit, perr = fit_bootstrap(pstart, xdata, ydata, ff, yerr_systematic=20.0)

print("\nFit parameters and parameter errors from bootstrap method (20x error):")
print("pfit = ", pfit)
print("perr = ", perr)


Fit parameters and parameter errors from bootstrap method (20x error):
pfit =  [  2.54029171e-02   3.84313695e+01   2.55729825e+00]
perr =  [  6.41602813  13.22283345   3.6629705 ]

啊,这也许是对拟合参数误差的更好估计。bootstrap认为它知道p1大约有 34% 的不确定性。

概括

optimize.leastsq and optimize.curvefit为我们提供了一种估计拟合参数误差的方法,但我们不能在不质疑它们的情况下就使用这些方法。这bootstrap是一种使用蛮力的统计方法,在我看来,它在可能难以解释的情况下往往效果更好。

我强烈建议您查看一个特定问题并尝试curvefit and bootstrap。如果它们相似,那么curvefit计算成本要便宜得多,因此可能值得使用。如果它们差异很大,那么我的钱将花在bootstrap.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 python 中的 Optimize.leastsq 方法获取拟合参数的标准误差 的相关文章

  • Python:在列表理解本身中引用列表理解?

    这个想法刚刚出现在我的脑海中 假设您出于某种原因想要通过 Python 中的列表理解来获取列表的唯一元素 i if i in created comprehension else 0 for i in 1 2 1 2 3 1 2 0 0 3
  • SQLAlchemy 通过关联对象声明式多对多自连接

    我有一个用户表和一个朋友表 它将用户映射到其他用户 因为每个用户可以有很多朋友 这个关系显然是对称的 如果用户A是用户B的朋友 那么用户B也是用户A的朋友 我只存储这个关系一次 除了两个用户 ID 之外 Friends 表还有其他字段 因此
  • 为 Anaconda Python 安装 psycopg2

    我有 Anaconda Python 3 4 但是每当我运行旧代码时 我都会通过输入 source activate python2 切换到 Anaconda Python 2 7 我的问题是我为 Anaconda Python 3 4 安
  • PyUSB 1.0:NotImplementedError:此平台不支持或未实现操作

    我刚刚开始使用 pyusb 基本上我正在玩示例代码here https github com walac pyusb blob master docs tutorial rst 我使用的是 Windows 7 64 位 并从以下地址下载 z
  • 测试 python Counter 是否包含在另一个 Counter 中

    如何测试是否是pythonCounter https docs python org 2 library collections html collections Counter is 包含在另一个中使用以下定义 柜台a包含在计数器中b当且
  • 基于代理的模拟:性能问题:Python vs NetLogo & Repast

    我正在 Python 3 中复制一小段 Sugarscape 代理模拟模型 我发现我的代码的性能比 NetLogo 慢约 3 倍 这可能是我的代码的问题 还是Python的固有限制 显然 这只是代码的一个片段 但 Python 却花费了三分
  • Python pickle:腌制对象不等于源对象

    我认为这是预期的行为 但想检查一下 也许找出原因 因为我所做的研究结果是空白 我有一个函数可以提取数据 创建自定义类的新实例 然后将其附加到列表中 该类仅包含变量 然后 我使用协议 2 作为二进制文件将该列表腌制到文件中 稍后我重新运行脚本
  • OpenCV 无法从 MacBook Pro iSight 捕获

    几天后 我无法再从 opencv 应用程序内部打开我的 iSight 相机 cap cv2 VideoCapture 0 返回 并且cap isOpened 回报true 然而 cap grab 刚刚返回false 有任何想法吗 示例代码
  • 如何使用 OpencV 从 Firebase 读取图像?

    有没有使用 OpenCV 从 Firebase 读取图像的想法 或者我必须先下载图片 然后从本地文件夹执行 cv imread 功能 有什么办法我可以使用cv imread link of picture from firebase 您可以
  • 如何在Python中获取葡萄牙语字符?

    我正在研究葡萄牙语 角色看起来很奇怪 我怎样才能解决这个问题 代码 import feedparser import random Vou definir os feeds feeds conf feedurl http pplware s
  • 在Python中获取文件描述符的位置

    比如说 我有一个原始数字文件描述符 我需要根据它获取文件中的当前位置 import os psutil some code that works with file lp lib open path to file p psutil Pro
  • 在f字符串中转义字符[重复]

    这个问题在这里已经有答案了 我遇到了以下问题f string gt gt gt a hello how to print hello gt gt gt f a a gt gt gt f a File
  • Pandas:merge_asof() 对多行求和/不重复

    我正在处理两个数据集 每个数据集具有不同的关联日期 我想合并它们 但因为日期不完全匹配 我相信merge asof 是最好的方法 然而 有两件事发生merge asof 不理想的 数字重复 数字丢失 以下代码是一个示例 df a pd Da
  • 将图像分割成多个网格

    我使用下面的代码将图像分割成网格的 20 个相等的部分 import cv2 im cv2 imread apple jpg im cv2 resize im 1000 500 imgwidth im shape 0 imgheight i
  • 向 Altair 图表添加背景实心填充

    I like Altair a lot for making graphs in Python As a tribute I wanted to regenerate the Economist graph s in Mistakes we
  • 如何在seaborn displot中使用hist_kws

    我想在同一图中用不同的颜色绘制直方图和 kde 线 我想为直方图设置绿色 为 kde 线设置蓝色 我设法弄清楚使用 line kws 来更改 kde 线条颜色 但 hist kws 不适用于显示 我尝试过使用 histplot 但我无法为
  • 对年龄列进行分组/分类

    我有一个数据框说df有一个柱子 Ages gt gt gt df Age 0 22 1 38 2 26 3 35 4 35 5 1 6 54 我想对这个年龄段进行分组并创建一个像这样的新专栏 If age gt 0 age lt 2 the
  • 类型错误:预期单个张量时的张量列表 - 将 const 与 tf.random_normal 一起使用时

    我有以下 TensorFlow 代码 tf constant tf random normal time step batch size 1 1 我正进入 状态TypeError List of Tensors when single Te
  • 发送用户注册密码,django-allauth

    我在 django 应用程序上使用 django alluth 进行身份验证 注册 我需要创建一个自定义注册表单 其中只有一个字段 电子邮件 密码将在服务器上生成 这是我创建的表格 from django import forms from
  • 从列表指向字典变量

    假设你有一个清单 a 3 4 1 我想用这些信息来指向字典 b 3 4 1 现在 我需要的是一个常规 看到该值后 在 b 的位置内读写一个值 我不喜欢复制变量 我想直接改变变量b的内容 假设b是一个嵌套字典 你可以这样做 reduce di

随机推荐

  • 使用 C# winform 的 Zeromq pub/sub 示例

    我正在尝试创建一个在发布 订阅模型中使用 ZeroMQ clrzmq net 绑定 x86 通过 nuget 的 C Winform 应用程序 经过大量搜索 我只能找到独立的 C 示例 其中代码使用 while 语句无限期地处理新消息 当我
  • 是否可以借用结构体的一部分作为可变的而其他部分作为不可变的?

    如果结构体的字段是私有的 是否可以借用结构体的一部分作为可变的 而另一部分作为不可变的 fn main let mut ecs EntityComponentSystem new for e id in ecs get entities w
  • 使用 cqlsh 复制非常大的 cassandra 表时出现 PicklingError

    当我尝试使用以下命令将表复制到 cassandra 时 copy images from images csv 我收到错误 PicklingError Can t pickle
  • 编译器优化能否消除在 for 循环条件中重复调用的函数?

    我正在阅读有关哈希函数的内容 我是一名中级计算机科学学生 并发现了这一点 int hash const string key int tableSize int hasVal 0 for int i 0 i lt key length i
  • 如何向用户授予 SSRS 浏览器对文件夹的权限,而不授予他们访问根目录的权限

    当用户浏览到 http ssrs server reports 时 除非他们拥有根文件夹的浏览器权限 否则他们的访问会被拒绝 如果他们在文件夹 Dept 1 Reports 上有浏览器 则他们可以成功浏览到 http ssrs server
  • MVC5 Razor html.dropdownlistfor 当值在数组中时设置选择

    我正在使用 C 和 NET Framework 4 6 1 开发 ASP NET MVC 5 应用程序 我有这个View model MyProject Web API Models AggregationLevelConfViewMode
  • 如何递归解压嵌套的 ZIP 文件?

    假设嵌套 ZIP 文件深处有一个秘密文件 即 zip 文件内的 zip 文件内的 zip 文件 等等 zip 文件的名称为1 zip 2 zip 3 zip etc 我们不知道 zip 文件嵌套的深度 但可能有数千个 循环遍历所有文件直到最
  • 在 Sails.js 中处理数据库环境配置

    我遇到的问题与以下引用有关官方文档 注意 如果模型使用了与适配器的任何连接 则与该适配器的所有连接都将加载到 sails lift 上 无论模型是否实际使用它们 在上面的示例中 如果模型配置为使用 localMysql 连接 则 local
  • 将远程 github 存储库的更改合并到本地存储库

    我前段时间在 github 上分叉了一个存储库 做了一个小更改并将更改推回我的 github 分叉 此后原始存储库已更改 我想将原始存储库中的更改合并到我的分支中 我对 git 和 github 都很陌生 我需要具体的命令来操作 git r
  • 为什么 apt-get 功能在 Mac OS X v10.9 (Mavericks) 的终端中不起作用?

    我当时正在看this 正如您所看到的 我被告知要输入的第一个命令是 sudo apt get install python setuptools 当我这样做时 它输出 sudo apt get command not found 我不知道为
  • -I GCC 中的标志(Linux)

    我找到了一个带有 Makefile 的源文件包 我浏览了它 在 CFLAG 变量中 有一个 FLAG I 我在网上搜索过 但找不到它实际的作用 它与 C 文件中包含的库文件有关吗 stdio h unistd h pthread h 请指出
  • Javascript 获取对象属性名称

    我传递了以下对象 var myVar typeA option1 one option2 two 我希望能够拔出钥匙typeA从上面的结构来看 这个值每次都会改变 所以下次它可能会改变typeB 所以我想知道是否有办法让我做类似以下伪代码的
  • LibGDX 中的 AssetManager

    我正在尝试使用AssetManagerLibGDX 中的类 我了解它是如何工作的 但我正在尝试实现一个加载屏幕 我已遵循AssetManagerTest java file here 但我很难弄清楚如何让它正常工作 有人能指出我正确的方向吗
  • 是否可以更改 ToolStripMenuItem 工具提示字体?

    我有一个动态填充的 ContextMenuStrip 其中每个 ToolStripMenuItem 都有一个工具提示的格式化文本 而且 为了使该文本对用户有意义 我必须使用等宽字体 例如 Courier New 默认字体是常规的非等宽字体
  • 当字段为空时,远程属性不会触发

    我在用着RemoteAttribute对于我表单上的特定字段 其目的并不重要 重要的是 每当字段发生更改时 它都需要触发验证操作 这对我来说工作得很好 除非该字段更改为空白 我用谷歌搜索过这个但没有找到结果 有谁知道如果RemoteAttr
  • 带有 lapply 的内部 S3 泛型

    我有一个 S3 通用函数 我希望将其作为包的内部部分 如果可能的话我宁愿不导出它 一个有趣的缺点是 似乎lapply无法找到或使用正确的 S3 方法 有谁知道这种行为背后的原因 下面是一个可重现的示例 其中涉及从我的 github 安装虚拟
  • 在导航控制器中单击后退按钮时会调用哪个方法?

    我想在导航控制器中单击后退按钮时保存数据库 所以我会在方法中插入代码 在导航控制器中单击后退按钮时会调用什么方法 要执行您要求的操作 请查看UINavigationControllerDelegate协议 即方法 void navigati
  • Scala 的 Actor 是否有非阻塞 IO 开源实现?

    我需要处理相当大的文件 500Meg zip 文件 Scala 的 actor 是否有非阻塞 IO 开源实现 如果我的问题是正确的 那么您需要文件的非阻塞 IO 那么我有坏消息要告诉你 NIO Java6 中的 Java NIO 在处理文件
  • 如何确定两组纬度/经度坐标之间的距离?

    我正在尝试写一些东西来确定纬度 经度坐标组之间的距离 我正在使用我在上面找到的以下代码这个网站 public static double distance double lat1 double lon1 double lat2 double
  • 使用 python 中的 Optimize.leastsq 方法获取拟合参数的标准误差

    我有一组数据 位移与时间 我使用 optimization leastsq 方法将其拟合到几个方程中 我现在正在寻找拟合参数的误差值 查看文档 输出的矩阵是雅可比矩阵 我必须将其乘以残差矩阵才能得到我的值 不幸的是 我不是统计学家 所以我有