简体   繁体   English

使用curve_fit拟合的数据不正确

[英]Data fitting with curve_fit not correct

I have some experimental data which needs to be fitted so we can elucidate x value for certain y value. 我有一些实验数据需要拟合,因此我们可以为某些y值阐明x值。

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.interpolate import interp1d
#from xlrd import open_workbook


points = np.array([(0, -0.0142294), (20, 0.0308458785714286), (50, 
 0.1091054), (100
 ,0.2379176875), (200, 0.404354166666667)])
x = points[:,0]
y = points[:,1]
def func(x, p1,p2):
  return p1*(1-np.e**(-p2*x))

popt, pcov = curve_fit(func, x, y)
p1 = popt[0]
p2 = popt[1]

curvex=np.linspace(0,200,1000)
fit = func(curvex, p1, p2)
plt.plot(x, y, 'yo', label='data')

f = interp1d(fit, curvex, kind = 'nearest')
print (f(100))
plt.plot(curvex,fit,'r', linewidth=1)

plt.plot(x,y,'x',label = 'Xsaved')

plt.show()

Data is not fitted correctly. 数据未正确安装。 Help would be much appreciated. 帮助将不胜感激。

Here is an example graphical fitter using your data and equation, with scipy's differential_evolution genetic algorithm used to supply initial parameter estimates. 这是一个使用您的数据和方程式的图形拟合器示例,其中scipy的differential_evolution遗传算法用于提供初始参数估计值。 The scipy implementation of Differential Evolution ises the Latin Hypercube algorithm to ensure a thorough search of parameter space, and this requires bounds within which to search. 差分进化的科学实现是Latin Hypercube算法,以确保彻底搜索参数空间,这需要在搜索范围内进行。 In this example I have used the data maximum and minimum values as search bounds, this seems to work in this case. 在此示例中,我将数据的最大值和最小值用作搜索范围,在这种情况下,这似乎可行。 Note that it is much easier to find ranges within which to search than specific values. 请注意,查找范围要比特定值容易得多。

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


points = numpy.array([(0, -0.0142294), (20, 0.0308458785714286), (50, 0.1091054), (100 ,0.2379176875), (200, 0.404354166666667)])
x = points[:,0]
y = points[:,1]

# rename to match previous example code below
xData = x
yData = y


def func(x, p1,p2):
  return p1*(1-numpy.exp(-p2*x))


# 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)

    minAllData = min(minX, minY)
    maxAllData = min(maxX, maxY)

    parameterBounds = []
    parameterBounds.append([minAllData, maxAllData]) # search bounds for p1
    parameterBounds.append([minAllData, maxAllData]) # search bounds for p2

    # "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)

情节

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM