मैं कैसे तय करता हूं कि आरएएस में LOESS रिग्रेशन में क्या उपयोग करना है?


26

मैं आर में LOESS प्रतिगमन मॉडल चला रहा हूं, और मैं अलग-अलग नमूना आकारों के साथ 12 विभिन्न मॉडलों के आउटपुट की तुलना करना चाहता हूं। मैं वास्तविक विवरणों को अधिक विवरणों में वर्णित कर सकता हूं यदि यह प्रश्न का उत्तर देने में मदद करता है।

यहाँ नमूना आकार हैं:

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 रिग्रेशन मॉडल एक सतह फिट है, जहां प्रत्येक बेसबॉल पिच के X स्थान और Y स्थान का उपयोग स्वाइप करने के लिए किया जाता है, स्ट्राइक स्ट्राइब की संभावना। हालाँकि, मैं इन सभी 12 मॉडलों के बीच तुलना करना चाहूंगा, लेकिन एक ही स्पैन (यानी स्पैन = 0.5) सेट करने से अलग-अलग परिणाम मिलेंगे, क्योंकि इस तरह के नमूने की एक विस्तृत श्रृंखला है।

मेरा मूल प्रश्न यह है कि आप अपने मॉडल की अवधि कैसे निर्धारित करते हैं? एक उच्च स्पैन फिट को अधिक चिकना करता है, जबकि एक कम स्पैन अधिक रुझानों को पकड़ता है लेकिन बहुत कम डेटा होने पर सांख्यिकीय शोर का परिचय देता है। मैं छोटे नमूना आकार के लिए उच्च अवधि और बड़े नमूना आकार के लिए कम अवधि का उपयोग करता हूं।

मुझे क्या करना चाहिए? R में LOESS रिग्रेशन मॉडल के लिए स्पैन सेट करते समय अंगूठे का एक अच्छा नियम क्या है? अग्रिम में धन्यवाद!


ध्यान दें कि स्पैन नाप का मतलब अलग-अलग संख्या में टिप्पणियों के लिए अलग-अलग विंडो का आकार होगा।
ताल गैली

2
अक्सर मैं देख रहा हूं कि ब्लैक बॉक्स के रूप में लोटे को ज्यादा समझा जाता है। दुर्भाग्य से, यह सच नहीं है। स्कैटर प्लॉट और सुपरइम्पोज़्ड लूप कर्व को देखने के अलावा कोई दूसरा तरीका नहीं है और अगर यह डेटा में पैटर्न का वर्णन करने का अच्छा काम करता है। लोटे की फिटिंग में इरेक्शन और अवशिष्ट जाँच प्रमुख है
सनकूलू जूल

जवाबों:


14

एक क्रॉस-मान्यता का उपयोग अक्सर किया जाता है, उदाहरण के लिए k -fold, यदि उद्देश्य सबसे कम RMSEP के साथ एक फिट खोजना है। अपने डेटा को k समूहों में विभाजित करें और, प्रत्येक समूह को बदले में छोड़कर, loess मॉडल का उपयोग करके फिट करें k -1 समूहों को डेटा और स्मूथिंग पैरामीटर के एक चुने हुए मूल्य का करें, और उस मॉडल का उपयोग बाएं समूह के लिए भविष्यवाणी करने के लिए करें। बाहर छोड़ दिया समूह के लिए भविष्यवाणी की मान संग्रहीत और फिर दोहराते रहें जब तक के प्रत्येक कश्मीर समूहों बाहर छोड़ दिया गया है एक बार। अनुमानित मूल्यों के सेट का उपयोग करके, RMSEP की गणना करें। फिर आप जिस भी स्मूदिंग पैरामीटर पर धुन करना चाहते हैं उसके प्रत्येक मूल्य के लिए पूरी बात दोहराएं। उस स्मूथिंग पैरामीटर का चयन करें जो CV के तहत सबसे कम RMSEP देता है।

यह, जैसा कि आप देख सकते हैं, काफी कम्प्यूटेशनल रूप से भारी है। मुझे आश्चर्य होगा कि अगर सही सीवी के लिए एक सामान्यीकृत क्रॉस-वेलिडेशन (GCV) विकल्प नहीं था जिसे आप LOESS - Hastie et al (सेक्शन 6.2) के साथ उपयोग कर सकते हैं, यह इंगित करता है कि यह करना काफी सरल है और उनके अभ्यास में शामिल है। ।

मेरा सुझाव है कि आप Hastie et al के अध्याय 5 में अनुभाग 6.1.1, और 6.2 और इसके अलावा चौरसाई को नियमित करने के अनुभागों (जैसे कि सामग्री यहाँ भी लागू होती है) को नियमित रूप से पढ़ें। (2009) सांख्यिकीय शिक्षा के तत्व: डेटा खनन, अनुमान और भविष्यवाणी । द्वितीय संस्करण। स्प्रिंगर। पीडीएफ को मुफ्त में डाउनलोड किया जा सकता है।


8

मेरा सुझाव है कि सामान्यीकृत योगात्मक मॉडल (GAM देखें, R में mgcv पैकेज देखें)। मैं केवल उनके बारे में सीख रहा हूं, लेकिन वे स्वचालित रूप से यह पता लगाते हैं कि डेटा द्वारा कितना "विगली-नेस" उचित है। मैं यह भी देखता हूं कि आप द्विपद डेटा (स्ट्राइक बनाम स्ट्राइक नहीं) के साथ काम कर रहे हैं, इसलिए कच्चे डेटा का विश्लेषण करना सुनिश्चित करें (यानी आनुपातिकों को एकत्र न करें, कच्चे पिच-बाय-पिच डेटा का उपयोग करें) और परिवार का उपयोग करें = 'द्विपद' (यह मानते हुए कि आप R का उपयोग करने जा रहे हैं)। यदि आपको इस बारे में जानकारी है कि व्यक्तिगत पिटर और हिटर डेटा में क्या योगदान दे रहे हैं, तो आप संभवतः एक सामान्यीकृत योज्य मिश्रित मॉडल (GAMM, Gamm4 पैकेज को R में देखें) और यादृच्छिक प्रभाव (या फिर और फिर से घड़े और हिटर को निर्दिष्ट करके) अपनी शक्ति बढ़ा सकते हैं। , परिवार स्थापित करना = 'द्विपद')। आखिरकार, आप शायद X & Y की स्मूथी के बीच बातचीत के लिए अनुमति देना चाहते हैं, लेकिन मैंने कभी भी यह कोशिश नहीं की है इसलिए मुझे नहीं पता कि इसके बारे में कैसे जाना जाए। एक्स * वाई इंटरैक्शन के बिना एक गैम 4 मॉडल जैसा दिखेगा:

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

यह सोचने के लिए आइए, आप संभवतः प्रत्येक प्रकार के पिच प्रकार और बैटर की दृढ़ता के भीतर चिकनी को अलग होने देना चाहते हैं। यह समस्या को और अधिक कठिन बना देता है क्योंकि मुझे अभी तक यह पता नहीं चला है कि स्मूथ को एक से अधिक वेरिएबल्स द्वारा अलग-अलग तरीके से कैसे जाने दिया जाए जो बाद में अर्थपूर्ण विश्लेषणात्मक परीक्षणों का निर्माण करता है ( आर-एसआईजी-मिक्स्ड-मॉडल सूची में मेरे प्रश्न देखें )। तुम कोशिश कर सकते हो:

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)

लेकिन यह सहज का सार्थक परीक्षण नहीं देगा। इस समस्या को स्वयं हल करने के प्रयास में, मैंने बूटस्ट्रैप का उपयोग किया है जहां प्रत्येक पुनरावृत्ति पर मुझे पूर्ण डेटा स्थान के लिए मॉडल की भविष्यवाणियाँ प्राप्त होती हैं और फिर स्पेस में प्रत्येक बिंदु के लिए बूटस्टैप 95% CI की गणना करें और कोई भी प्रभाव जो मैं गणना करने के लिए परवाह करता हूं।


ऐसा प्रतीत होता है कि ggplot डिफ़ॉल्ट रूप से N> 1000 डेटापॉइंट के लिए अपने geom_smooth फ़ंक्शन के लिए GAM का उपयोग करता है।
उदाहरण

6

एक कम प्रतिगमन के लिए, एक गैर-सांख्यिकीविद् के रूप में मेरी समझ यह है कि आप दृश्य व्याख्या के आधार पर अपना समय चुन सकते हैं (कई स्पैन मूल्यों के साथ प्लॉट कम से कम चौरसाई के साथ एक का चयन कर सकते हैं जो उचित लगता है) या आप क्रॉस सत्यापन का उपयोग कर सकते हैं (CV) या सामान्यीकृत क्रॉस सत्यापन (GCV)। नीचे दिए गए कोड I का उपयोग टेकज़वा की उत्कृष्ट पुस्तक, इंट्रोडक्शन टू नॉनपरमेट्रिक रिग्रेशन (P219 से) के कोड पर आधारित एक लोस रिग्रेशन के GCV के लिए किया गया था ।

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

और अपने डेटा के साथ, मैंने निम्न कार्य किया:

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)

खेद है कि कोड बल्कि मैला है, यह आर का उपयोग करते हुए मेरी पहली बार में से एक था, लेकिन यह आपको यह अनुमान देना चाहिए कि सरल दृश्य निरीक्षण की तुलना में अधिक उद्देश्य तरीके से उपयोग करने के लिए जीएसवी को कम अंतराल के लिए सबसे अच्छा अवधि खोजने के लिए कैसे करना है। उपरोक्त भूखंड पर, आप उस स्पैन में रुचि रखते हैं जो फ़ंक्शन को कम करता है (प्लॉट किए गए "वक्र" पर सबसे कम)।


3

यदि आप एक जेनरल एडिटिव मॉडल पर स्विच करते हैं, तो आप mgcv पैकेज gam()से फ़ंक्शन का उपयोग कर सकते हैं , जिसमें लेखक यह आश्वासन देता है :

तो, कश्मीर का सटीक विकल्प आम तौर पर महत्वपूर्ण नहीं है: इसे पर्याप्त रूप से बड़ा चुना जाना चाहिए कि आप यथोचित रूप से अच्छी तरह से अंतर्निहित 'सत्य' का प्रतिनिधित्व करने के लिए स्वतंत्रता की पर्याप्त डिग्री होने पर सुनिश्चित हों, लेकिन उचित कम्प्यूटेशनल दक्षता बनाए रखने के लिए पर्याप्त छोटा है। स्पष्ट रूप से 'बड़ी' और 'छोटी' संबोधित की जा रही विशेष समस्या पर निर्भर हैं।

(k यहाँ चिकनी के लिए स्वतंत्रता पैरामीटर की डिग्री है, जो 'स्मूथनेस पैरामीटर के समान है'


धन्यवाद माइक :) मैंने पिछले जवाबों से देखा है कि आप जीएएम पर मजबूत हैं। मैं भविष्य में इस पर एक नज़र
डालूंगा

2

आप अपने स्वयं के क्रॉस सत्यापन लूप को खरोंच से लिख सकते हैं loess()जो statsपैकेज से फ़ंक्शन का उपयोग करता है ।

  1. एक खिलौना डेटा फ़्रेम सेट करें।

    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. क्रॉस-सत्यापन पाश को संभालने के लिए उपयोगी चर सेट करें।

    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. नेस्टेड forलूप को चलाएं, जिसमें प्रत्येक स्पैन संभावना पर span.seqऔर हर फोल्ड में पुनरावृति हो 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. 10 पारियों में से प्रत्येक से औसत क्रॉस-वेलिडेशन माध्य वर्ग त्रुटि की गणना करें:

    सीवी(10)=110Σमैं=110एमएसमैं
    cv.errors <- rowMeans(cv.error.mtrx)
  5. खोजें कि किस अवधि के परिणाम सबसे कम थे एमएस

    best.span.i <- which.min(cv.errors)
    best.span.i
    span.seq[best.span.i]
  6. अपने परिणाम प्लॉट करें।

    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)

साइट में आपका स्वागत है, @hynso। यह एक अच्छा उत्तर (+1) है, और मैं साइट के प्रतिरूपों के प्रारूपण विकल्पों के आपके उपयोग की सराहना करता हूं। ध्यान दें कि हम आर-विशिष्ट साइट नहीं हैं और विशेष रूप से आर के बारे में प्रश्नों के लिए हमारी सहिष्णुता 7 वर्षों में कम हो गई है क्योंकि यह क्यू पोस्ट किया गया था। संक्षेप में, यह बेहतर हो सकता है यदि आप भविष्य में दर्शकों के लिए यह w / स्यूडोकोड जो आर नहीं पढ़ते बढ़ाने सकता है
फिर से बहाल करते मोनिका - गुंग

कूल, सुझावों के लिए धन्यवाद @gung। मैं स्यूडोकोड जोड़ने पर काम करूंगा।
हाइन्सो


0

FANCOVA पैकेज आदर्श अवधि की गणना करने के जीसीवी या AIC का उपयोग कर एक स्वचालित तरीका प्रदान करता है:

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))
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.