Spline sonuçlarını yorumlama


20

R kullanarak bir GLM için bir spline uydurmaya çalışıyorum. Spline'ı yerleştirdikten sonra, ortaya çıkan modelimi alıp bir Excel çalışma kitabında bir modelleme dosyası oluşturmak istiyorum.

Örneğin, y'nin x'in rastgele bir işlevi olduğu ve eğimin belirli bir noktada aniden değiştiği bir veri kümem olduğunu varsayalım (bu durumda @ x = 500).

set.seed(1066)
x<- 1:1000
y<- rep(0,1000)

y[1:500]<- pmax(x[1:500]+(runif(500)-.5)*67*500/pmax(x[1:500],100),0.01)
y[501:1000]<-500+x[501:1000]^1.05*(runif(500)-.5)/7.5

df<-as.data.frame(cbind(x,y))

plot(df)

Şimdi bunu kullanarak uyuyorum

library(splines)
spline1 <- glm(y~ns(x,knots=c(500)),data=df,family=Gamma(link="log"))

ve sonuçlarım gösteriyor

summary(spline1)

Call:
glm(formula = y ~ ns(x, knots = c(500)), family = Gamma(link = "log"), 
    data = df)

Deviance Residuals: 
     Min       1Q   Median       3Q      Max  
-4.0849  -0.1124  -0.0111   0.0988   1.1346  

Coefficients:
                       Estimate Std. Error t value Pr(>|t|)    
(Intercept)             4.17460    0.02994  139.43   <2e-16 ***
ns(x, knots = c(500))1  3.83042    0.06700   57.17   <2e-16 ***
ns(x, knots = c(500))2  0.71388    0.03644   19.59   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

(Dispersion parameter for Gamma family taken to be 0.1108924)

    Null deviance: 916.12  on 999  degrees of freedom
Residual deviance: 621.29  on 997  degrees of freedom
AIC: 13423

Number of Fisher Scoring iterations: 9

Bu noktada, r içindeki tahmin fonksiyonunu kullanabilir ve mükemmel kabul edilebilir cevaplar alabilirim. Sorun, Excel'de bir çalışma kitabı oluşturmak için model sonuçlarını kullanmak istememdir.

Tahmin işlevini anladığım kadarıyla, yeni bir "x" değeri verildiğinde, r, yeni x'i uygun eğri işlevine (500'ün üzerindeki değerler işlevi veya 500'ün altındaki değerler için işlev) takarsa, o sonucu alır ve çarpar buna uygun katsayı ile ve bu noktadan itibaren diğer model terimleri gibi davranır. Bu spline işlevlerini nasıl edinebilirim?

(Not: Günlük bağlantılı bir gama GLM'nin sağlanan veri seti için uygun olmayabileceğini anlıyorum. GLM'lerin nasıl veya ne zaman takılacağını sormuyorum. Bu seti tekrarlanabilirlik amacıyla örnek olarak sunuyorum.)


7
Mümkünse, tüm değişkenleri ( rm(list=ls())) silen kodu dahil etmekten kaçınmak için özellikle herhangi bir uyarı yapmamayı öneririm . Bazı zaten değişkenleri (ancak hiçbiri denir sahip olduğu Birisi R açık oturumda içine yere yapıştırın olabilir x, y, dfveya spline1) ve bayan kodunuzu işlerini mendil söyledi. Bunu yapmaları biraz aptalca mı? Evet. Ancak, kendi değişkenlerini ne zaman sileceklerine karar vermelerine izin vermek hala kibar.
Glen_b

Yanıtlar:


25

Spline formüllerini Rkoda girmek zorunda kalmadan tersine mühendislik yapabilirsiniz . Bunu bilmek yeterli

  • Spline, parçalı bir polinom fonksiyonudur.

  • Derece polinomları , noktalarındaki değerleri ile belirlenir .d + 1dd+1

  • Bir polinomun katsayıları doğrusal regresyon yoluyla elde edilebilir.

Bu nedenle, sadece oluşturmak zorunda , (veri aralığının kapalı uç noktaları dahil olmak üzere), birbirini takip eden düğüm çifti arasında aralıklı noktalar eğri değerlerini tahmin ve güçlerine karşı tahmini gerileme kadar . Bu düğüm "bölmeleri" içindeki her bir spline temel elemanı için ayrı bir formül olacaktır. Örneğin, aşağıdaki örnekte üç iç düğüm (dört düğüm bölmesi için) vardır ve kübik spline'lar ( ) kullanılmıştır, bu da her biri katsayılı kübik polinom ile sonuçlanır . Çünkü nispeten yüksek güçlerix x d d = 3 4 × 4 = 16 d + 1 = 4 xd+1xxdd=34×4=16d+1=4xsöz konusu ise, katsayılardaki tüm hassasiyeti korumak zorunludur. Tahmin edebileceğiniz gibi, herhangi bir spline temel elementinin tam formülü oldukça uzun sürebilir!

Bir süre önce bahsettiğim gibi, bir programın çıktısını başka bir programın girdisi olarak kullanabilmek (yeniden oluşturulamayan hatalar oluşturabilen manuel müdahale olmadan) faydalı bir istatistiksel iletişim becerisidir. Bu soru, bu ilkenin nasıl uygulandığına dair güzel bir örnek sunmaktadır: on altı haneli katsayıları manuel olarak kopyalamak yerine, hesaplanan eğrileri Excel'in anlayabileceği formüllere dönüştürmenin bir yolunu bir araya getirebiliriz. Tek yapmamız gereken spline katsayılarını yukarıda açıklandığı gibi çıkarmak, bunları Excel benzeri formüllerde yeniden biçimlendirmek ve bunları kopyalayıp Excel'e yapıştırmaktır.64RR

Bu yöntem, herhangi bir istatistiksel yazılımla, kaynak kodu kullanılamayan belgesiz özel yazılımla bile çalışacaktır.

İşte sorudan alınan ancak üç iç noktada ( ) ve uç noktalarda düğümlere sahip olacak şekilde değiştirilmiş bir örnek . Grafikler , Excel'in oluşturulmasını izleyen sürümünü gösterir . Her iki ortamda da çok az kişiselleştirme gerçekleştirildi ( yaklaşık olarak Excel'in varsayılan renkleriyle eşleşecek renkleri belirtmek dışında ).( 1 , 1000 )200,500,800(1,1000)RR

R grafikleri

Excel grafikleri

(Sürümdeki dikey gri ızgara çizgileri R, iç düğümlerin nerede olduğunu gösterir.)


İşte tam Rkod. Tamamen pastedize manipülasyonunu gerçekleştirme işlevine dayanan, sofistike olmayan bir kesmek . (Formül şablonu oluşturmak ve dizgi eşleme ve değiştirme komutlarını kullanarak doldurmak daha iyi bir yol olabilir.)

#
# Create and display a spline basis.
#
x <- 1:1000
n <- ns(x, knots=c(200, 500, 800))

colors <- c("Orange", "Gray", "tomato2", "deepskyblue3")
plot(range(x), range(n), type="n", main="R Version",
     xlab="x", ylab="Spline value")
for (k in attr(n, "knots")) abline(v=k, col="Gray", lty=2)
for (j in 1:ncol(n)) {
  lines(x, n[,j], col=colors[j], lwd=2)
}
#
# Export this basis in Excel-readable format.
#
ns.formula <- function(n, ref="A1") {
  ref.p <- paste("I(", ref, sep="")
  knots <- sort(c(attr(n, "Boundary.knots"), attr(n, "knots")))
  d <- attr(n, "degree")
  f <- sapply(2:length(knots), function(i) {
    s.pre <- paste("IF(AND(", knots[i-1], "<=", ref, ", ", ref, "<", knots[i], "), ", 
                   sep="")
    x <- seq(knots[i-1], knots[i], length.out=d+1)
    y <- predict(n, x)
    apply(y, 2, function(z) {
      s.f <- paste("z ~ x+", paste("I(x", 2:d, sep="^", collapse=")+"), ")", sep="")
      f <- as.formula(s.f)
      b.hat <- coef(lm(f))
      s <- paste(c(b.hat[1], 
            sapply(1:d, function(j) paste(b.hat[j+1], "*", ref, "^", j, sep=""))), 
            collapse=" + ")
      paste(s.pre, s, ", 0)", sep="")
    })
  })
  apply(f, 1, function(s) paste(s, collapse=" + "))
}
ns.formula(n) # Each line of this output is one basis formula: paste into Excel

İlk spline çıktı formülü (burada üretilen dördünden)

"IF(AND(1<=A1, A1<200), -1.26037447288906e-08 + 3.78112341937071e-08*A1^1 + -3.78112341940948e-08*A1^2 + 1.26037447313669e-08*A1^3, 0) + IF(AND(200<=A1, A1<500), 0.278894459758071 + -0.00418337927419299*A1^1 + 2.08792741929417e-05*A1^2 + -2.22580643138594e-08*A1^3, 0) + IF(AND(500<=A1, A1<800), -5.28222778473101 + 0.0291833541927414*A1^1 + -4.58541927409268e-05*A1^2 + 2.22309136420529e-08*A1^3, 0) + IF(AND(800<=A1, A1<1000), 12.500000000002 + -0.0375000000000067*A1^1 + 3.75000000000076e-05*A1^2 + -1.25000000000028e-08*A1^3, 0)"

Bunun Excel'de çalışması için tek yapmanız gereken çevredeki tırnak işaretlerini kaldırmak ve "=" işaretiyle önek kullanmaktır. (Biraz daha fazla çaba sarf Rederek, Excel tarafından içe aktarıldığında bu formüllerin kopyalarını doğru yerlere içeren bir dosya yazabilirsiniz.) Bir formül kutusuna yapıştırın ve sonra "A1", spline'ın hesaplanacağı değer. Diğer hücrelerin değerlerini hesaplamak için o hücreyi kopyalayıp yapıştırın (veya sürükleyip bırakın). B2: E: 102 hücrelerini bu formüllerle doldurdum, A2: A102 hücrelerindeki değerlerine başvurdum .xxx

Excel snippet'i


2
ns.formula.. R'de mi düşünüyorsun ?! Ciddi olarak yöntem çok yararlı görünüyor ama bu parametreleri almak için bir kesmek kesmek zorunda ironik gibi görünüyor. Bir tablo çıkarmak için çok yararlı olur ..
geotheory

Bu aptalca bir soru olabilir: ama çizdiğiniz 4 spline mı yoksa bir spline'ın 4 temeli mi?
Erosennin

@Erosennin "Tek bir spline" ile ne demek istediğine bağlıyım. Bu dört eğri, cevabımı tanıtan üç mermi noktasının tarif ettiği gibi, dört aralıkta parçalı kübik olan ve bu aralıkların buluştuğu üç noktada sürekli olarak ikinci olarak ayırt edilebilen bir spline için temel oluşturur.
whuber

Teşekkürler! Nitpick olmak istemedim, sadece dört spline (cevaptan) var ve temel olan dört eğri var gibi görünüyor. Yine, ben sadece anlamaya çalışıyorum ...
Erosennin

1
@Erosennin Sorun değil. Belki bu yardımcı olacaktır: "spline" bu dört eğrinin doğrusal birleşimi regresyon uydurma işlemiyle belirlenen şeydir. Bir başka deyişle: spline, bu dört eğrinin doğrusal kombinasyonları alınarak oluşturulabilen bir vektör eğrileri uzayından oluşur.
whuber

4

Şunu zaten yaptınız:

> rm(list=ls())
> set.seed(1066)
> x<- 1:1000
> y<- rep(0,1000)
> y[1:500]<- pmax(x[1:500]+(runif(500)-.5)*67*500/pmax(x[1:500],100),0.01)
> y[501:1000]<-500+x[501:1000]^1.05*(runif(500)-.5)/7.5
> df<-as.data.frame(cbind(x,y))
> library(splines)
> spline1 <- glm(y~ns(x,knots=c(500)),data=df,family=Gamma(link="log"))
> 

Şimdi size x = 12 için (tepki) iki farklı şekilde nasıl tahmin edeceğinizi göstereceğim: İlk önce tahmin fonksiyonunu kullanarak (kolay yol!)

> new.dat=data.frame(x=12)
> predict(spline1,new.dat,type="response")
       1 
68.78721 

İkinci yol, doğrudan model matrisine dayanmaktadır. Not Kullanılan expbağlantı işlevi günlük olduğundan kullandım.

> m=model.matrix( ~ ns(df$x,knots=c(500))) 
> prd=exp(coefficients(spline1) %*% t(m)) 
> prd[12]
[1] 68.78721

Yukarıda x = 12'ye karşılık geldiğinden 12. elemanı çıkardığımı unutmayın. Eğitim kümesinin dışında bir x için tahmin etmek istiyorsanız, tahmin işlevini tekrar kullanabilirsiniz. Diyelim ki x = 1100 için tahmini yanıt değerini bulmak istiyoruz.

> predict(spline1, newdata=data.frame(x=1100),type="response")
       1 
366.3483 

Cevabınız için teşekkürler! Ama hala kafam karıştı:. Bu matrisle ne yapacağımı bildiğimden emin değilim. Örneğin, x = 12 olsaydı, tahmin y = 68.78721 diyor, ancak bu matristen 12 ararken 0.016816392 elde ediyorum. X <500 için orijinal kesişim ve katsayısı sırasıyla 4.174603 ve 3.830416'dır. exp (4.174603 + 3.8304116 * 0.016816392) <> 68.78721. Ayrıca, x eğitim setinde olmasaydı x için değerleri nasıl alabilirim?
Eric

Cevabımı değiştirdim.
Stat

X eğitim setinde olmadığında durum için bir kod ekledim.
Stat

2
Tahmin fonksiyonunu kullanmadan x = 1100 için 366.3483 elde etmenin bir yolu var mı?
Eric

4

R rmspaketini kullanarak kübik regresyon spline'ları için kesik güç tabanını kullanmayı daha kolay bulabilirsiniz . Modeli taktıktan sonra Functionveya latexfonksiyonlarını kullanarak takılan spline fonksiyonunun cebirsel temsilini alabilirsiniz rms.


Teşekkür ederim. Aslında yanıtınızı burada göndermeden önce okudum istatistik.stackexchange.com/questions/67607/… . Sanırım rms ile neler yapabileceğimi daha iyi kavramaya ihtiyacım var.
Eric

İçin belgeler Function()gerçekten ne yaptığını söylemiyor. Benim durumumda (Rpubs ayrıntılarını görmek rpubs.com/EmilOWK/rms_splines , benim hemen) değer modelinde, ilk katsayısı ise , ikinci ve son katsayısı denklem her yerde görülmez. Aynısı, çıktısı için de geçerlidir . function(x = NA) {-2863.7787+245.72672* x-0.1391794*pmax(x-10.9,0)^3+0.27835881*pmax(x-50.5,0)^3-0.1391794*pmax(x-90.1,0)^3 } <environment: 0x556156e80db8>-2863.7787245.72672-873.0223latex()
Deleet

Functionile çalışır Glm()kullandığınızda rcsspline fonksiyonu olarak. Çıktı eğri çizgiyi en basit biçimde, RMS ders notlarımda ayrıntılı olarak açıklandığı gibi doğrusal kuyruk kısıtlamaları yokmuş gibi yazıyor .
Frank Harrell
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.