【问题标题】:Can we find the value of a particular fitting parameter from Quadratic equation?我们可以从二次方程中找到特定拟合参数的值吗?
【发布时间】:2023-11-26 17:26:01
【问题描述】:

在下面的代码中,我想找到拟合参数 v 的值。我知道幂律关系应该适用于我的数据点。但是当我拟合一个二次方程时,我最适合我的数据点。但在二次方程中,v 是多少?如果我符合幂律,那么误差很大,那么在这种情况下我该怎么办?

`import numpy as np
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import math
import scipy 
from scipy import optimize

fig = plt.figure()
ax= fig.add_subplot(111)

x_data = np.array([21,42,63,84]) 
y_data= np.array([0.14829848, 0.08196068, 0.04347054, 0.03137703])

def power_law(L,v):
    return (L**(-1/v))

def ff(L,a,b,Ec):
    return (a*(L)**2 + b*L +Ec) 

ax2.scatter(x_data, y_data, marker='s',s=4**2,)


pfit,pcov = optimize.curve_fit(ff,x_data,y_data)
print("pfit: ",pfit)
print("pcov: ",pcov.shape)
#print(pcov)
perr = np.sqrt(np.diag(pcov))
x=np.linspace(20,85,1000)

ax2.plot(x,ff(x,*pfit),color='red')`

【问题讨论】:

    标签: matplotlib curve-fitting


    【解决方案1】:

    代码中的二次方程有一个偏移项。幂律方程也需要一个偏移项。这是一个图形化 Python 拟合器,它使用您的数据和代码中的幂律加上偏移量。

    import numpy, scipy, matplotlib
    import matplotlib.pyplot as plt
    from scipy.optimize import curve_fit
    
    
    xData = numpy.array([21,42,63,84], dtype=float) 
    yData= numpy.array([0.14829848, 0.08196068, 0.04347054, 0.03137703])
    
    
    def func(L, v, offset):
        return (L**(-1.0/v)) + offset
    
    
    # these are the same as the scipy defaults
    initialParameters = numpy.array([1.0, 1.0])
    
    # curve fit the test data
    fittedParameters, pcov = curve_fit(func, xData, yData, initialParameters)
    
    modelPredictions = func(xData, *fittedParameters) 
    
    absError = modelPredictions - yData
    
    SE = numpy.square(absError) # squared errors
    MSE = numpy.mean(SE) # mean squared errors
    RMSE = numpy.sqrt(MSE) # Root Mean Squared Error, RMSE
    Rsquared = 1.0 - (numpy.var(absError) / numpy.var(yData))
    
    print('Parameters:', fittedParameters)
    print('RMSE:', RMSE)
    print('R-squared:', Rsquared)
    
    print()
    
    
    ##########################################################
    # graphics output section
    def ModelAndScatterPlot(graphWidth, graphHeight):
        f = plt.figure(figsize=(graphWidth/100.0, graphHeight/100.0), dpi=100)
        axes = f.add_subplot(111)
    
        # first the raw data as a scatter plot
        axes.plot(xData, yData,  'D')
    
        # create data for the fitted equation plot
        xModel = numpy.linspace(min(xData), max(xData))
        yModel = func(xModel, *fittedParameters)
    
        # now the model as a line plot
        axes.plot(xModel, yModel)
    
        axes.set_xlabel('X Data') # X axis data label
        axes.set_ylabel('Y Data') # Y axis data label
    
        plt.show()
        plt.close('all') # clean up after using pyplot
    
    graphWidth = 800
    graphHeight = 600
    ModelAndScatterPlot(graphWidth, graphHeight)
    

    【讨论】:

    • 但我有些困惑。如果我使用幂律作为 (a*L^(-1/v)+c) 我得到 v=2.15,误差为 1.57,但是如果我使用你提到的幂律公式,我会得到非常准确的 v 值。为什么会这样?这是否表明我的 3 个拟合参数的数据点较少?如何决定我应该更喜欢哪个功能?
    • 二次函数和我的函数中的偏移参数直接在 y 轴上垂直上下移动曲线。例如,如果数据是由“幂律 + 50”生成的,那么拟合的偏移参数应该是 50,如果没有该参数,幂律本身将无法拟合数据。您的数据包含一个小的偏移量,因此用于建模数据的方程应包含一个偏移量参数来说明这一点。我知道电子放大器和传感器可以在测量中引入这种偏移。
    • 该等式中还有一个参数 a。如果我介绍它,那么我的拟合参数的误差很大。这可能是什么原因?跳过a是否意味着我的拟合函数不正确?
    • 函数“(a*L^(-1/v)+c)”有一个增益因子“a”会影响v的拟合值,并有参数“c”作为抵消。当我在我发布的代码中使用这个函数时,它看起来很合适。我确实必须再添加一个初始参数值,因为该数组包含每个拟合参数的一个值,但在使用新函数时我没有进行其他更改。