繁体   English   中英

使用SciPy的minimum_squares()进行曲线拟合

[英]Curve fitting with SciPy's least_squares()

我正在使用Python进行最小二乘曲线拟合,并获得了不错的结果,但希望它更加健壮。

我有来自一阶LTI系统的数据,更具体地说是由测速仪读取的电机速度。 我试图适应电机的阶跃响应,以便推断出其传递函数。

速度(v(t))具有以下形式:v(t)= K *(1-exp(-t / T))

我在使用的数据中存在一些异常值,并希望缓解它们。 这通常在速度变得恒定时发生。 假设速度为10000个单位,有时我会得到10000 +/- 400的离群值。我想知道如何设置f_scale参数,因为我希望数据点保持在“实际”速度(平均值)的+/- 400以内。 我应该将f_scale设置为400还是800? 我不确定应该在那设置什么。

谢谢

编辑:一些数据。 在此处输入图片说明

我构建了一个最小的示例,该示例适用于与您相似的曲线。 如果您发布的是实际数据而不是图片,则速度会更快一些。 这两个关键的东西,了解有关与强大的配件least_squares是,你必须要使用的不同的值loss比线性参数和f_scale被用作损失函数的缩放参数。

基本上,从文档中, least_squares尝试

minimize F(x) = 0.5 * sum(rho(f_i(x)**2)

在上述公式中,设置损耗loss参数将改变rho 对于loss='linear' rho只是恒等函数。 loss='soft_l1'rho(z) = 2 * ((1 + z)**0.5 - 1) f_scale用于缩放损失函数,以使rho_(f**2) = C**2 * rho(f**2 / C**2) 因此,它与您在上面所要求的含义不同,它更像是一种减少较大错误的方法。

在这种特殊情况下,它似乎并没有太大的区别。

import numpy
import matplotlib.pyplot as plt
import scipy.optimize

tmax = 6000
N = 100
K = 6000
T = 200

smootht = numpy.linspace(0, tmax, 1000)
tm = numpy.linspace(0, tmax, N)

def f(t, K, T):
    return K * (1 - numpy.exp(-t/T))

v = f(smootht, K, T)

vm = f(tm, K, T) + numpy.random.randn(N)*400

def error(pars):
    K, T = pars
    vp = f(tm, K, T)
    return vm - vp

f_scales = [0.01, 1, 100]

plt.scatter(tm, vm)
for f_scale in f_scales:
    r = scipy.optimize.least_squares(error, [10, 10], loss='soft_l1', f_scale=f_scale)
    vp = f(smootht, *r.x)
    plt.plot(smootht, vp, label=f_scale)
plt.legend()

结果图如下:

f_scale的作用

我的建议是从开始尝试不同的损失函数开始,然后再使用f_scale

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM