Meu problema : recentemente, conheci um estatístico que me informou que as splines são úteis apenas para explorar dados e estão sujeitas a sobreajuste, portanto, não são úteis na previsão. Ele preferia explorar com polinômios simples ... Como sou um grande fã de splines, e isso vai contra a minha intuição. Estou interessado em descobrir quão válidos esses argumentos são e se existe um grande grupo de anti-splines- ativistas por aí?
Antecedentes : tento seguir Frank Harrell, Estratégias de Modelagem de Regressão (1), quando crio meus modelos. Ele argumenta que splines cúbicos restritos são uma ferramenta válida para explorar variáveis contínuas. Ele também argumenta que os polinômios são ruins na modelagem de certas relações, como limiares logarítmicos (2). Para testar a linearidade do modelo, ele sugere um teste ANOVA para o spline:
Pesquisei por overfitting com splines, mas não achei muito útil (além de avisos gerais sobre não usar muitos nós). Neste fórum, parece haver uma preferência pela modelagem de splines, Kolassa , Harrell , gung .
Eu encontrei uma postagem no blog sobre polinômios, o diabo da super adaptação que fala sobre a previsão de polinômios. A postagem termina com estes comentários:
Até certo ponto, os exemplos aqui apresentados são trapaceiros - sabe-se que a regressão polinomial é altamente não robusta. Muito melhor na prática é usar splines em vez de polinômios.
Agora, isso me levou a verificar o desempenho das splines com o exemplo:
library(rms)
p4 <- poly(1:100, degree=4)
true4 <- p4 %*% c(1,2,-6,9)
days <- 1:70
set.seed(7987)
noise4 <- true4 + rnorm(100, sd=.5)
reg.n4.4 <- lm(noise4[1:70] ~ poly(days, 4))
reg.n4.4ns <- lm(noise4[1:70] ~ ns(days,4))
dd <- datadist(noise4[1:70], days)
options("datadist" = "dd")
reg.n4.4rcs_ols <- ols(noise4[1:70] ~ rcs(days,5))
plot(1:100, noise4)
nd <- data.frame(days=1:100)
lines(1:100, predict(reg.n4.4, newdata=nd), col="orange", lwd=3)
lines(1:100, predict(reg.n4.4ns, newdata=nd), col="red", lwd=3)
lines(1:100, predict(reg.n4.4rcs_ols, newdata=nd), col="darkblue", lwd=3)
legend("top", fill=c("orange", "red","darkblue"),
legend=c("Poly", "Natural splines", "RCS - ols"))
Dá a seguinte imagem:
Em conclusão, não encontrei muita coisa que me convença de reconsiderar splines, o que estou perdendo?
- FE Harrell, Estratégias de modelagem de regressão: com aplicações em modelos lineares, regressão logística e análise de sobrevivência, reimpressão em capa mole da capa dura 1ª ed. 2001. Springer, 2010.
- FE Harrell, KL Lee e BG Pollock, "Modelos de Regressão em Estudos Clínicos: Determinando Relações entre Preditores e Resposta", JNCI J Natl Cancer Inst, vol. 80, n. 15, pp. 1198–1202, outubro de 1988.
Atualizar
Os comentários me fizeram pensar o que acontece no período de dados, mas com curvas desconfortáveis. Na maioria das situações, não vou além do limite de dados, como o exemplo acima indica. Não sei se isso se qualifica como previsão ...
Enfim, aqui está um exemplo em que eu crio uma linha mais complexa que não pode ser traduzida em um polinômio. Como a maioria das observações está no centro dos dados, tentei simular isso também:
library(rms)
cmplx_line <- 1:200/10
cmplx_line <- cmplx_line + 0.05*(cmplx_line - quantile(cmplx_line, .7))^2
cmplx_line <- cmplx_line - 0.06*(cmplx_line - quantile(cmplx_line, .3))^2
center <- (length(cmplx_line)/4*2):(length(cmplx_line)/4*3)
cmplx_line[center] <- cmplx_line[center] +
dnorm(6*(1:length(center)-length(center)/2)/length(center))*10
ds <- data.frame(cmplx_line, x=1:200)
days <- 1:140/2
set.seed(1234)
sample <- round(rnorm(600, mean=100, 60))
sample <- sample[sample <= max(ds$x) &
sample >= min(ds$x)]
sample_ds <- ds[sample, ]
sample_ds$noise4 <- sample_ds$cmplx_line + rnorm(nrow(sample_ds), sd=2)
reg.n4.4 <- lm(noise4 ~ poly(x, 6), data=sample_ds)
dd <- datadist(sample_ds)
options("datadist" = "dd")
reg.n4.4rcs_ols <- ols(noise4 ~ rcs(x, 7), data=sample_ds)
AIC(reg.n4.4)
plot(sample_ds$x, sample_ds$noise4, col="#AAAAAA")
lines(x=ds$x, y=ds$cmplx_line, lwd=3, col="black", lty=4)
nd <- data.frame(x=ds$x)
lines(ds$x, predict(reg.n4.4, newdata=ds), col="orange", lwd=3)
lines(ds$x, predict(reg.n4.4rcs_ols, newdata=ds), col="lightblue", lwd=3)
legend("bottomright", fill=c("black", "orange","lightblue"),
legend=c("True line", "Poly", "RCS - ols"), inset=.05)
Isso fornece o seguinte gráfico:
Atualização 2
Desde este post, publiquei um artigo que analisa a não linearidade por idade em um grande conjunto de dados. O suplemento compara diferentes métodos e eu escrevi um post sobre isso .
fonte
Respostas:
A super adaptação vem de permitir uma classe de modelos muito grande. Isso fica um pouco complicado com modelos com parâmetros contínuos (como splines e polinômios), mas se você discretizar os parâmetros em algum número de valores distintos, verá que o aumento do número de nós / coeficientes aumentará exponencialmente o número de modelos disponíveis . Para cada conjunto de dados, há um spline e um polinômio que se ajustam com precisão, desde que você permita coeficientes / nós suficientes. Pode ser que um spline com três nós se encaixe mais do que um polinômio com três coeficientes, mas isso dificilmente é uma comparação justa.
Se você possui um número baixo de parâmetros e um grande conjunto de dados, pode ter certeza de que não está se adaptando demais. Se você quiser tentar um número mais alto de parâmetros, tente validar cruzadamente dentro do seu conjunto de testes para encontrar o melhor número ou use um critério como Comprimento Mínimo da Descrição .
EDIT : Conforme solicitado nos comentários, um exemplo de como se aplicaria o MDL. Primeiro, você precisa lidar com o fato de que seus dados são contínuos, para que não possam ser representados em um código finito. Por uma questão de simplicidade, segmentaremos o espaço de dados em caixas do lado e, em vez de descrever os pontos de dados, descreveremos as caixas em que os dados se enquadram. Isso significa que perdemos um pouco de precisão, mas podemos tornar arbitrariamente pequeno, portanto isso não importa muito.ϵ ϵ
Agora, a tarefa é descrever o conjunto de dados da maneira mais sucinta possível, com a ajuda de algum polinômio. Primeiro, descrevemos o polinômio. Se é um polinômio de n-ésima ordem, precisamos armazenar (n + 1) coeficientes. Novamente, precisamos discretizar esses valores. Depois disso, precisamos armazenar primeiro o valor na codificação sem prefixo (para sabermos quando parar de ler) e depoisn n+1 valores de parâmetro. Com essas informações, um receptor do nosso código pode restaurar o polinômio. Em seguida, adicionamos o restante das informações necessárias para armazenar o conjunto de dados. Para cada ponto de dados, fornecemos o valor x e, em seguida, quantas caixas acima ou abaixo do ponto de dados estão fora do polinômio. Ambos os valores são armazenados em codificação sem prefixo, para que valores curtos exijam poucos bits e não precisaremos de delimitadores entre pontos. (Você pode encurtar o código para os valores x armazenando apenas os incrementos entre os valores)
O ponto fundamental aqui é a troca. Se eu escolher o polinômio de uma ordem (como f (x) = 3,4), o modelo é muito simples de armazenar, mas, para os valores de y, estou armazenando essencialmente a distância da média. Mais coeficientes me proporcionam um polinômio de melhor ajuste (e, portanto, códigos mais curtos para os valores y), mas tenho que gastar mais bits descrevendo o modelo. O modelo que fornece o código mais curto para seus dados é o mais adequado ao critério MDL.
(Observe que isso é conhecido como 'MDL bruto' e existem alguns refinamentos que você pode fazer para resolver vários problemas técnicos).
fonte
Os estatísticos discutem sobre o ajuste polinomial há séculos e, na minha experiência, tudo se resume a isso:
As splines são basicamente uma série de equações diferentes reunidas, o que tende a aumentar a precisão dos valores interpolados ao custo da capacidade de projetar fora do intervalo de dados. Isso é bom se você souber que seus dados são puros e provenientes de uma fonte consistente e se estiver tentando descrever a probabilidade de presença de valores diferentes dentro do seu intervalo de valores. No entanto, geralmente não aprendemos muito sobre os fundamentos teóricos que direcionam nossos dados, pois um novo spline inicia quando o spline antigo para de descrever com precisão os dados. Isso torna a previsão de valores fora de nossos dados quase inútil.
Agora, splines não são exclusivos nesse aspecto. As funções polinomiais realmente sofrem do mesmo problema se estamos apenas ajustando os dados e não usando uma estrutura teórica para escolher as variáveis. Aqueles que possuem uma teoria bem formada determinam quais variáveis permitem variar e em que medida confiarão mais na capacidade de uma função polinomial complexa de extrapolar previsões fora dos dados.
Muitos estatísticos, no entanto, estão trabalhando com dados sem a ajuda de um referencial teórico pré-estabelecido, e isso leva algumas pessoas a polinômios simples. Eles argumentam que uma função menos flexível que se ajusta aos dados tem maior probabilidade de prever com precisão valores fora dos dados, porque é menos provável que a função seja influenciada por anomalias nos dados. Embora tenha tido conversas sobre isso com pessoas que preferem polinômios simples, nunca tive a sensação de um grupo anti-spline. Parece que polinômios simples fazem com que alguns estatísticos se sintam mais confortáveis em evitar ajustes excessivos.
aviso Legal
Pessoalmente, não costumo usar splines ou polinômios simples com a maioria dos meus dados, porque trabalho em um campo com muitas estruturas teóricas pré-estabelecidas. Além disso, geralmente observei a coleta de dados e posso ter uma idéia decente sobre o que estava impulsionando os resultados. Nesse caso, estou construindo mais um algoritmo lógico e testando a adequação do algoritmo, em vez de testar a adequação de uma função polinomial. Você pode adicionar esse grão de sal à minha resposta.
fonte