求数值曲线的曲线方程

Chi*_*nik 0 python curve-fitting

我有一个二维图,它看起来是二次的。我从通过计算以数字方式获得的数据集中得到它。我知道可以通过拟合数据集来获得方程。Python 似乎自动根据数据点进行拟合。我需要打印拟合曲线的方程。

我对不同的 X 求解 Y 并获得两个数组 Y 和 X。然后我将它们绘制出来

plt.plot(X,Y)

plt.xlabel('X')
plt.ylabel('Y')
plt.savefig('YvsX.png', format='png', dpi=1000)

plt.show()
Run Code Online (Sandbox Code Playgroud)

并得到这个:

在此输入图像描述

需要打印该图的方程

Jam*_*ips 5

我从图中提取了数据点并执行了方程搜索,结果发现“y = a * exp(b/x) + Offset”作为可能的候选方程。这是一个使用提取的数据和该方程的图形拟合器,其中由 scipy 的 Differential_evolution 遗传算法模块提供 scipy 的 curve_fit() 求解器的初始参数估计。该模块使用拉丁超立方算法来确保对参数空间的彻底搜索,需要在搜索范围内进行。在此示例中,我使用了最大和最小数据值的界限,并且这些搜索界限在这种情况下效果很好。

阴谋

import numpy, scipy, matplotlib
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.optimize import differential_evolution
import warnings


# extracted from plot
xData = numpy.array([365.731, 377.548, 392.909, 409.453, 428.360, 447.267, 473.264, 498.079, 521.713, 545.347, 573.707, 598.522, 629.246, 669.423, 695.420, 736.779, 772.230, 823.042, 858.493, 883.308, 915.214, 951.846, 986.115, 1029.837, 1059.379, 1105.465, 1155.096, 1204.726, 1251.994])
yData = numpy.array([-0.306, -0.576, -0.969, -1.276, -1.766, -2.147, -2.503, -2.883, -3.177, -3.398, -3.705, -3.963, -4.196, -4.515, -4.662, -4.871, -5.055, -5.300, -5.374, -5.496, -5.582, -5.705, -5.803, -5.914, -5.987, -6.098, -6.208, -6.331, -6.368])


def func(x, a, b, Offset): # from the zunzun.com "function finder"
    return a * numpy.exp(b/x) + Offset


# function for genetic algorithm to minimize (sum of squared error)
def sumOfSquaredError(parameterTuple):
    warnings.filterwarnings("ignore") # do not print warnings by genetic algorithm
    val = func(xData, *parameterTuple)
    return numpy.sum((yData - val) ** 2.0)


def generate_Initial_Parameters():
    # min and max used for bounds
    maxX = max(xData)
    minX = min(xData)
    maxY = max(yData)
    minY = min(yData)

    minData = min(minX, minY)
    maxData = max(maxX, maxY)

    parameterBounds = []
    parameterBounds.append([minData, maxData]) # search bounds for a
    parameterBounds.append([minData, maxData]) # search bounds for b
    parameterBounds.append([minData, maxData]) # search bounds for Offset

    # "seed" the numpy random number generator for repeatable results
    result = differential_evolution(sumOfSquaredError, parameterBounds, seed=3)
    return result.x

# by default, differential_evolution completes by calling curve_fit() using parameter bounds
geneticParameters = generate_Initial_Parameters()

# now call curve_fit without passing bounds from the genetic algorithm,
# just in case the best fit parameters are aoutside those bounds
fittedParameters, pcov = curve_fit(func, xData, yData, geneticParameters)
print('Fitted parameters:', fittedParameters)
print()

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()
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)
Run Code Online (Sandbox Code Playgroud)