在 scipy python 中使用 UnivariateSpline 拟合数据 [英] Fitting data using UnivariateSpline in scipy python

查看:21
本文介绍了在 scipy python 中使用 UnivariateSpline 拟合数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个实验数据,我试图在 scipy 中使用 UnivariateSpline 函数拟合曲线.数据如下:

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

 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    

这是我在做什么:

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()

看起来是这样的:

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

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

谢谢!

推荐答案

有几个问题.

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

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

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

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

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.

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

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 : 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 决定了插值曲线与数据点的接近程度,在最小二乘意义上.如果我们将值设置得很大,那么样条就不需要靠近数据点.

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.

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

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()

这篇关于在 scipy python 中使用 UnivariateSpline 拟合数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆