通过更改python中的模型函数进行通用曲线拟合

Posted

技术标签:

【中文标题】通过更改python中的模型函数进行通用曲线拟合【英文标题】:generic curve fitting by changing model function in python 【发布时间】:2021-12-31 09:29:35 【问题描述】:

我正在使用 SciPy.optimize.curve_fit https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html 为了获得曲线拟合函数的系数,SciPy 函数将模型函数作为其第一个参数 所以如果我想进行线性曲线拟合,我将以下函数传递给它:

def objective(x, a, b):
    return a * x + b

如果我想要二次多项式曲线拟合,我通过以下:

def objective(x, a, b, c):
    return a * x + b * x**2 + c

等等,我要实现的就是让这个模型函数泛型化 例如,如果用户想通过输入 5 来拟合 5 次多项式,则应更改为

def objective(x, a, b, c, d, e, f):
    return (a * x) + (b * x**2) + (c * x**3) + (d * x**4) + (e * x**5) + f

代码运行时 这可能吗? 如果由于需要更改功能而无法使用 SciPy,还有其他方法可以实现我想要的吗?

【问题讨论】:

【参考方案1】:

该任务可以通过几种方式完成。如果你想使用 scipy,你可以简单地创建一个字典来使用用户输入的数字来引用特定的函数:

import scipy.optimize as optimization
polnum = 2 # suppose this is input from user


def objective1(x, a, b):
    return a * x + b


def objective2(x, a, b, c):
    return a * x + b * x**2 + c

# Include some more functions

# Do not include round brackets in the dictionary 
object_dict = 
    1: objective1,
    2: objective2
# Include the numbers with corresponding functions

opt = optimization.curve_fit(object_dict[polnum], x, y)  # Curve fitted

print(opt[0]) # Returns parameters

但是,我建议您采用一种更好的方法,您不必定义每个函数:

import numpy as np
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import make_pipeline
from sklearn.linear_model import LinearRegression

polnum = 2  # suppose this is input from user

# Creates a Polynomial of polnum degree
model = make_pipeline(PolynomialFeatures(polnum), LinearRegression)
# You can change the estimator Linear Regression to any other offered in sklearn.linear_model
# Make sure that x and y data are of the same shape
model.fit(x, y)
# Now you can use the model to check some other values
y_predict = model.predict(x_predict[:, np.newaxis])

【讨论】:

非常感谢 我想问一下“x_predict[:, np.newaxis]”这是做什么的?换句话说我在model.predict()中放了什么 对不起,这是我的错,我不应该把它包括在那里。但是,我可能会尝试解释您可以这样做的场合。假设你有很多数据,你想把它分成两部分:第一部分是训练模型,第二部分是检查模型是否正确。因此,您将有 2 个批次 x_train + y train 和 x_test + y_test。显然,您在 x_train + y train 上训练数据,并使用带有 x_test 输入的模型测试数据并获得 y_predict 的值。然后你比较 y_predict 和 y_test 看看模型是否足够好。希望你能理解!【参考方案2】:

如果你真的想自己实现它,你可以使用可变数量的系数*coeffs

def objective(x, *coeffs):
    result = coeffs[-1]
    for i, coeff in enumerate(coeffs[:-1]):
        result += coeff * x**(i+1)
    return result

或使用np.polyval:

import numpy as np

def objective(x, *coeffs):
    return np.polyval(x, coeffs)

但是,请注意,无需使用 curve_fit。您可以直接使用np.polyfit 进行最小二乘多项式拟合。

【讨论】:

效果很好,谢谢

以上是关于通过更改python中的模型函数进行通用曲线拟合的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV中实现曲线与圆拟合

Python最小二乘法拟合与作图

R语言mgcv包中的gam函数拟合广义加性模型(Generalized Additive Model)GAM(对非线性变量进行样条处理计算RMSER方调整R方可视化模型预测值与真实值的曲线)

利用Python的scipy包实现曲线的拟合

python 拟合曲线并求参

在 Python 中拟合参数曲线