2012-09-26 6 views
6

Ho lavorato su Python, ma sono nuovo su scipy. Sto cercando di utilizzare i metodi della libreria interpolate per ottenere una funzione che si approssimi a un insieme di dati.Ottieni la formula di una funzione di interpolazione creata da scipy

Ho guardato alcuni esempi per iniziare, e potrebbe ottenere il codice di esempio lavorando in Python(x,y):

import numpy as np 
from scipy.interpolate import interp1d, Rbf 
import pylab as P 

# show the plot (empty for now) 
P.clf() 
P.show() 

# generate random input data 
original_data = np.linspace(0, 1, 10) 

# random noise to be added to the data 
noise = (np.random.random(10)*2 - 1) * 1e-1 

# calculate f(x)=sin(2*PI*x)+noise 
f_original_data = np.sin(2 * np.pi * original_data) + noise 

# create interpolator 
rbf_interp = Rbf(original_data, f_original_data, function='gaussian') 

# Create new sample data (for input), calculate f(x) 
#using different interpolation methods 
new_sample_data = np.linspace(0, 1, 50) 
rbf_new_sample_data = rbf_interp(new_sample_data) 

# draw all results to compare 
P.plot(original_data, f_original_data, 'o', ms=6, label='f_original_data') 
P.plot(new_sample_data, rbf_new_sample_data, label='Rbf interp') 
P.legend() 

La trama viene visualizzato come segue:

interpolation-plot

Ora , esiste un modo per ottenere un'espressione polinomiale che rappresenta la funzione interpolata creata da Rbf (ovvero il metodo creato come rbf_interp)?

Oppure, se questo non è possibile con Rbf, qualsiasi suggerimento che utilizza un metodo di interpolazione diverso, un'altra libreria o anche uno strumento diverso sono i benvenuti.

+0

Guardando i documenti per 'scipy.interpolate.Rbf' e per il modulo' scipy.interpolate' non riesco a vedere nulla di ciò che si desidera. L'unico modo in cui riesco a pensare è leggere il codice sorgente e capire come viene creata la funzione in base ai parametri e quindi scrivere la propria funzione che è in grado di restituire una rappresentazione leggibile. Ma questo dipenderebbe dai dettagli di implementazione. Anche se non riesco a vedere come potresti farcela. – Bakuriu

+0

Considera due passaggi: dati -> una curva (di Rbf o quant'altro), quindi curva -> polinomiale a tratti: una spline. È facile salvare i parametri della spline, (npiece + 1) * 4 - chiedi ulteriori informazioni se è quello che vuoi fare. – denis

risposta

4

L'RBF utilizza qualsiasi funzione tu chieda, è ovviamente un modello globale, quindi sì, c'è un risultato di funzione, ma ovviamente è vero che probabilmente non ti piacerà poiché è una somma su molti gaussiani. Hai:

rbf.nodes # the factors for each of the RBF (probably gaussians) 
rbf.xi  # the centers. 
rbf.epsilon # the width of the gaussian, but remember that the Norm plays a role too 

Così, con queste cose che si possono calcolare le distanze (con rbf.xi poi pluggin le distanze con i fattori in rbf.nodes e rbf.epsilon nella gaussiana (o qualunque funzione che ha chiesto di utilizzare).(È possibile controllare il codice python di __call__ e _call_norm)

in modo da ottenere qualcosa come sum(rbf.nodes[i] * gaussian(rbf.epsilon, sqrt((rbf.xi - center)**2)) for i, center in enumerate(rbf.nodes)) di dare qualche divertente mezzo di codice/formula, la funzione RBFs è scritto nella documentazione, ma si può anche verificare il codice python.

1

RBF probabilmente sta per Radial Basis Function. Non sarei sorpreso se scipy.interpolate.Rbf fosse la funzione che stai cercando.

Tuttavia, dubito che sarete in grado di trovare un'espressione polinomiale per rappresentare il risultato.

Se volete provare diversi metodi di interpolazione, controllare il corrispondente Scipy documentation, che dà link RBF, spline ...

+0

Ciao @Pierre, forse non ero chiaro nella mia domanda. Sto già usando 'scipy.interpolate.Rbf'. Quello che vorrei sapere è se posso in qualche modo estrarre una formula che rappresenta la funzione di interpolazione creata (ad esempio 'exp (x) + x^3-x^2', ecc.) –

2

La risposta è no, non esiste un modo "gentile" di scrivere la formula, o almeno non in modo breve. Alcuni tipi di interpolazioni, come RBF e Loess, non cercano direttamente una funzione matematica parametrica per adattarsi ai dati e invece calcolano il valore di ogni nuovo punto dati separatamente come funzione degli altri punti.

Queste interpolazioni garantiscono sempre una buona adattabilità ai dati (come nel caso specifico), e il motivo è che per descriverli è necessario un numero molto elevato di parametri (in pratica tutti i punti dati) . Pensala in questo modo: puoi interpolare linearmente collegando punti dati consecutivi con linee rette. È possibile adattare qualsiasi dato in questo modo e quindi descrivere la funzione in una forma matematica, ma richiederebbe un gran numero di parametri (almeno il numero di punti). In realtà ciò che stai facendo in questo momento è praticamente una versione liscia di questo.

Se si desidera che la formula sia breve, significa che si desidera descrivere i dati con una funzione matematica che non ha molti parametri (in particolare il numero di parametri dovrebbe essere molto inferiore al numero di punti dati). Tali esempi sono funzioni logistiche, funzioni polinomiali e persino la funzione seno (utilizzata per generare i dati). Ovviamente, se si sa quale funzione ha generato i dati, sarà la funzione che si desidera adattare.

+1

Hello @Bitwise, ovviamente nel codice sopra conosco la funzione ('f (x) = sin (2 * PI * x) + noise'); in realtà ho un set di dati in un CSV e non ho idea di quale sia la funzione (posso solo fare supposizioni basate sulla sua forma, tutto qui) –

+0

@ Eduardo sì, questo è quello che ho assunto. Il punto è che se hai un'idea di quale tipo di modello potrebbe adattarsi ai dati, sia per conoscenza precedente o semplicemente guardando i dati, questo potrebbe indicarti quale tipo di funzione dovresti usare. Altrimenti potrebbe essere qualsiasi cosa e l'unica cosa che puoi fare è provare diverse famiglie di funzioni parametriche. – Bitwise

+0

Ho leggermente modificato la mia risposta e aggiunto un breve esempio di interpolazione lineare. – Bitwise

0

Non credo che l'RBF di SciPy possa darvi la funzione effettiva. Ma una cosa che potresti fare è campionare la funzione che l'RBF di SciPy ti ha dato (cioè 100 punti). Quindi usa l'interpretazione di Lagrange con quei punti. Questo genererà una funzione polinomiale per te. Ecco un esempio su come questo sembrerebbe. Se non si desidera utilizzare l'interpolazione di Lagrange, è anche possibile utilizzare "Newton's dividend difference method" per generare una funzione polinomiale. enter image description here