Como interpretar coeficientes a partir de um ajuste de modelo polinomial?


36

Estou tentando criar um ajuste polinomial de segunda ordem para alguns dados que tenho. Digamos que eu plotei este ajuste com ggplot():

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

Eu recebo:

gráfico de ajuste parabólico com banda de confiança no gráfico de dispersão

Portanto, um ajuste de segunda ordem funciona muito bem. Eu calculo com R:

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

E eu recebo:

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 ***
# ....

Agora, eu assumiria que a fórmula para o meu ajuste é:

Barra=3,268-0,122foo+1.575foo2

Mas isso me dá os valores errados. Por exemplo, com sendo 3, eu esperaria que se tornasse algo em torno de 3,15. No entanto, inserindo na fórmula acima, recebo: fooBarra

Barra=3,268-0,1223+1.57532=17,077

O que da? Estou interpretando incorretamente os coeficientes do modelo?


2
Esta pergunta é respondida em vários tópicos que podem ser encontrados através de pesquisa o nosso site para ortogonal polinomial
whuber

6
@whuber Se eu soubesse que o problema estava com "polinômios ortogonais", provavelmente teria encontrado uma resposta. Mas se você não sabe o que procurar, é um pouco difícil.
User13907

2
Você também pode encontrar respostas pesquisando no poly , que aparece com destaque no seu código. Coloco essas informações nos comentários por dois motivos: (1) os links podem ajudar futuros leitores, além de você e (2) eles podem ajudar a mostrar como explorar nosso sistema de pesquisa (um tanto idiossincrático).
whuber

7
Você postou uma pergunta relacionada ao seu uso polysem digitar ?polyR primeiro? Diz " Calcular polinômios ortogonais " na parte superior em letras grandes e amigáveis.
Glen_b -Reinstala Monica

4
@Glen_b Sim, bem, eu fiz tipo em ?polyentender a sintaxe. É certo que tenho pouco conhecimento dos conceitos por trás disso. Eu não sabia que havia outra coisa (ou uma diferença tão grande entre polinômios "normais" e polinômios ortogonais), e os exemplos que vi on-line eram usados poly()para adaptação, especialmente com ggplot- então por que não usaria isso e ficar confuso se o resultado foi "errado"? Veja bem, eu não sou habilidoso em matemática - estou apenas aplicando o que vi outros fazerem e tentando entendê-lo.
User13907

Respostas:


55

Minha resposta detalhada está abaixo, mas a resposta geral (ou seja, real) a esse tipo de pergunta é: 1) experimente, dê uma olhada, veja os dados, você não pode quebrar o computador, não importa o que faça. . . experimentar; ou 2) RTFM .

Aqui está um Rcódigo que replica o problema identificado nesta pergunta, mais ou menos:

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

O primeiro lmretorna a resposta esperada:

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

O segundo lmretorna algo estranho:

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

Como lmé o mesmo nas duas chamadas, os argumentos lmsão diferentes. Então, vamos olhar para os argumentos. Obviamente, yé o mesmo. São as outras partes. Vejamos as primeiras observações sobre as variáveis ​​do lado direito na primeira chamada de lm. O retorno de head(cbind(x,x^2))parece:

            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

Isto é como esperado. A primeira coluna é xe a segunda coluna é x^2. Que tal a segunda chamada de lm, aquela com poli? O retorno de se head(poly(x,2))parece com:

              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, isso é realmente diferente. A primeira coluna não é xe a segunda coluna não x^2. Então, o poly(x,2)que quer que faça, ele não retorna xe x^2. Se quisermos saber o que polyfaz, podemos começar lendo seu arquivo de ajuda. É o que dizemos help(poly). A descrição diz:

Retorna ou avalia polinômios ortogonais de grau 1 a grau sobre o conjunto especificado de pontos x. Tudo isso é ortogonal ao polinômio constante de grau 0. Como alternativa, avalie os polinômios brutos.

Agora, você sabe o que são "polinômios ortogonais" ou não. Caso contrário, use a Wikipedia ou o Bing (não o Google, é claro, porque o Google é ruim - não tão ruim quanto a Apple, naturalmente, mas ainda ruim). Ou então, você pode decidir que não se importa com o que são polinômios ortogonais. Você pode notar a frase "polinômios brutos" e um pouco mais abaixo no arquivo de ajuda que polypossui uma opção rawque é, por padrão, igual a FALSE. Essas duas considerações podem inspirá-lo a experimentar head(poly(x, 2, raw=TRUE))quais retornos:

            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

Animado com essa descoberta (parece certo, agora, sim?), Você pode tentar: summary(lm(y ~ poly(x, 2, raw=TRUE))) Isso retorna:

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

Existem pelo menos dois níveis na resposta acima. Primeiro, eu respondi sua pergunta. Segundo, e muito mais importante, ilustrei como você deve responder a perguntas como essa. Toda pessoa que "sabe programar" passou por uma sequência como a acima de sessenta milhões de vezes. Até pessoas tão deprimente em programação quanto eu passam por essa sequência o tempo todo. É normal que o código não funcione. É normal entender mal o que as funções fazem. A maneira de lidar com isso é mexer, experimentar, examinar os dados e o RTFM. Saia do modo "sem pensar em seguir uma receita" e entre no modo "detetive".


7
Eu acho que isso merece um +6. Vou tentar lembrar em alguns dias quando isso se tornar possível. FTR, acho que não precisa ser tão sarcástico, mas faz um bom trabalho em mostrar o que são polinômios ortogonais / como eles funcionam e mostrar o processo que você usa para descobrir essas coisas.
gung - Restabelece Monica

13
Ótima resposta, obrigado. Embora eu esteja um pouco ofendido com um "RTFM" (mas talvez seja apenas eu): O problema é que em tudo o que li, pelo menos no que diz respeito à regressão linear em R, as pessoas às vezes fazem isso, outras fazem isso. Francamente, não entendo a entrada da Wikipedia sobre polinômios ortogonais. Não me ocorre por que alguém usaria isso para regressão se os coeficientes obtidos "estiverem errados". Não sou matemático - tento seguir as receitas porque não sou um cozinheiro experiente, mas preciso comer alguma coisa.
User13907

12
@ user13907, não é só você. Esta é de fato uma boa resposta que merece ser votada, mas se beneficiaria de ter um tom mais agradável.
Waldir Leoncio

8
Você realmente não precisa entender o que os polinômios ortogonais estão aqui - você só precisa entender que eles não são o que você deseja. Por que alguém pode querer polinômios ortogonais? Envie cov (poli (x, 2)) para descobrir que a covariância entre os dois termos no polinômio é zero (até erro de arredondamento). Essa é a propriedade chave dos polinômios ortogonais - seus termos têm covariância zero entre si. Às vezes, é conveniente que suas variáveis ​​RHS não tenham correlação zero entre si. Seus coeficientes não estão errados, na verdade, eles apenas precisam ser interpretados de maneira diferente.
Bill

2
Ah, tudo bem, essa explicação em inglês simples agora faz sentido. Obrigado.
User13907

5

Há uma abordagem interessante para a interpretação da regressão polinomial por Stimson et al. (1978) . Envolve reescrever

Y=β0 0+β1X+β2X2+você

Como

Y=m+β2(f-X)2+você

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



4

Se você deseja apenas um empurrão na direção certa, sem muito julgamento: poly()cria polinômios ortogonais (não correlacionados), ao contrário de I(), que ignora completamente a correlação entre os polinômios resultantes. A correlação entre variáveis ​​preditivas pode ser um problema em modelos lineares (veja aqui para obter mais informações sobre por que a correlação pode ser problemática); portanto, provavelmente é melhor (em geral) usar em poly()vez de I(). Agora, por que os resultados parecem tão diferentes? Bem, ambos poly()e I()tomar x e convertê-lo em um novo x (no caso de I(), o novo x é apenas x ^ 1 ou x ^ 2, no caso de poly(), os novos x são muito mais complicado (se você quer saber de onde eles vêm (e você provavelmente não), você pode começaraqui ou na página da Wikipedia ou livro mencionado ). O ponto é que, ao calcular (prever) y com base em um conjunto específico de valores de x, você precisa usar os valores de x convertidos produzidos por um poly()ou I()(dependendo de qual deles estava em seu modelo linear). Tão:

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]

Nesse caso, os dois modelos retornam a mesma resposta, o que sugere que a correlação entre variáveis ​​preditivas não está influenciando seus resultados. Se a correlação fosse um problema, os dois métodos preveriam valores diferentes.


1

'poli' executa a orto-normalização de Graham-Schmidt nos polinômios 1, x, x ^ 2, ..., x ^ deg Por exemplo, essa função faz a mesma coisa que 'poli' sem retornar os atributos de 'coef', é claro.

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]
}

Eu cheguei nesse tópico porque estava interessado na forma funcional. Então, como expressamos o resultado de 'poli' como uma expressão? Basta inverter o procedimento de Graham-Schmidt. Você vai acabar com uma bagunça!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.