Python中已知系数的曲线拟合



我尝试使用Numpy, Scipy和Scikitlearn,但无法找到我需要的任何一个,基本上我需要将曲线拟合到数据集,但将一些系数限制为已知值,我发现如何在MATLAB中使用fittype,但无法在python中做到这一点。

在我的例子中,我有一个X和Y的数据集我需要找到最好的拟合曲线,我知道它是一个二次多项式(ax^2 + bx + c)我知道它的b和c的值,所以我只需要找到a的值

我在MATLAB中找到的解决方案是https://www.mathworks.com/matlabcentral/answers/216688-constraining-polyfit-with-known-coefficients,这与我的问题相同,但不同的是,他们的多项式是5度,我怎么能在python中做类似的事情?

添加一些信息:我需要拟合数据集的曲线,所以像scipy.optimize。curve_fit期望一个函数不会工作(至少就我所尝试的而言)。

您可用的工具通常只期望函数输入它们的参数(在您的情况下a是唯一未知的),或者输入它们的参数和一些数据(在您的情况下a,xy)。

Scipy的curve-fit很好地处理了这个用例,只要我们给它一个它能理解的函数。它首先需要x,然后将所有参数作为剩余的参数:

from scipy.optimize import curve_fit
import numpy as np
b = 0
c = 0
def f(x, a):
return c+x*(b+x*a)
x = np.linspace(-5, 5)
y = x**2
# params == [1.]
params, _ = curve_fit(f, x, y)

或者你可以选择你最喜欢的最小化程序。这里的不同之处在于,您手动构造了错误函数,以便它只输入您关心的参数,然后您不需要向scipy提供该数据。

from scipy.optimize import minimize
import numpy as np
b = 0
c = 0
x = np.linspace(-5, 5)
y = x**2
def error(a):
prediction = c+x*(b+x*a)
return np.linalg.norm(prediction-y)/len(prediction)**.5
result = minimize(error, np.array([42.]))
assert result.success
# params == [1.]
params = result.x

我不认为scipy有一个内置的部分应用的多项式拟合函数,但是如果你经常做这种事情,你可以使用上面的任何一个想法来轻松地自己构建一个。

from scipy.optimize import curve_fit
import numpy as np
def polyfit(coefs, x, y):
# build a mapping from null coefficient locations to locations in the function
# coefficients we're passing to curve_fit
# 
# idx[j]==i means that unknown_coefs[i] belongs in coefs[j]
_tmp = [i for i,c in enumerate(coefs) if c is None]
idx = {j:i for i,j in enumerate(_tmp)}
def f(x, *unknown_coefs):
# create the entire polynomial's coefficients by filling in the unknown
# values in the right places, using the aforementioned mapping
p = [(unknown_coefs[idx[i]] if c is None else c) for i,c in enumerate(coefs)]
return np.polyval(p, x)

# we're passing an initial value just so that scipy knows how many parameters
# to use
params, _ = curve_fit(f, x, y, np.zeros((sum(c is None for c in coefs),)))
# return all the polynomial's coefficients, not just the few we just discovered
return np.array([(params[idx[i]] if c is None else c) for i,c in enumerate(coefs)])
x = np.linspace(-5, 5)
y = x**2
# (unknown)x^2 + 1x + 0
# params == [1, 0, 0.]
params = fit([None, 0, 0], x, y)

几乎所有主流科学图书馆都存在类似的特征;您可能只需要稍微调整一下您的问题,以便根据可用的原语将其框定。

最新更新