R'deki LOESS regresyonunda hangi açıklığın kullanılacağına nasıl karar verebilirim?


26

R'de LOESS regresyon modelleri kullanıyorum ve 12 farklı modelin çıktılarını değişen örneklem boyutlarıyla karşılaştırmak istiyorum. Soruyu cevaplamaya yardımcı olursa gerçek modelleri daha ayrıntılı olarak anlatabilirim.

Örnek büyüklükler:

Fastballs vs RHH 2008-09: 2002
Fastballs vs LHH 2008-09: 2209
Fastballs vs RHH 2010: 527 
Fastballs vs LHH 2010: 449

Changeups vs RHH 2008-09: 365
Changeups vs LHH 2008-09: 824
Changeups vs RHH 2010: 201
Changeups vs LHH 2010: 330

Curveballs vs RHH 2008-09: 488
Curveballs vs LHH 2008-09: 483
Curveballs vs RHH 2010: 213
Curveballs vs LHH 2010: 162

LOESS regresyon modeli, her beyzbol sahasının X konumu ve Y konumunun sw, sallanma çarpma olasılığını tahmin etmek için kullanıldığı bir yüzeye uygundur. Bununla birlikte, bu modellerin 12'sinin hepsinin karşılaştırmasını yapmak isterim, ancak aynı aralıkların ayarlanması (yani span = 0.5) çok geniş bir örneklem büyüklüğü aralığı bulunduğundan farklı sonuçlar doğuracaktır.

Temel sorum şu, modelinizin kapsamını nasıl belirlersiniz? Daha yüksek bir açıklık, oturumu daha da düzleştirir, düşük bir açıklık ise daha fazla eğilim yakalar, ancak çok az veri varsa istatistiksel gürültü çıkarır. Daha küçük örnek boyutları için daha yüksek bir yayılma alanı ve daha büyük örnek boyutları için daha düşük bir yayılma alanı kullanıyorum.

Ne yapmalıyım? R'deki LOESS regresyon modelleri için span ayarı yapılırken iyi bir kural nedir? Şimdiden teşekkürler!


Yayılma ölçüsünün, farklı sayıda gözlem için farklı pencere boyutu anlamına geldiğine dikkat edin.
Tal Galili,

2
Genelde loess'in kara bir kutu gibi göründüğünü görüyorum. Ne yazık ki doğru değil. Dağılım grafiğine ve üst üste bindirilmiş olan eğri eğrisine bakmanın ve verideki kalıpları tanımlamanın iyi bir iş yapıp yapmadığını kontrol etmekten başka bir yol yoktur. İterasyon ve artık kontroller, takma diş takmada anahtardır .
suncoolsu

Yanıtlar:


14

Bir çapraz doğrulama genellikle kullanılır, örneğin , amaç en düşük RMSEP'e uygun bir yer bulmaksa, k- katlı. Verilerinizi k gruplarına ayırın ve sırayla her grubu dışarıda bırakarak, k -1 veri gruplarını ve yumuşatma parametresinin seçilen değerini kullanarak loess bir modele uyun ve soldaki grubu tahmin etmek için bu modeli kullanın. Soldaki grup için öngörülen değerleri saklayın ve sonra k gruplarının her biri bir kere bırakılana kadar tekrarlayın . Öngörülen değerler kümesini kullanarak, RMSEP'i hesaplayın. Ardından, ayarlamak istediğiniz yumuşatma parametresinin her değeri için her şeyi tekrarlayın. CV altında en düşük RMSEP veren yumuşatma parametresini seçin.

Bu, gördüğünüz gibi, oldukça hesaplamalı olarak ağır. LOESS - Hastie ve diğerleri (bölüm 6.2) ile kullanabileceğiniz gerçek CV'ye alternatif bir genelleştirilmiş onaylama (GCV) alternatifi olmasaydı, şaşırırdım, bunun yapılması oldukça basit ve alıştırmalarından birinde belirtilmiş. .

Bölüm 6.1.1, 6.1.2 ve 6.2'yi ve ayrıca düzleme yaylarının düzenlenmesi ile ilgili bölümleri (içerik burada da geçerlidir) Hastie ve arkadaşlarının 5. Bölümünde okumanızı öneririm. (2009) İstatistiksel Öğrenmenin Öğeleri: Veri madenciliği, çıkarım ve tahmin . 2. Baskı. Springer. PDF ücretsiz indirilebilir.


8

Genelleştirilmiş ilave modelleri kontrol etmenizi öneririm (GAM, R'deki mgcv paketine bakın). Sadece onlar hakkında kendimi öğrendim, ancak otomatik olarak ne kadar "gariplik" in veriler tarafından doğrulandığını buluyorlar. Ayrıca binom verisiyle (grev vs grev değil) uğraştığınızı da görüyorum, bu nedenle ham verileri analiz ettiğinizden emin olun (yani oranlara göre toplanmayın, ham adım adım verileri kullanın) ve ailesi kullanın = 'binomial' (R kullanacağını varsayarsak). Eğer bireysel atıcıların ve vurucuların verilere ne katkı sağladığına dair bilginiz varsa, genelleştirilmiş bir karma katkı modeli (GAMM, R'deki gamm4 paketine bakın) ve rasgele efektler olarak belirterek (ve tekrar , aile ayarı = 'binomial'). En sonunda, Muhtemelen X & Y'nin pürüzsüzlükleri arasında bir etkileşime izin vermek istersiniz, fakat bunu kendim hiç denemedim, bu yüzden nasıl devam edeceğimi bilemiyorum. X * Y etkileşimi olmayan bir gamm4 modeli şöyle görünür:

fit = gamm4(
    formula = strike ~ s(X) + s(Y) + pitch_type*batter_handedness + (1|pitcher) + (1|batter)
    , data = my_data
    , family = 'binomial'
)
summary(fit$gam)

Bir düşününce, pürüzsüzlüklerin her perde tipi ve meyilli el sıklığı seviyesine göre değişmesine izin vermek istersiniz. Bu, pürüzsüzlüklerin daha sonra anlamlı analitik testler üretecek şekilde birden fazla değişkene göre değişiklik göstermesine izin vermediğimi henüz bulmadığım için sorunu daha da zorlaştırıyor ( bkz. R-SIG-Karışık Modeller listesine sorgular ). Deneyebilirsin:

my_data$dummy = factor(paste(my_data$pitch_type,my_data$batter_handedness))
fit = gamm4(
    formula = strike ~ s(X,by=dummy) + s(Y,by=dummy) + pitch_type*batter_handedness + (1|pitcher) + (1|batter)
    , data = my_data
    , family = 'binomial'
)
summary(fit$gam)

Ancak bu, pürüzsüzlüklerin anlamlı testlerini vermez. Bu sorunu kendim çözmeye çalışırken, her yinelemede tam veri alanı için model tahminlerini aldığım ve daha sonra uzayda bulunan her nokta için çizme% 95 CI'lerini ve hesaplamayı düşündüğüm etkileri hesapladığımda bootstrap yeniden örnekleme kullandım.


Ggplot, varsayılan olarak N> 1000 veri noktaları için geom_smooth işlevi için GAM kullanmaktadır.
örneğiyle örnek öğrenme istatistikleri

6

Loess regresyonu için istatistiki olmayan bir anlayış olarak, görüşünüzü görsel yorumlamaya dayalı olarak seçebilmenizdir (çok sayıda açıklık değerine sahip olan arsa uygun görünen en az düzleştirme miktarına sahip olanı seçebilir) veya çapraz doğrulama kullanabilirsiniz (CV) veya genelleştirilmiş çapraz doğrulama (GCV). Aşağıda Takezawa'nın mükemmel kitabı olan, Parametrik Olmayan Regresyona Giriş (p219'dan) gelen koda dayalı bir loess regresyonun GCV'si için kullandım.

locv1 <- function(x1, y1, nd, span, ntrial)
{
locvgcv <- function(sp, x1, y1)
{
    nd <- length(x1)

    assign("data1", data.frame(xx1 = x1, yy1 = y1))
    fit.lo <- loess(yy1 ~ xx1, data = data1, span = sp, family = "gaussian", degree = 2, surface = "direct")
    res <- residuals(fit.lo)

    dhat2 <- function(x1, sp)
    {
        nd2 <- length(x1)
        diag1 <- diag(nd2)
        dhat <- rep(0, length = nd2)

        for(jj in 1:nd2){
            y2 <- diag1[, jj]
            assign("data1", data.frame(xx1 = x1, yy1 = y2))
            fit.lo <- loess(yy1 ~ xx1, data = data1, span = sp, family = "gaussian", degree = 2, surface = "direct")
            ey <- fitted.values(fit.lo)
            dhat[jj] <- ey[jj]
            }
            return(dhat)
        }

        dhat <- dhat2(x1, sp)
        trhat <- sum(dhat)
        sse <- sum(res^2)

        cv <- sum((res/(1 - dhat))^2)/nd
        gcv <- sse/(nd * (1 - (trhat/nd))^2)

        return(gcv)
    }

    gcv <- lapply(as.list(span1), locvgcv, x1 = x1, y1 = y1)
    #cvgcv <- unlist(cvgcv)
    #cv <- cvgcv[attr(cvgcv, "names") == "cv"]
    #gcv <- cvgcv[attr(cvgcv, "names") == "gcv"]

    return(gcv)
}

ve verilerimle aşağıdakileri yaptım:

nd <- length(Edge2$Distance)
xx <- Edge2$Distance
yy <- lcap

ntrial <- 50
span1 <- seq(from = 0.5, by = 0.01, length = ntrial)

output.lo <- locv1(xx, yy, nd, span1, ntrial)
#cv <- output.lo
gcv <- output.lo

plot(span1, gcv, type = "n", xlab = "span", ylab = "GCV")
points(span1, gcv, pch = 3)
lines(span1, gcv, lwd = 2)
gpcvmin <- seq(along = gcv)[gcv == min(gcv)]
spangcv <- span1[pgcvmin]
gcvmin <- cv[pgcvmin]
points(spangcv, gcvmin, cex = 1, pch = 15)

Maalesef kod oldukça özensiz, bu benim R kullanan ilk zamanlarımdan biriydi, ancak basit görsel muayeneden daha objektif bir şekilde kullanılacak en iyi açıklığı bulmak için loess regresyon için GSV'nin nasıl yapılacağı hakkında bir fikir vermeli. Yukarıdaki çizimde, işlevi en aza indiren açıklık ile ilgileniyorsunuz (çizilen "eğri" de en düşük).


3

Genelleştirilmiş bir modele geçerseniz, gam()işlevi bize yazarın temin ettiği mgcv paketinden kullanabilirsiniz :

Bu nedenle, k'nın kesin seçimi genel olarak kritik değildir: temelde 'gerçeği' makul derecede iyi temsil etmek için yeterince serbestlik derecesine sahip olduğunuzdan, makul bir hesaplama etkinliğini sağlayacak kadar küçük olduğundan makul derecede emin olacağınız kadar seçilmelidir. Açıkça 'büyük' ​​ve 'küçük' ele alınan belirli bir soruna bağlıdır.

( kburada, pürüzsüzlük parametresini göz ardı eden pürüzsüzlük için serbestlik derecesi parametresidir)


Teşekkürler Mike :) Önceki cevaplardan GAM'da güçlü olduğunuzu gördüm. Gelecekte bir göz
atacağım

2

Kendi çapraz doğrulama döngüsünü loess(), statspaketteki işlevi kullanan sıfırdan yazabilirsiniz .

  1. Bir oyuncak veri çerçevesi kurun.

    set.seed(4)
    x <- rnorm(n = 500)
    y <- (x)^3 + (x - 3)^2 + (x - 8) - 1 + rnorm(n = 500, sd = 0.5)
    plot(x, y)
    df <- data.frame(x, y)
  2. Çapraz doğrulama döngüsünü işlemek için yararlı değişkenler ayarlayın.

    span.seq <- seq(from = 0.15, to = 0.95, by = 0.05) #explores range of spans
    k <- 10 #number of folds
    set.seed(1) # replicate results
    folds <- sample(x = 1:k, size = length(x), replace = TRUE)
    cv.error.mtrx <- matrix(rep(x = NA, times = k * length(span.seq)), 
                            nrow = length(span.seq), ncol = k)
  3. forHer yayılma olasılığını yineleyerek span.seqve her katlamayı iç içe geçmiş bir döngü çalıştırın folds.

    for(i in 1:length(span.seq)) {
      for(j in 1:k) {
        loess.fit <- loess(formula = y ~ x, data = df[folds != j, ], span = span.seq[i])
        preds <- predict(object = loess.fit, newdata = df[folds == j, ])
        cv.error.mtrx[i, j] <- mean((df$y[folds == j] - preds)^2, na.rm = TRUE)
        # some predictions result in `NA` because of the `x` ranges in each fold
     }
    }
  4. CV(10)=110Σben=110MSEben
    cv.errors <- rowMeans(cv.error.mtrx)
  5. Hangi yayılma alanının en düşük sonuçlandığını bulunMSE.

    best.span.i <- which.min(cv.errors)
    best.span.i
    span.seq[best.span.i]
  6. Sonuçlarını çiz.

    plot(x = span.seq, y = cv.errors, type = "l", main = "CV Plot")
    points(x = span.seq, y = cv.errors, 
           pch = 20, cex = 0.75, col = "blue")
    points(x = span.seq[best.span.i], y = cv.errors[best.span.i], 
           pch = 20, cex = 1, col = "red")
    
    best.loess.fit <- loess(formula = y ~ x, data = df, 
                            span = span.seq[best.span.i])
    
    x.seq <- seq(from = min(x), to = max(x), length = 100)
    
    plot(x = df$x, y = df$y, main = "Best Span Plot")
    lines(x = x.seq, y = predict(object = best.loess.fit, 
                                 newdata = data.frame(x = x.seq)), 
          col = "red", lwd = 2)

Siteye hoş geldiniz, @hynso. Bu iyi bir cevap (+1) ve sitenin sağladığı biçimlendirme seçeneklerini kullandığınız için teşekkür ederim. R'ye özgü bir site olmamamız gerekmediğini ve özellikle R ile ilgili sorulara toleransımızın, bu Q'nun yayınlanmasından bu yana 7 yıl içinde azaldığını unutmayın. Kısacası, bu w / sözde
kodunu, R'yi

Harika, ipuçları için teşekkürler. Sözde kod eklemeye çalışacağım.
hynso,


0

FANCOVA paket GCV veya AIC kullanılarak İdeal aralığını hesaplamak için otomatik bir yol sağlar:

FTSE.lo3 <- loess.as(Index, FTSE_close, degree = 1, criterion = c("aicc", "gcv")[2], user.span = NULL, plot = F)
FTSE.lo.predict3 <- predict(FTSE.lo3, data.frame(Index=Index))
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.