scipy非线性曲线拟合中的过拟合

use*_*932 3 python curve-fitting scipy scikit-learn non-linear-regression

我有一个模型方程式,我们称它为eq_m:

eq_m

我知道我的数据集如下,因此我试图将数据拟合到eq_m,以便可以使用拟合的参数来预测新数据。

但是,此eq_m是非线性的,因此我使用scipy的curve_fit来获取lambda,mu,sigma参数值,并使用以下代码段:

opt_parms, parm_cov = o.curve_fit(eq_m, x, y,maxfev=50000)
lamb , mu, sigm = opt_parms
Run Code Online (Sandbox Code Playgroud)

我在应该遵循该模型的各种数据组上运行此模型,而55/60则给了我很好的结果,但是其余5组非常适合,并且预测的参数具有高正值。有没有办法使用scipy / numpy或scikit-learn来规范曲线拟合并惩罚高幅值参数值?

我的主管建议使用共轭先验,但我不知道如何在此处这样做。

谁能帮我这个忙吗?如果我必须提供解决这个问题的猜测,是否可以有人告诉我如何计算这些猜测?

kaz*_*ase 5

curve_fit不支持正则化。它始终使用最小二乘成本函数。为了规范拟合,您需要编写一个自定义成本函数,并用最小化scipy.optimize.minimize

让我们首先将曲线拟合转化为最小化问题:

def eq_m(x, lamb, mu, sigm):  # assumed signature of eq_m
    pass

def cost(params):  # simply use globally defined x and y
    lamb, mu, sigm = params
    model = eq_m(x, lamb, mu, sigm)
    return np.mean((model - y)**2)  # quadratic cost function

p0 = [1, 0, 1]  # initial guess for lambda, mu, and sigma
res = o.minimize(cost, p0)
print(res)  # see if minimization succeeded.
lamb, mu, sigm = res.x
Run Code Online (Sandbox Code Playgroud)

希望这会给您与相似的结果curve_fit。(如果不是这种情况,就该开始调试了。)

现在我们可以使用cost函数来实现正则化:

def cost(params):
    lamb, mu, sigm = params
    model = eq_m(x, lamb, mu, sigm)
    reg = lamb**2 + mu**2 + sigm**2  # very simple: higher parameters -> higher cost
    regweight = 1.0  # determines relative importance of regularization vs goodness of fit
    return np.mean((model - y)**2)  + reg * regweight
Run Code Online (Sandbox Code Playgroud)

不需要严格二次惩罚参数。基本上,您可以做任何事情,只要确保大参数会增加成本。结果会有所不同:-)

所有这一切都是非常严格的方法,缺乏严格的理论基础。主管的建议使用共轭先验声音,就像他们希望您使用贝叶斯估计技术一样。尽管可以将某些先验视为等效于正则化,但是该方法完全不同,并且可以在数学上相当复杂。代替成本函数,您需要定义一个似然函数,在参数上定义先验,然后使用贝叶斯定律将它们组合起来以得到后验似然,最终将其最大化。