【问题标题】:How to calculate errors on slopes of linear fits when y-errors are asymmetric当 y 误差不对称时如何计算线性拟合斜率上的误差
【发布时间】:2017-07-08 09:27:09
【问题描述】:

我有一个数据集,其中的值可以绘制为 x 值与 y 值的对比。 y轴上的数据有不对称误差,即

我想用线性函数拟合这些数据。 我可以在python中通过多种方式进行拟合,但是它们都有相同的问题,即如何获取拟合参数的错误。

this 非常相关,但不可能(或至少不直接)使用scipy.optimize.curve_fit,因为我的数据在纵坐标(y 轴)上也存在不对称误差,以便得到斜率误差。

那么,当 y 误差线不对称时,如何计算线性拟合斜率上的误差?

有什么python函数可以解决这个问题吗?

【问题讨论】:

  • 拜托,这个问题在我看来很清楚而且非常具体。你能告诉我这里出了什么问题吗?
  • 仅供参考,您可以使用 this one 之类的网站嵌入 LaTeX。

标签: python numpy scipy


【解决方案1】:

Barlow+04 https://arxiv.org/abs/physics/0406120 有一篇关于找到具有不对称误差线的变量的平均值的论文。您或许可以使用这些技术。

我采取的蛮力方法是从分裂正态分布 (https://en.wikipedia.org/wiki/Split_normal_distribution) 中提取变量的许多实现,并为它们存储最佳拟合多项式参数。然后,我计算每个多项式参数的中位数和 1-sigma 上/下误差线(分别来自中位数的第 84 和第 16 个百分位数)。

下面的代码在 Python 2.7.9 中执行此操作。有一个函数用于计算分裂正常值、百分位数的误差和拟合多项式。

希望这会有所帮助。

#! /bin/python

from random import choice, gauss
from numpy import polyfit

def split_normal(mus, sigmas_u68, sigmas_l68):
    """
    RET: A split-normal value.
    """

    split_normal = []

    for mu, sigma_u68, sigma_l68 in zip(mus, sigmas_u68, sigmas_l68):

        sigma = choice([sigma_u68, -sigma_l68])
        g = abs(gauss(0.0, 1.0)) * sigma + mu
        split_normal.append(g)

    return split_normal

def errors_84_16(x):
    """
    RET: 1-sigma upper/lower error bars from the 84/16th percentile
         from the median.
    """

    n = len(x)

    index_med = n / 2 # median.
    index_84 = int(round(n * 0.84135)) # 84th percentile from median.
    index_16 = int(round(n * 0.15865))

    x_sorted = sorted(x)
    x_med = x_sorted[index_med]
    x_u68 = x_sorted[index_84] - x_med # 1-sigma upper error.
    x_l68 = x_med - x_sorted[index_16] # 1-sigma lower error.

    return x_med, x_u68, x_l68

def assymetric_polyfit(x, y, y_u68, y_l68, n_mc=500):
    """
    DES: Solves y = a + b * x for assymentric y error bars.
    RET: [a, a_u68, a_l68, b, b_u68, b_l68].
    """

    a_mc = []
    b_mc = []

    for i in xrange(0, n_mc):
        y_mc = split_normal(y, y_u68, y_l68)
        pars = polyfit(x, y_mc, 2)
        a_mc.append(pars[2])
        b_mc.append(pars[1])


    a, a_u68, a_l68 = errors_84_16(a_mc)
    b, b_u68, b_l68 = errors_84_16(b_mc)

    return a, a_u68, a_l68, b, b_u68, b_l68

def example():
    """
    """

    x = [1.0, 2.0, 3.0, 4.0, 5.0]
    y = [5.0, 8.0, 11.0, 14.0, 17.0] # 2 + 3x
    y_u68 = [0.5, 0.5, 0.5, 0.5, 0.5]
    y_l68 = [1.5, 1.5, 1.5, 1.5, 1.5]

    pars = assymetric_polyfit(x, y, y_u68, y_l68)
    print(pars)

if __name__ == '__main__':

    example()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-19
    相关资源
    最近更新 更多