曲线拟合整数输入 Python 3.3

use*_*216 5 numpy curve-fitting scipy python-3.x

我正在使用 scipy 的曲线拟合模块来拟合函数,想知道是否有办法告诉它唯一可能的条目是整数而不是实数?关于另一种方法的任何想法?

beh*_*uri 5

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

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

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

  1. a = 5使用和生成一些测试数据b = -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
    
    Run Code Online (Sandbox Code Playgroud)
  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)
    
    Run Code Online (Sandbox Code Playgroud)
  3. 给定整数系数的函数,使用上述函数来优化浮点系数并返回错误:

    def errfun(intcoef, *args):
        xs, ys = args
        return optfloat(intcoef, xs, ys)['errsqr']
    
    Run Code Online (Sandbox Code Playgroud)
  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]
    
    Run Code Online (Sandbox Code Playgroud)

使用这种方法,我获得了[5.0, -1.50577]最佳系数,该系数对于整数系数来说是精确的,并且对于实数系数来说足够接近。