2013-07-28 14 views
12

Ho un dato sperimentale a cui sto provando ad adattare una curva usando la funzione UnivariateSpline in scipy. I dati si presenta come:Raccordo dati usando UnivariateSpline in python scipy

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  

Ecco quello che sto facendo:

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

Ecco come appare:

Curve fit

Mi chiedevo se qualcuno ha pensato su altra curva opzioni di adattamento che potrebbe avere Scipy? Sono relativamente nuovo a Scipy.

Grazie!

+0

Avete la conoscenza a priori sui dati si sta lavorando? Può essere una rappresentazione teorica? O puoi ottenere più dati? 50 o 100 punti? – twil

+0

@twil: No. I dati provengono da esperimenti che coinvolgono decisioni umane. Questo è tutto quello che so. Sto cercando di adattare una curva con l'obiettivo di estrapolare a ulteriori valori di x. Ho provato cubic spline e polyfit, ma non sono neanche buoni. Sto facendo qualcosa di sbagliato con la scelta della funzione di livellamento sopra in UnivariateSpline? –

+0

Stai andando bene, ma devi avere pochi dati. Direi che i valori a 3 e 13 non sono in qualche modo "normali". Se li rimuovi otterrai una ... curva migliore? Ma senza alcuna conoscenza o assunzione sul processo non è giusto :) – twil

risposta

31

Ci sono alcuni problemi.

Il primo problema è l'ordine dei valori x. Dalla documentazione per scipy.interpolate.UnivariateSpline troviamo

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

stress aggiunto da me. Per i dati che hai dato la x è nell'ordine inverso. Per eseguire il debug di questo è utile utilizzare una spline "normale" per assicurarsi che tutto abbia un senso.

Il secondo problema, e uno più direttamente rilevante per il problema, si riferisce al parametro s. Che cosa fa? Anche in questo caso dalla documentazione troviamo

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. 

Così s determina quanto vicino la curva interpolata deve fare i punti dati, nel senso dei minimi quadrati. Se impostiamo il valore molto grande, la spline non ha bisogno di avvicinarsi ai punti dati.

Come un esempio completo considerare il seguente

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

Grazie per aver spiegato il significato di regolare i parametri s e per indicare l'ordine errato. Funziona bene! –

+0

Se impongo la condizione per cui la spline deve essere monotonicamente decrescente, UnivariateSpline mi consente di farlo? Grazie! –

+0

@PrakharMehrotra Non capisco la domanda. L'implementazione della spline richiede che x sia in aumento. Come nell'esempio, è semplice invertire gli array quando si trovano nell'opposto dell'ordine richiesto. –

Problemi correlati