曲线拟合与整数输入Python 3.3

时间:2014-04-03 22:55:33

标签: python-3.x numpy scipy curve-fitting

我正在使用scipy的curvefit模块来拟合一个函数,并想知道是否有办法告诉它唯一可能的条目是整数而不是实数?有关另一种做法的想法吗?

2 个答案:

答案 0 :(得分:2)

在一般形式中,整数规划问题是NP难的(参见here)。有一些有效的启发式算法或近似算法可以解决这个问题,但没有一个算法可以保证精确的最优解。

在scipy中,您可以对整数系数实施网格搜索,并使用curve_fit覆盖给定整数系数的实际参数。至于网格搜索。 scipy有brute功能。

例如,如果y = a * x + b * x^2 + some-noise a必须是整数,则可能有效:

  1. 使用a = 5b = -1.5生成一些测试数据:

    coef, n = [5, - 1.5], 50
    xs = np.linspace(0, 10, n)[:,np.newaxis]
    xs = np.hstack([xs, xs**2])
    noise = 2 * np.random.randn(n)
    ys = np.dot(xs, coef) + noise
    
  2. 给定整数系数的函数使用curve_fit方法拟合实系数:

    def optfloat(intcoef, xs, ys):
        from scipy.optimize import curve_fit
        def poly(xs, floatcoef):
            return np.dot(xs, [intcoef, floatcoef])
        popt, pcov = curve_fit(poly, xs, ys)
        errsqr = np.linalg.norm(poly(xs, popt) - ys)
        return dict(errsqr=errsqr, floatcoef=popt)
    
  3. 给定整数系数的函数,使用上述函数优化浮点系数并返回错误:

    def errfun(intcoef, *args):
        xs, ys = args
        return optfloat(intcoef, xs, ys)['errsqr']
    
  4. 使用errfun最小化scipy.optimize.brute以找到最佳整数系数,并使用优化的整数系数调用optfloat以找到最佳实数系数:

    from scipy.optimize import brute
    grid = [slice(1, 10, 1)]  # grid search over 1, 2, ..., 9
    # it is important to specify finish=None in below
    intcoef = brute(errfun, grid, args=(xs, ys,), finish=None)
    floatcoef = optfloat(intcoef, xs, ys)['floatcoef'][0]
    
  5. 使用这种方法,我获得[5.0, -1.50577]的最佳系数,这对于整数系数是精确的,并且对于实系数足够接近。

答案 1 :(得分:0)

一般来说,答案是否:它所基于的scipy.optimize.curve_fit()和leastsq(),以及(AFAIK)scipy.optimize中的所有其他求解器都严格依赖于浮点数。

您可以尝试增加epsfcn的值(其默认值为numpy.finfo(' double')。eps~2.e-16),它将用作初始步骤问题中的所有变量。基本问题是拟合算法将调整浮点数,如果你做

    int_var = int(float_var)

并且算法将float_var从1.0更改为1.00000001,它将看到结果没有差异,并确定该值实际上不会改变拟合度量。

另一种方法是使用浮点参数&t; tmp_float_var'可以通过拟合算法自由调整,然后在目标函数中使用

    int_var = int(tmp_float_var / numpy.finfo('double').eps)

作为整数变量的值。这可能需要稍微调整,可能有点不稳定,但应该有效。