Sorunum : Kısa süre önce, spline'ların yalnızca verileri araştırmak için yararlı olduğunu ve fazladan incelemeye maruz kaldığını, bu nedenle öngörmede fayda sağlamadığını bildiren bir istatistikçiyle tanıştım. Basit polinomlarla keşif yapmayı tercih etti ... Spline'ların büyük bir hayranı olduğum için ve bu sezgime aykırı olduğu için, bu argümanların ne kadar geçerli olduğunu ve eğer büyük bir anti-spline grubu olup olmadığını öğrenmek istiyorum. aktivistler orada mı?
Arkaplan : Modellerimi oluştururken Regresyon Modelleme Stratejileri (1) Frank Harrell'i izlemeye çalışıyorum. Kısıtlanmış kübik eğri çizgilerin sürekli değişkenleri araştırmak için geçerli bir araç olduğunu savunuyor. Ayrıca polinomların eşik, logaritmik gibi belirli ilişkileri modelleme konusunda yetersiz olduğunu savunuyor (2). Modelin doğrusallığını test etmek için spline için bir ANOVA testi önermektedir:
Spline'lara fazla uyduğum için googledim ancak bu kadar faydalı bulamadım (çok fazla düğüm kullanmama konusunda genel uyarılar dışında). Bu forumda spline modelleme için, bir tercih var gibi görünüyor Kolassa , Harrell , kendini tutamayan .
Polinomlarla ilgili bir blog yazısı buldum, polinomları tahmin etmekten bahseden fazla şeytan şeytan . Gönderi şu yorumlarla bitiyor:
Bir dereceye kadar burada sunulan örnekler hile yapıyor - polinom regresyonunun oldukça sağlam olmadığı bilinmektedir. Uygulamada çok daha iyi, polinomlardan ziyade spline kullanmaktır.
Şimdi bu, spline'ların örnekte nasıl performans göstereceğini kontrol etmemi istedi:
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"))
Aşağıdaki görüntüyü verir:
Sonuç olarak, beni tekrar gözden geçirme çizgileri konusunda ikna edecek bir şey bulamadım, neyi özlüyorum?
- FE Harrell, Regresyon Modelleme Stratejileri: Doğrusal Modellere Uygulamalar, Lojistik Regresyon ve Hayatta Kalma Analizi, Ciltli Kapaklı 1. Baskı'nın kapaklı baskısı. 2001. Springer, 2010.
- FE Harrell, KL Lee ve BG Pollock, “Klinik Çalışmalarda Regresyon Modelleri: Öngörü ve Tepki Arasındaki İlişkilerin Belirlenmesi” JNCI J Natl Cancer Inst, vol. 80, hayır. 15, sayfa 1198-1202, Ekim 1988.
Güncelleme
Yorumlar, veri aralığında neler olduğunu ama rahatsız edici kıvrımlarla beni meraklandırdı. Çoğu durumda, yukarıdaki örnekte gösterildiği gibi veri sınırlarının dışına çıkmıyorum. Bunun tahmin olarak nitelendirildiğinden emin değilim ...
Her neyse, burada polinomlara çevrilemeyen daha karmaşık bir çizgi oluşturduğum bir örnek. Gözlemlerin çoğu verilerin merkezinde olduğundan, bunu da benzetmeye çalıştı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)
Bu, aşağıdaki arsa verir:
Güncelleme 2
Bu gönderiden bu yana , büyük bir veri setinde yaş için doğrusallıktan yoksun görünen bir makale yayınladım . Ek, farklı yöntemleri karşılaştırıyor ve bunun hakkında bir blog yazısı yazdım .