过度拟合scipy非线性曲线拟合

时间:2017-04-19 16:14:13

标签: python scipy scikit-learn curve-fitting 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

我在各种数据组上运行这个模型,这些数据都应该遵循这个模型,而55/60给了我很好的结果,但是剩下的5个组高度拟合并且预测了具有高正值的参数。有没有办法可以使用scipy / numpy或scikit-learn来调整曲线拟合并惩罚高幅度参数值?

我的主管建议使用共轭先验,但我不知道该怎么做。

任何人都可以帮我这个吗?如果我必须提供一个猜测来解决这个问题,有人可以请告诉我如何计算这些猜测吗?

1 个答案:

答案 0 :(得分:4)

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

这有望为您提供与curve_fit类似的结果。 (如果不是这种情况,则需要开始调试。)

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

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

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

所有这些都是一种非常特殊的方法,缺乏严格的理论基础。主管建议使用共轭先验听起来像是期望你使用贝叶斯估计技术。虽然某些先验可以被认为等同于正规化,但这种方法完全不同,可以在数学上相当复杂。您需要定义似然函数,而不是成本函数,定义参数的先验,并使用贝叶斯规则将它们组合起来以获得最终最大化的后验可能性。