Come interpretare i coefficienti dall'adattamento di un modello polinomiale?


36

Sto cercando di creare un polinomio del secondo ordine adatto ad alcuni dati che ho. Diciamo che ho tracciato questo adattamento con ggplot():

ggplot(data, aes(foo, bar)) + geom_point() + 
       geom_smooth(method="lm", formula=y~poly(x, 2))

Ottengo:

trama di adattamento parabolico con banda di sicurezza su scatterplot

Quindi, un secondo ordine funziona abbastanza bene. Lo calcolo con R:

summary(lm(data$bar ~ poly(data$foo, 2)))

E ottengo:

lm(formula = data$bar ~ poly(data$foo, 2))
# ...
# Coefficients:
#                     Estimate Std. Error t value Pr(>|t|)    
# (Intercept)         3.268162   0.008282 394.623   <2e-16 ***
# poly(data$foo, 2)1 -0.122391   0.096225  -1.272    0.206
# poly(data$foo, 2)2  1.575391   0.096225  16.372   <2e-16 ***
# ....

Ora, suppongo che la formula per la mia misura sia:

bar=3.268-0,122foo+1.575foo2

Ma questo mi dà solo i valori sbagliati. Ad esempio, con 3 mi aspetto che diventi qualcosa intorno a 3.15. Tuttavia, inserendo nella formula sopra ottengo: foobar

bar=3.268-0,1223+1.57532=17,077

Cosa dà? Sto interpretando erroneamente i coefficienti del modello?


2
A questa domanda viene data risposta in diversi thread che possono essere trovati cercando nel nostro sito il polinomio ortogonale
whuber

6
@whuber Se avessi saputo che il problema era con "polinomi ortogonali", probabilmente avrei trovato una risposta. Ma se non sai cosa cercare, è un po 'difficile.
user13907,

2
Puoi anche trovare risposte cercando su poly , che appare in primo piano nel tuo codice. Ho inserito tali informazioni nei commenti per due motivi: (1) i link possono aiutare sia i lettori futuri che te stesso e (2) possono aiutarti a mostrare come sfruttare il nostro sistema di ricerca (alquanto idiosincratico).
whuber

7
Hai pubblicato una domanda relativa al tuo utilizzo polysenza prima digitare ?polyR? Ciò dice " Calcola polinomi ortogonali " in alto con grandi lettere amichevoli.
Glen_b -Restate Monica

4
@Glen_b Sì, be ', ho fatto il tipo di ?polycomprendere la sintassi. Certo, ho solo poca conoscenza dei concetti alla base. Non sapevo che ci fosse qualcos'altro (o una differenza così grande tra polinomi "normali" e polinomi ortogonali) e gli esempi che ho visto online tutti usati poly()per adattarsi, specialmente con ggplot- quindi perché non dovrei semplicemente usarlo e essere confuso se il risultato fosse "sbagliato"? Intendiamoci, non sono esperto in matematica, sto semplicemente applicando ciò che ho visto fare agli altri e sto cercando di capirlo.
user13907,

Risposte:


55

La mia risposta dettagliata è di seguito, ma la risposta generale (cioè reale) a questo tipo di domanda è: 1) sperimentare, rovinare, guardare i dati, non si può rompere il computer indipendentemente da ciò che si fa, quindi. . . sperimentare; o 2) RTFM .

Ecco del Rcodice che replica più o meno il problema identificato in questa domanda:

# This program written in response to a Cross Validated question
# http://stats.stackexchange.com/questions/95939/
# 
# It is an exploration of why the result from lm(y_x+I(x^2))
# looks so different from the result from lm(y~poly(x,2))

library(ggplot2)


epsilon <- 0.25*rnorm(100)
x       <- seq(from=1, to=5, length.out=100)
y       <- 4 - 0.6*x + 0.1*x^2 + epsilon

# Minimum is at x=3, the expected y value there is
4 - 0.6*3 + 0.1*3^2

ggplot(data=NULL,aes(x, y)) + geom_point() + 
       geom_smooth(method = "lm", formula = y ~ poly(x, 2))

summary(lm(y~x+I(x^2)))       # Looks right
summary(lm(y ~ poly(x, 2)))   # Looks like garbage

# What happened?
# What do x and x^2 look like:
head(cbind(x,x^2))

#What does poly(x,2) look like:
head(poly(x,2))

Il primo lmrestituisce la risposta prevista:

Call:
lm(formula = y ~ x + I(x^2))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.53815 -0.13465 -0.01262  0.15369  0.61645 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  3.92734    0.15376  25.542  < 2e-16 ***
x           -0.53929    0.11221  -4.806 5.62e-06 ***
I(x^2)       0.09029    0.01843   4.900 3.84e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Residual standard error: 0.2241 on 97 degrees of freedom
Multiple R-squared:  0.1985,    Adjusted R-squared:  0.182 
F-statistic: 12.01 on 2 and 97 DF,  p-value: 2.181e-05

Il secondo lmrestituisce qualcosa di strano:

Call:
lm(formula = y ~ poly(x, 2))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.53815 -0.13465 -0.01262  0.15369  0.61645 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)  3.24489    0.02241 144.765  < 2e-16 ***
poly(x, 2)1  0.02853    0.22415   0.127    0.899    
poly(x, 2)2  1.09835    0.22415   4.900 3.84e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Residual standard error: 0.2241 on 97 degrees of freedom
Multiple R-squared:  0.1985,    Adjusted R-squared:  0.182 
F-statistic: 12.01 on 2 and 97 DF,  p-value: 2.181e-05

Poiché lmè lo stesso nelle due chiamate, devono essere gli argomenti di lmcui sono diversi. Quindi, diamo un'occhiata agli argomenti. Ovviamente yè lo stesso. Sono le altre parti. Diamo un'occhiata alle prime osservazioni sulle variabili di destra nella prima chiamata di lm. Il ritorno di head(cbind(x,x^2))assomiglia a:

            x         
[1,] 1.000000 1.000000
[2,] 1.040404 1.082441
[3,] 1.080808 1.168146
[4,] 1.121212 1.257117
[5,] 1.161616 1.349352
[6,] 1.202020 1.444853

Questo è come previsto. La prima colonna è xe la seconda colonna è x^2. Che ne dici della seconda chiamata di lm, quella con poli? Il ritorno di head(poly(x,2))assomiglia a:

              1         2
[1,] -0.1714816 0.2169976
[2,] -0.1680173 0.2038462
[3,] -0.1645531 0.1909632
[4,] -0.1610888 0.1783486
[5,] -0.1576245 0.1660025
[6,] -0.1541602 0.1539247

OK, è davvero diverso. La prima colonna non lo è xe la seconda colonna no x^2. Quindi, qualunque cosa poly(x,2)faccia, non ritorna xe x^2. Se vogliamo sapere cosa polyfa, potremmo iniziare leggendo il suo file di aiuto. Quindi diciamo help(poly). La descrizione dice:

Restituisce o valuta i polinomi ortogonali di grado 1 in gradi rispetto all'insieme di punti specificato x. Questi sono tutti ortogonali al polinomio costante di grado 0. In alternativa, valutare i polinomi grezzi.

Ora, o sai cosa sono i "polinomi ortogonali" o no. Se non lo fai, usa Wikipedia o Bing (non Google, ovviamente, perché Google è malvagio, non tanto cattivo quanto Apple, naturalmente, ma comunque cattivo). Oppure potresti decidere che non ti importa cosa siano i polinomi ortogonali. Potresti notare la frase "polinomi grezzi" e potresti notare un po 'più in basso nel file della guida che polyha un'opzione rawche, per impostazione predefinita, è uguale a FALSE. Queste due considerazioni potrebbero ispirarti a provare head(poly(x, 2, raw=TRUE))quale restituisce:

            1        2
[1,] 1.000000 1.000000
[2,] 1.040404 1.082441
[3,] 1.080808 1.168146
[4,] 1.121212 1.257117
[5,] 1.161616 1.349352
[6,] 1.202020 1.444853

Eccitato da questa scoperta (sembra giusto, ora sì?), Potresti continuare a provare summary(lm(y ~ poly(x, 2, raw=TRUE))) Questo ritorna:

Call:
lm(formula = y ~ poly(x, 2, raw = TRUE))

Residuals:
     Min       1Q   Median       3Q      Max 
-0.53815 -0.13465 -0.01262  0.15369  0.61645 

Coefficients:
                        Estimate Std. Error t value Pr(>|t|)    
(Intercept)              3.92734    0.15376  25.542  < 2e-16 ***
poly(x, 2, raw = TRUE)1 -0.53929    0.11221  -4.806 5.62e-06 ***
poly(x, 2, raw = TRUE)2  0.09029    0.01843   4.900 3.84e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1   1

Residual standard error: 0.2241 on 97 degrees of freedom
Multiple R-squared:  0.1985,    Adjusted R-squared:  0.182 
F-statistic: 12.01 on 2 and 97 DF,  p-value: 2.181e-05

Esistono almeno due livelli per la risposta sopra. Innanzitutto, ho risposto alla tua domanda. In secondo luogo, e molto più importante, ho illustrato come dovresti rispondere tu stesso a domande come questa. Ogni singola persona che "sa programmare" ha attraversato una sequenza come quella sopra sessanta milioni di volte. Anche le persone che sono depresse nella programmazione come me sono continuamente in questa sequenza. È normale che il codice non funzioni. È normale fraintendere le funzioni. Il modo per gestirlo è fare un giro, sperimentare, guardare i dati e RTFM. Esci dalla modalità "insensatamente seguendo una ricetta" e nella modalità "detective".


7
Penso che questo meriti un +6. Proverò a ricordare tra un paio di giorni quando ciò sarà possibile. FTR, penso che non debba essere così sarcastico, ma fa un buon lavoro nel mostrare quali polinomi ortogonali sono / come funzionano e nel mostrare il processo che usi per capire queste cose.
gung - Ripristina Monica

13
Ottima risposta, grazie. Anche se sono un po 'offeso da un "RTFM" (ma forse sono solo io): il problema è che in tutto ciò che ho letto, almeno per quanto riguarda la regressione lineare in R, le persone a volte lo fanno, altri lo fanno. Francamente, non capisco la voce di Wikipedia sui polinomi ortogonali. Non mi viene in mente il motivo per cui uno lo userebbe per la regressione se i coefficienti ottenuti sono "sbagliati". Non sono un matematico, provo a seguire le ricette perché non sono un cuoco istruito, ma devo comunque mangiare qualcosa.
user13907,

12
@ user13907, non sei solo tu. Questa è davvero una buona risposta che merita di essere votata, ma trarrebbe beneficio dall'avere un tono più gradevole.
Waldir Leoncio,

8
Non hai davvero bisogno di capire quali polinomi ortogonali sono qui --- devi solo capire che non sono quello che vuoi. Perché qualcuno potrebbe volere polinomi ortogonali? Invia cov (poli (x, 2)) per scoprire che la covarianza tra i due termini nel polinomio è zero (fino all'errore di arrotondamento). Questa è la proprietà chiave dei polinomi ortogonali --- i loro termini hanno zero covarianza l'uno con l'altro. A volte è conveniente per le variabili RHS avere zero correlazione tra loro. I loro coefficienti non sono sbagliati, in realtà, devono solo essere interpretati in modo diverso.
Bill

2
Oh, okay, questa spiegazione in un inglese semplice ora ha un senso. Grazie.
user13907,

5

C'è un approccio interessante all'interpretazione della regressione polinomiale di Stimson et al. (1978) . Implica la riscrittura

Y=β0+β1X+β2X2+u

come

Y=m+β2(f-X)2+u

m=β0-β12/4β2β2f=-β1/2β2



4

Se vuoi solo una spinta nella giusta direzione senza troppi giudizi: poly()crea polinomi ortogonali (non correlati), al contrario I(), che ignora completamente la correlazione tra i polinomi risultanti. La correlazione tra variabili predittive può essere un problema nei modelli lineari (vedi qui per maggiori informazioni sul perché la correlazione può essere problematica), quindi è probabilmente meglio (in generale) usare poly()invece di I(). Ora, perché i risultati sembrano così diversi? Bene, entrambi poly()e I()prendi x e convertilo in una nuova x (nel caso di I(), la nuova x è solo x ^ 1 o x ^ 2, nel caso di poly(), le nuove x sono molto più complicate (se vuoi sapere da dove vengono (e probabilmente non lo fai), puoi iniziarequi o la suddetta pagina di Wikipedia o un libro di testo). Il punto è che quando si calcola (prevedendo) y in base a un particolare set di valori x, è necessario utilizzare i valori x convertiti prodotti da uno poly()o I()(a seconda di quale era nel modello lineare). Così:

library(ggplot2)    

set.seed(3)
epsilon <- 0.25*rnorm(100)
x       <- seq(from=1, to=5, length.out=100)
y       <- 4 - 0.6*x + 0.1*x^2 + epsilon

# Minimum is at x=3, the expected y value there is
4 - 0.6*3 + 0.1*3^2

ggplot(data=NULL,aes(x, y)) + geom_point() + 
   geom_smooth(method = "lm", formula = y ~ poly(x, 2))

modI <- lm(y~x+I(x^2)) 
summary(modI) # Looks right
modp <- lm(y ~ poly(x, 2))
summary(modp)  # Looks like garbage

# predict y using modI
coef(modI)[1] + coef(modI)[2] * 3^1 + coef(modI)[3] * 3^2

# predict y using modp
# calculate the new x values using predict.poly()
x_poly <- stats:::predict.poly(object = poly(x,2), newdata = 3)
coef(modp)[1] + coef(modp)[2] * x_poly[1] + coef(modp)[3] * x_poly[2]

In questo caso, entrambi i modelli restituiscono la stessa risposta, il che suggerisce che la correlazione tra le variabili predittive non sta influenzando i risultati. Se la correlazione fosse un problema, i due metodi prevederebbero valori diversi.


1

'poly' esegue l'orto-normalizzazione di Graham-Schmidt sui polinomi 1, x, x ^ 2, ..., x ^ deg Ad esempio questa funzione fa la stessa cosa di 'poly' senza restituire, naturalmente, gli attributi 'coef'.

MyPoly <- 
function(x, deg)
{
    n <- length(x)
    ans <- NULL
    for(k in 1:deg)
    {
        v <- x^k
        cmps <- rep(0, n)
        if(k>0) for(j in 0:(k-1)) cmps <- cmps + c(v%*%ans[,j+1])*ans[,j+1]
        p <- v - cmps
        p <- p/sum(p^2)^0.5
        ans <- cbind(ans, p)
    }
    ans[,-1]
}

Sono arrivato a questo thread perché ero interessato alla forma funzionale. Quindi, come possiamo esprimere il risultato di "poli" come espressione? Basta invertire la procedura di Graham-Schmidt. Finirai con un casino!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.