<p>我从图中提取数据点并执行了一个方程搜索,结果显示“y=a*exp(b/x)+Offset”可能是一个候选方程。这是一个使用提取的数据和该方程的图形拟合器,以及scipy的微分进化遗传算法模块提供的scipy曲线拟合()解算器的初始参数估计。该模块使用拉丁超立方体算法来确保对参数空间的彻底搜索,并要求在该范围内进行搜索。在这个例子中,我使用了最大和最小数据值的边界,这些搜索边界在本例中工作得很好。在</p>
<p><a href="https://i.stack.imgur.com/14bJQ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/14bJQ.png" alt="plot"/></a></p>
<pre><code>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)
</code></pre>