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()
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
@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? –
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