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