Python的Power Law Fit

发布于 2025-01-28 00:21:42 字数 110 浏览 2 评论 0 原文

我有两列数据, x y 。我有兴趣进行表格的power Law拟合: y = a+b*x^c 。 Python中是否有包装?

I have two columns of data, x and y. I am interested to do power law fit of the form: y=a+b*x^c. Are there packages available in Python which does it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薄荷→糖丶微凉 2025-02-04 00:21:42

以下将两个参数与

import numpy as np
from scipy.optimize import least_squares
    # least_squares(fun, x0, jac='2-point', bounds=(-inf, inf), method='trf',
    #      ftol=1e-08, xtol=1e-08, gtol=1e-08, x_scale=1.0, loss='linear',
    # https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html

def fitpower( y, x: np.ndarray, c0=1, p0=1, verbose=0, **kw
) -> "OptimizeResult with .x .fun ...":
    """ fit y ~ c x^p with scipy least_squares """

    def err( cp ):
        c, p = cp
        return y - c * (x ** p)

    res = least_squares( err, x0=[c0, p0], jac='3-point', verbose=verbose, **kw )
    c, p = res.x
    if verbose:
        print( "fitpower: y ~ %.3g x^%.3g \n  err %s " % (
            c, p, res.fun ))
    return res  # an OptimizeResult with .x .fun ...

scipy.optimize.curve_fit 是最小二乘或最小值的包装器。

如果您有统计背景,请参阅
so How-to-to-properly-fit-data -to-a-power-law-in-python

The following fits two parameters with scipy least_squares (which is really nice, really powerful);
you can easily modify it for a + b x^c --

import numpy as np
from scipy.optimize import least_squares
    # least_squares(fun, x0, jac='2-point', bounds=(-inf, inf), method='trf',
    #      ftol=1e-08, xtol=1e-08, gtol=1e-08, x_scale=1.0, loss='linear',
    # https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.least_squares.html

def fitpower( y, x: np.ndarray, c0=1, p0=1, verbose=0, **kw
) -> "OptimizeResult with .x .fun ...":
    """ fit y ~ c x^p with scipy least_squares """

    def err( cp ):
        c, p = cp
        return y - c * (x ** p)

    res = least_squares( err, x0=[c0, p0], jac='3-point', verbose=verbose, **kw )
    c, p = res.x
    if verbose:
        print( "fitpower: y ~ %.3g x^%.3g \n  err %s " % (
            c, p, res.fun ))
    return res  # an OptimizeResult with .x .fun ...

scipy.optimize.curve_fit is a wrapper for least_squares or leastsq.

If you have some background in statistics, see
SO how-to-properly-fit-data-to-a-power-law-in-python.

我偏爱纯白色 2025-02-04 00:21:42

首先定义模型函数,

def power(x, a, b, c):
    return a + b * x ** c

我们可以使用从Scipy找到可以最佳拟合的A,B和C的值。

popt, pcov = curve_fit(power, x, y, p0=initial_guess)

“ POPT”是A,B和C的值列表,它给出了最佳拟合度(请注意,无法保证存在解决方案,或者您获得的解决方案是最佳的解决方案)。

“ PCOV”是矩阵。其对角线的平方根是对溶液不确定性的度量。

“初始猜测”是在拟合算法的第一次迭代中用作A,B和C的初始值的三个数字的列表。您必须提供值。

您可以传递到curve_fit的另一个关键字是“界限”。这将限制算法搜索参数a,b和c的值的范围。 “界限”可以列出两个列表。第一个列表是每个参数的底部限制,而第二个列表是针对顶部界限的。

这是一个例子。

x = [  2.5,   5. ,  10. ,  20. ,  40. , 160. ]
y = [  82933.97231252,  195697.01890895,  411424.83454658,
    689365.13501311, 1100703.42291616, 3069058.97376933]
initial_guess = [1e4, 1e4, 0.5]
popt, pcov = curve_fit(power, x, y, p0=initial_guess)

您应该得到

popt = array([-8.38814011e+04,  9.58024081e+04,  6.88182131e-01])
pcov = array([[ 1.49036273e+09, -4.72459139e+08,  8.87583051e+02],
             [-4.72459139e+08,  1.72727658e+08, -3.30764877e+02],
             [ 8.87583051e+02, -3.30764877e+02,  6.37612550e-04]])
fig, ax = plt.subplots()
ax.plot(x,y, ls='None', marker='.', ms=10)
X = np.linspace(0, 200, 201)
ax.plot(X, power(X, *popt))

“蓝色圆圈是原始数据,橙色线是适合的”

Start by defining a model function

def power(x, a, b, c):
    return a + b * x ** c

We can use the curve_fit function from scipy to find the values for a, b, and c which give the best fit.

popt, pcov = curve_fit(power, x, y, p0=initial_guess)

'popt' is a list of the values for a, b, and c which gives the best fit (notice that there is no guarantee a solution exists or that the one you get is the optimal one).

'pcov' is a matrix. The square root of its diagonal is a measure of the uncertainty of the solution.

'initial guess' is a list of three numbers that serve as initial values for a, b, and c in the first iteration of the fitting algorithm. You must provide the values.

Another keyword that you can pass to curve_fit is 'bounds'. This serves to limit the range the algorithm searches for values for the parameters a, b, and c. 'bounds' can take a tuple of two lists. The first list are the bottom limits for each parameter, while the second list is for the top bounds.

Here is an example.

x = [  2.5,   5. ,  10. ,  20. ,  40. , 160. ]
y = [  82933.97231252,  195697.01890895,  411424.83454658,
    689365.13501311, 1100703.42291616, 3069058.97376933]
initial_guess = [1e4, 1e4, 0.5]
popt, pcov = curve_fit(power, x, y, p0=initial_guess)

You should get

popt = array([-8.38814011e+04,  9.58024081e+04,  6.88182131e-01])
pcov = array([[ 1.49036273e+09, -4.72459139e+08,  8.87583051e+02],
             [-4.72459139e+08,  1.72727658e+08, -3.30764877e+02],
             [ 8.87583051e+02, -3.30764877e+02,  6.37612550e-04]])
fig, ax = plt.subplots()
ax.plot(x,y, ls='None', marker='.', ms=10)
X = np.linspace(0, 200, 201)
ax.plot(X, power(X, *popt))

Blue circles are the original data, and orange line is the fit

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文