python - 为什么Python的curve_fit没有完成优化?

标签 python curve-fitting

我需要找到最适合给定 x 和 y 值的方程的两个参数。

我正在使用 Python 3,以及 Numpy 和 Scipy。

from scipy.optimize import curve_fit

def func(dx, d50, p):
    return (1 / (1 + ((d50 / dx) ** p)))

xdata = [280, 150, 75, 45, 38, 20, 10, 5.1, 2.6]
ydata = [99.57592773, 95.53773499, 81.14313507, 67.08183289, 62.93716431, 49.961483, 37.80876923, 24.53152657, 13.2219696]

# curve fit:
popt, pcov = curve_fit(func, xdata, ydata)
print(popt)

I expect a d50 ~ 20 and a p > 0.

但是 Python 发送给我:

[0.00221498 1.60291553]

> /usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:4:
> RuntimeWarning: invalid value encountered in power

从 sys.path 中删除 cwd 后。

最佳答案

我无法使用您帖子中的方程获得与您的数据的良好拟合。我的方程搜索发现,标准威 bool 峰方程“a * exp(-0.5 * pow(log(x/b)/c, 2.0))”对于参数 a = 103.1533969 给出 RMSE= 1.619 和 R 平方 = 0.997 ,b = 498.93546398 和 c = 2.67321918 如下所示。我已经包含了一个 Python 图形拟合器,使用这个方程和标准 scipy Differential_evolution 遗传算法模块来查找 curve_fit() 的初始参数估计,这个 scipy 模块使用拉丁超立方算法来确保对参数空间的彻底搜索,并且该算法需要范围内的边界要搜索哪个。在此示例中,搜索范围源自数据。确定初始参数估计值的范围比查找具体值要容易得多。

plot

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


xData = [280, 150, 75, 45, 38, 20, 10, 5.1, 2.6]
yData = [99.57592773, 95.53773499, 81.14313507, 67.08183289, 62.93716431, 49.961483, 37.80876923, 24.53152657, 13.2219696]


def func(x, a, b, c): # Peak_WeibullPeak_model from zunzun.com
    return a * numpy.exp(-0.5 * numpy.power(numpy.log(x/b) / c, 2.0))


# 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(maxY, maxX)

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

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

关于python - 为什么Python的curve_fit没有完成优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56520248/

相关文章:

r - R中的曲线拟合

r - 使用一组样本插值新值

MATLAB 曲线拟合 - 最小二乘法 - 使用高次错误 "fit"

python - 在 Django REST ListAPI View 中对原始 SQL 查询进行分页的最佳方法?

python - Peewee 的 Where 子句中的 IN 条件

python - 提取图像中的车牌号

python - Scipy 的优化曲线拟合限制

python - 如何使用 kapteyn.kmpfit 计算具有 2 个或更多自变量的模型的置信带

python - 二叉搜索树不插入/打印实际最大值,除非它被实现为根

python - 为什么python在for和while循环之后使用 'else'?