在 scipy python 中使用 UnivariateSpline 拟合数据

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17913330/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:28:08  来源:igfitidea点击:

Fitting data using UnivariateSpline in scipy python

pythonnumpyscipycurve-fitting

提问by Prakhar Mehrotra

I have a experimental data to which I am trying to fit a curve using UnivariateSpline function in scipy. The data looks like:

我有一个实验数据,我试图在 scipy 中使用 UnivariateSpline 函数拟合曲线。数据看起来像:

 x         y
13    2.404070
12    1.588134
11    1.760112
10    1.771360
09    1.860087
08    1.955789
07    1.910408
06    1.655911
05    1.778952
04    2.624719
03    1.698099
02    3.022607
01    3.303135    

Here is what I am doing:

这是我在做什么:

import matplotlib.pyplot as plt
from scipy import interpolate
yinterp = interpolate.UnivariateSpline(x, y, s = 5e8)(x) 
plt.plot(x, y, 'bo', label = 'Original')
plt.plot(x, yinterp, 'r', label = 'Interpolated')
plt.show()

That's how it looks:

这就是它的外观:

Curve fit

曲线拟合

I was wondering if anyone has thought on other curve fitting options which scipy might have? I am relatively new to scipy.

我想知道是否有人考虑过 scipy 可能具有的其他曲线拟合选项?我对 scipy 比较陌生。

Thanks!

谢谢!

采纳答案by Craig J Copi

There are a few issues.

有几个问题。

The first issue is the order of the x values. From the documentation for scipy.interpolate.UnivariateSplinewe find

第一个问题是 x 值的顺序。从文档中scipy.interpolate.UnivariateSpline我们发现

x : (N,) array_like
    1-D array of independent input data. MUST BE INCREASING.

Stress added by me. For the data you have given the x is in the reversed order. To debug this it is useful to use a "normal" spline to make sure everything makes sense.

压力是我加的。对于您给出的数据,x 的顺序相反。为了调试这个,使用“正常”样条来确保一切都有意义是很有用的。

The second issue, and the one more directly relevant for your issue, relates to the s parameter. What does it do? Again from the documentation we find

第二个问题,也是与您的问题更直接相关的问题,与 s 参数有关。它有什么作用?再次从我们发现的文档中

s : float or None, optional
    Positive smoothing factor used to choose the number of knots.  Number
    of knots will be increased until the smoothing condition is satisfied:

    sum((w[i]*(y[i]-s(x[i])))**2,axis=0) <= s

    If None (default), s=len(w) which should be a good value if 1/w[i] is
    an estimate of the standard deviation of y[i].  If 0, spline will
    interpolate through all data points.

So s determines how close the interpolated curve must come to the data points, in the least squares sense. If we set the value very large then the spline does not need to come near the data points.

所以 s 决定了插值曲线必须接近数据点的程度,在最小二乘意义上。如果我们将值设置得非常大,则样条不需要靠近数据点。

As a complete example consider the following

作为一个完整的例子,考虑以下

import scipy.interpolate as inter
import numpy as np
import pylab as plt

x = np.array([13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1])
y = np.array([2.404070, 1.588134, 1.760112, 1.771360, 1.860087,
          1.955789, 1.910408, 1.655911, 1.778952, 2.624719,
          1.698099, 3.022607, 3.303135])
xx = np.arange(1,13.01,0.1)
s1 = inter.InterpolatedUnivariateSpline (x, y)
s1rev = inter.InterpolatedUnivariateSpline (x[::-1], y[::-1])
# Use a smallish value for s
s2 = inter.UnivariateSpline (x[::-1], y[::-1], s=0.1)
s2crazy = inter.UnivariateSpline (x[::-1], y[::-1], s=5e8)
plt.plot (x, y, 'bo', label='Data')
plt.plot (xx, s1(xx), 'k-', label='Spline, wrong order')
plt.plot (xx, s1rev(xx), 'k--', label='Spline, correct order')
plt.plot (xx, s2(xx), 'r-', label='Spline, fit')
# Uncomment to get the poor fit.
#plt.plot (xx, s2crazy(xx), 'r--', label='Spline, fit, s=5e8')
plt.minorticks_on()
plt.legend()
plt.xlabel('x')
plt.ylabel('y')
plt.show()

Result from example code

示例代码的结果