【问题标题】:best curve fitting the distribution拟合分布的最佳曲线
【发布时间】:2019-03-31 17:42:38
【问题描述】:

我尝试使用多项式(3 度)来拟合数据系列,但似乎仍然不是最佳拟合(下图中有些点偏离了)。我还尝试添加一个日志功能来帮助绘图。但结果也没有改善。

这里最好的曲线拟合是什么?

以下是我拥有的原始数据点: x_values = [ 0.51,0.56444444,0.61888889 , 0.67333333 , 0.72777778, 0.78222222, 0.83666667, 0.89111111 , 0.94555556 , 1. ] y_values = [0.67154591, 0.66657266, 0.65878351, 0.6488696, 0.63499979, 0.6202393, 0.59887225, 0.56689689, 0.51768976, 0.33029004]

多项式拟合的结果:

【问题讨论】:

    标签: numpy plot scipy model-fitting


    【解决方案1】:

    如果你的曲线拟合过程是假设驱动的,那就更好了,也就是说,你已经有了一个想法,期望什么样的关系。在我看来,这个形状更像是一个指数函数:

    from matplotlib import pyplot as plt
    import numpy as np
    from scipy.optimize import curve_fit
    
    #the function that describes the data    
    def func(x, a, b, c, d):
        return a * np.exp(b * x + c) + d
    
    x_values = [0.51,0.56444444, 0.61888889, 0.67333333 , 0.72777778, 0.78222222, 0.83666667, 0.89111111 , 0.94555556 , 1.  ]
    y_values = [0.67154591, 0.66657266, 0.65878351, 0.6488696, 0.63499979, 0.6202393, 0.59887225, 0.56689689, 0.51768976, 0.33029004]
    
    #start values [a, b, c, d]
    start = [-.1, 1, 0, .1]
    #curve fitting
    popt, pcov = curve_fit(func, x_values, y_values, p0 = start)
    #output [a, b, c, d]
    print(popt)
    
    #calculating the fit curve at a better resolution
    x_fit = np.linspace(min(x_values), max(x_values), 1000)
    y_fit = func(x_fit, *popt)
        
    #plot data and fit
    plt.scatter(x_values, y_values, label = "data")
    plt.plot(x_fit, y_fit, label = "fit")
    plt.legend()
    plt.show()
    

    这给出了以下输出:

    这看起来仍然不正确,第一部分似乎有线性偏移。如果我们考虑到这一点:

    from matplotlib import pyplot as plt
    import numpy as np
    from scipy.optimize import curve_fit
    
    def func(x, a, b, c, d, e):
        return a * np.exp(b * x + c) + d * x + e
    
    x_values = [0.51,0.56444444, 0.61888889, 0.67333333 , 0.72777778, 0.78222222, 0.83666667, 0.89111111 , 0.94555556 , 1.  ]
    y_values = [0.67154591, 0.66657266, 0.65878351, 0.6488696, 0.63499979, 0.6202393, 0.59887225, 0.56689689, 0.51768976, 0.33029004]
    
    start = [-.1, 1, 0, .1, 1]
    popt, pcov = curve_fit(func, x_values, y_values, p0 = start)
    print(popt)
    
    x_fit = np.linspace(min(x_values), max(x_values), 1000)
    y_fit = func(x_fit, *popt)
    
    plt.scatter(x_values, y_values, label = "data")
    plt.plot(x_fit, y_fit, label = "fit")
    plt.legend()
    plt.show()
    

    我们有以下输出:

    这现在更接近您的数据点。 但。你应该去你的数据思考,哪个模型最有可能反映现实,然后实施这个模型。您始终可以构建更复杂的函数来更好地拟合您的数据,但它们不一定能反映更好的现实。

    【讨论】:

      猜你喜欢
      • 2011-01-31
      • 2017-03-31
      • 2016-07-25
      • 1970-01-01
      • 2019-06-04
      • 2018-06-04
      • 2021-03-14
      • 2023-03-26
      相关资源
      最近更新 更多