2013-07-28 76 views
12

我有一個試驗數據,我試圖用scipy中的UnivariateSpline函數擬合曲線。數據是這樣的:在scipy python中使用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  

下面是我在做什麼:

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

這是它的外觀:

Curve fit

如果任何人有其他曲線以爲我不知道scipy可能有哪些適合的選項?我對scipy比較陌生。

謝謝!

+0

你對你正在使用的數據先驗知識?可能是理論表徵?或者你能獲得更多的數據嗎? 50或100分? – twil

+0

@twil:沒有。數據來自涉及人類決策的實驗。這是我所知道的一切。我試圖擬合曲線來推斷x的進一步值。我嘗試了三次樣條和polyfit,但它們也不好。我在UnivariateSpline中選擇了平滑函數嗎? –

+0

你做得很好,但只有很少的數據。我會說在3和13的值有點不「正常」。如果你刪除它們,你會得到一個更好的曲線?但沒有任何關於過程的知識或假設,這是不公平的:) – twil

回答

31

有幾個問題。

第一個問題是x值的順序。從scipy.interpolate.UnivariateSpline的文檔,我們發現

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

強調由我添加。對於你給出的數據,x是相反的順序。 要調試此功能,使用「正常」樣條來確保一切都合理有用。

第二個問題與您的問題更直接相關,與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. 

所以小號決定了插值曲線必須多接近來數據點,在最小二乘意義。如果我們將該值設置得非常大,則樣條線不需要靠近數據點。

作爲一個完整的例子考慮以下

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

+0

感謝您解釋平滑參數s的含義,並指出錯誤的順序。它工作正常! –

+0

如果我強調樣條需要單調遞減的條件,UnivariateSpline是否允許我這樣做?謝謝! –

+0

@PrakharMehrotra我不明白這個問題。樣條的實施要求x增加。正如在示例中所做的那樣,當它們與所需順序相反時,很容易顛倒數組。 –