【问题标题】:curve fitting by curve_fit from scipy in Pythonpython中scipy中curve_fit的曲线拟合
【发布时间】:2020-08-25 17:51:13
【问题描述】:

我正在尝试用指数函数拟合我的数据

import numpy as np

def exponentional(k, alpha, k0, c):
    return k0 * np.exp(k *-alpha) + c 

我使用了来自 scipy.optimize 的 curve_fit

from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
uniq_deg = [2,...,103,..,203,...,307,...,506] 
normalized_deg_dist = [0.99,...,0.43,..0.12,..,0.04,..., 0.01]
           
            
popt, pcov = curve_fit(exponentional, uniq_deg, normalized_deg_dist, 
                       p0 = [1,0.00001,1,1], maxfev = 6000)
           
fig = plt.figure() 
ax = fig.add_subplot(111)
             
ax.semilogy(uniq_deg, normalized_deg_dist, 'bo', label = 'Real data') 
ax.semilogy(uniq_deg,[exponentional(d,*popt) for d in uniq_deg], 'r-', label = 'Fit') 
ax.set_xlabel('Degree' ) 
ax.set_ylabel('1-CDF degree') 
ax.legend(loc='best')
ax.set_title(f'Degree distribution in {city}')
plt.show()

导致:

看起来不太合适。

我哪里错了?

【问题讨论】:

  • 我建议你使用 sklearn。它让一切变得简单。
  • 你能发布数据集吗?此外,您可以尝试将模型转换为对数空间并在那里进行拟合(然后只是线性拟合);这有时可以帮助获得更好的结果。
  • @VinayakMikkal 很抱歉,但如果您从数学角度不明白出了什么问题,那么更改 python 包不是解决方案。
  • 你好,玛丽亚姆,这可能非常合适。您正在拟合线性空间。因此,1 级的误差远比 10e-3 级的误差重要得多,尤其是当拟合确实检查了这些误差的平方时。因此,1e-2 以下的所有数据实际上都无关紧要。看来您的适合度设置为c<0,这样您就可以在对数尺度上获得这种差异。您的模型是否真的需要c?它可以是负面的还是你能确定c>=0?请注意,如果您按照@Cleb 的建议将数据放入对数空间中,则可以更改加权对数。
  • 这是一个巨大的数组。我应该在这里复制并粘贴吗? @Cleb

标签: python scipy curve-fitting


【解决方案1】:

最后,我没有使用curve_fit。我使用了来自https://mathworld.wolfram.com/LeastSquaresFittingExponential.html的指数拟合的定义@

而且我还需要通过幂律拟合一些其他数据,我也是这样做的。

    #%%
def fit_powerlaw(xs, ys):
    S_lnx_lny = 0.0
    S_lnx_S_lny = 0.0
    S_lny = 0.0
    S_lnx = 0.0
    S_lnx2 = 0.0
    S_ln_x_2 = 0.0
    n = len(xs)
    for (x,y) in zip(xs, ys):
        S_lnx += np.log(x)
        S_lny += np.log(y)
        S_lnx_lny += np.log(x) * np.log(y)
        S_lnx_S_lny = S_lnx * S_lny
        S_lnx2 += np.power(np.log(x),2)
        S_ln_x_2 = np.power(S_lnx,2)
    #end
    b = (n * S_lnx_lny - S_lnx_S_lny ) / (n * S_lnx2 - S_ln_x_2)
    a = (S_lny - b * S_lnx)  / (n)
    return (np.exp(a), b)
#%%
def fit_exp(xs, ys):
    S_x2_y = 0.0
    S_y_lny = 0.0
    S_x_y = 0.0
    S_x_y_lny = 0.0
    S_y = 0.0
    for (x,y) in zip(xs, ys):
        S_x2_y += x * x * y
        S_y_lny += y * np.log(y)
        S_x_y += x * y
        S_x_y_lny += x * y * np.log(y)
        S_y += y
    #end
    a = (S_x2_y * S_y_lny - S_x_y * S_x_y_lny) / (S_y * S_x2_y - S_x_y * S_x_y)
    b = (S_y * S_x_y_lny - S_x_y * S_y_lny) / (S_y * S_x2_y - S_x_y * S_x_y)
    return (np.exp(a), b)

指数拟合的第一张图和幂律的第二张图。 我认为结果令人信服。

【讨论】:

    猜你喜欢
    • 2016-11-29
    • 2021-09-25
    • 2020-05-05
    • 2020-07-07
    • 2020-07-12
    • 2013-10-10
    • 2014-09-08
    • 2017-04-21
    • 2020-06-12
    相关资源
    最近更新 更多