2016-03-27 19 views
8

Come adattare una regressione ponderata localmente in python in modo che possa essere utilizzata per prevedere nuovi dati?Prevedere nuovi dati utilizzando la regressione ponderata localmente (LOESS/LOWESS)

C'è statsmodels.nonparametric.smoothers_lowess.lowess, ma restituisce le stime solo per il set di dati originale; quindi sembra fare solo fit e predict insieme, piuttosto che separatamente come mi aspettavo.

scikit-learn ha sempre un metodo fit che consente di utilizzare l'oggetto in seguito sui nuovi dati con predict; ma non implementa lowess.

+2

Questo non è ciò che è per Lowess. Lowess è per levigare, non prevedere –

+2

@JesseBakker Può certamente essere usato per la previsione. https://stat.ethz.ch/R-manual/R-devel/library/stats/html/predict.loess.html. Vedi anche http://stackoverflow.com/questions/12822069/loess-predict-with-new-x-values. – max

risposta

3

Lowess funziona alla grande per la previsione (se combinato con l'interpolazione)! Penso che il codice sia piuttosto semplice-- fammi sapere se hai qualche domanda! Matplolib Figure

import matplotlib.pyplot as plt 
%matplotlib inline 
from scipy.interpolate import interp1d 
import statsmodels.api as sm 

# introduce some floats in our x-values 
x = list(range(3, 33)) + [3.2, 6.2] 
y = [1,2,1,2,1,1,3,4,5,4,5,6,5,6,7,8,9,10,11,11,12,11,11,10,12,11,11,10,9,8,2,13] 

# lowess will return our "smoothed" data with a y value for at every x-value 
lowess = sm.nonparametric.lowess(y, x, frac=.3) 

# unpack the lowess smoothed points to their values 
lowess_x = list(zip(*lowess))[0] 
lowess_y = list(zip(*lowess))[1] 

# run scipy's interpolation. There is also extrapolation I believe 
f = interp1d(lowess_x, lowess_y, bounds_error=False) 

xnew = [i/10. for i in range(400)] 

# this this generate y values for our xvalues by our interpolator 
# it will MISS values outsite of the x window (less than 3, greater than 33) 
# There might be a better approach, but you can run a for loop 
#and if the value is out of the range, use f(min(lowess_x)) or f(max(lowess_x)) 
ynew = f(xnew) 


plt.plot(x, y, 'o') 
plt.plot(lowess_x, lowess_y, '*') 
plt.plot(xnew, ynew, '-') 
plt.show() 
+2

Ciò richiederebbe l'interpolazione lineare. Anche se non è irragionevole, non è proprio lo stesso di "prevedere l'uso di lowess". Lowess è definito come una regressione lineare ponderata su un sottoinsieme dei punti di allenamento. La predizione che farebbe per un nuovo punto dovrebbe essere basata sul risultato di quella regressione, piuttosto che sulla previsione di due punti vicini del set di allenamento e quindi collegarli con una linea. Per un set di dati denso, la differenza è banale, ovviamente. I punti al di fuori dell'intervallo devono anche essere previsti con un LR ponderato sul quartiere corrispondente) anziché un valore fisso. – max

+0

@max Ho appena trovato questa domanda con un problema simile. Mentre sklearn non implementa LOESS, ha un'implementazione RANSAC, che sembra abbastanza simile ai miei occhi inesperti. Spero che questo sia utile a qualcuno: http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RANSACRegressor.html –

+0

@max non è affatto irragionevole e ho usato un approccio simile per ridimensionare la metabolomica dati in modo non parametrico per qualche tempo. I punti di scala al di fuori dell'intervallo per il massimo o il minimo della curva LOWESS e eseguono un'interpolazione lineare per tutto il resto. Se non ci sono abbastanza punti per una corretta interpolazione lineare, a mio avviso non ci sono abbastanza punti per una curva LOWESS adeguata. Un'altra nota, ho usato la libreria R per LOWESS sulla libreria Python. La libreria Python ha alcuni problemi con effetti di bordo che non ho potuto riconciliare. Devo amare RPy2 –

2

considerare l'utilizzo del kernel di regressione, invece.

statmodels ha un implementation.

Se si dispone di troppi punti dati, perché non utilizzare sk.learn's radiusNeighborRegression e specificare una funzione di ponderazione tricube?

+0

@David_R, se hai fornito più chiarezza di cosa intendevi (in realtà ha mostrato la tua implementazione), questa risposta sarebbe eccezionale. Solo un suggerimento. – benjaminmgross

+0

@benjaminmgross, grazie per la nota. Forse troverò del tempo per elaborare più tardi questa settimana o questo fine settimana. –

Problemi correlati