Python中的曲线拟合最小化均匀范数或L1范数(尤其是正方形)

时间:2017-08-03 23:32:08

标签: python mathematical-optimization curve-fitting

我有一组数据点(x_i,y_i)并且想要拟合曲线。我有一个函数的参数化,所以f(x; a)由参数a。

定义

我对最小化均匀范数的参数感兴趣,即目标是min_a max_i | f(x_i; a)-y_i |。 如果不可能,我也对L1规范感兴趣,即目标\ min_a \ sum_i | f(x_i; a)-y_i |。

我知道scipy.optimize中的curve_fit,但该库只适用于最小二乘的目标,即L2范数。

我想要解决的问题是体积小,大约100-200个数据点和4-5个参数,所以如果算法超级慢则不是什么大问题。 非常感谢任何图书馆的建议。

谢谢!

1 个答案:

答案 0 :(得分:0)

解决这个问题的一种方法(我只在这里解决L1规范):

转换:

  • 不可微分(由于L1范数)无约束优化问题
  • to:可区分约束优化问题!

基本理念:

  • 代替Min(Sum(L1(x))):
    • 引入形状为x(aux-vars)的变量y
    • 引入约束:-y< = x< = y
    • 求解:Min(Sum(y))

使用scipy的基本示例:

import numpy as np
import matplotlib.pyplot as plt
from scipy import optimize
np.random.seed(0)

""" Example function and curve_fit """

def f(t, omega, phi):
    return np.cos(omega * t + phi)

x_ = np.linspace(0, 3, 50)
y = f(x_, 1.5, 1) + .5*np.random.normal(size=50)
y[5] += 5  # synthetic outlier
y[10] += 5 # """

params, params_cov = optimize.curve_fit(f, x_, y)
t = np.linspace(0, 3, 1000)

""" Prototype l1 solver """
N = 2  # n-vars
M = x_.shape[0]  # number of samples

def g(x):
    return sum(x[N+M:])

cons = ({'type': 'eq',
         'fun': lambda x: x[N:N+M] - (f(x_, *x[:N]) - y),
        }
        ,
        {'type': 'ineq',
         'fun': lambda x: x[N+M:] + x[N:M+2],                    # -u_i <= x_i
        },
        {'type': 'ineq',
         'fun': lambda x: -x[N:M+2] + x[N+M:]}                   # x_i <= u_i
       )

res = optimize.minimize(g, np.random.uniform(high=0.05, size=N+M+M), constraints=cons, options={'disp': True})
params_ = res.x[:N]

print(res.x[N:N+M])  # losses
print(res.x[N+M:])   # l1(losses)

""" Plot results """

plt.plot(x_, y, color='red', label='orig')
plt.plot(t, f(t, *params), color='blue', label='curve_fit')
plt.plot(t, f(t, *params_), color='black', label='l1')
plt.legend()
plt.show()

输出

enter image description here

说明

  • 由于使用非凸包的一般求解器,问题高度依赖于初始值/不稳健