एक क्यूक्यू-प्लॉट के केंद्र के पास बाहरी बिंदुओं को हटाना


14

मैं R में Qqplot (और ggplot2 में डेटा खिला) के बारे में 1.2 मिलियन अंक के दो डेटा सेट के साथ एक QQ- साजिश की कोशिश कर रहा हूँ। गणना काफी आसान है, लेकिन परिणामी ग्राफ लोड करने के लिए धीमी गति से है, क्योंकि बहुत सारे बिंदु हैं। मैंने 10000 की संख्या को कम करने के लिए रैखिक सन्निकटन की कोशिश की है (यह वही है जो qqplot फ़ंक्शन वैसे भी करता है, यदि आपका एक डेटा सेट दूसरे से बड़ा है), लेकिन तब आप पूंछ में बहुत अधिक विवरण खो देते हैं।

केंद्र की ओर अधिकांश डेटा बिंदु मूल रूप से बेकार हैं - वे इतना ओवरलैप करते हैं कि शायद प्रति पिक्सेल लगभग 100 है। क्या पूंछों की ओर अधिक विरल डेटा खोए बिना, डेटा को हटाने का कोई सरल तरीका है?


मुझे उल्लेख करना चाहिए था, मैं वास्तव में एक डेटा सेट (जलवायु टिप्पणियों) की तुलना तुलनीय डेटा सेट (मॉडल रन) के संयोजन से कर रहा हूं। इसलिए मैं वास्तव में 87 मीटर मॉडल अंकों के साथ 1.2 मीटर अवलोकन बिंदुओं की तुलना कर रहा हूं, इसलिए approx()फ़ंक्शन फ़ंक्शन में आता qqplot()है।
n

जवाबों:


12

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

यहाँ कोड को दर्शाया गया है कि संपूर्ण डेटासेट के साथ-साथ चरम मान कैसे लिया जाए।

quant.subsample <- function(y, m=100, e=1) {
  # m: size of a systematic sample
  # e: number of extreme values at either end to use
  x <- sort(y)
  n <- length(x)
  quants <- (1 + sin(1:m / (m+1) * pi - pi/2))/2
  sort(c(x[1:e], quantile(x, probs=quants), x[(n+1-e):n]))
  # Returns m + 2*e sorted values from the EDF of y
}

वर्णन करने के लिए, यह नकली डेटासेट लगभग 1.2 मिलियन मूल्यों के दो डेटासेट के साथ-साथ उनमें से एक में "संदूषण" की बहुत कम मात्रा के बीच एक संरचनात्मक अंतर दिखाता है। इसके अलावा, इस परीक्षण को कठोर बनाने के लिए, मानों के अंतराल को एक डेटासेट से पूरी तरह से बाहर रखा गया है: क्यूक्यू प्लॉट को उन मूल्यों के लिए एक ब्रेक दिखाने की आवश्यकता है।

set.seed(17)
n.x <- 1.21 * 10^6
n.y <- 1.20 * 10^6
k <- floor(0.0001*n.x)
x <- c(rnorm(n.x-k), rnorm(k, mean=2, sd=2))
x <- x[x <= -3 | x >= -2.5]
y <- rbeta(n.y, 10,13)

हम प्रत्येक डेटासेट के 0.1% को सब्सक्राइब कर सकते हैं और 2420 पॉइंट्स को प्लॉट देते हुए अपने 0.1% एक्सट्रीम को शामिल कर सकते हैं। कुल बीता हुआ समय 0.5 सेकंड से कम है:

m <- .001 * max(n.x, n.y)
e <- floor(0.0005 * max(n.x, n.y))

system.time(
  plot(quant.subsample(x, m, e), 
       quant.subsample(y, m, e), 
       pch=".", cex=4,
       xlab="x", ylab="y", main="QQ Plot")
  )

कोई जानकारी खो जो भी है:

QQ प्लॉट


क्या आपको अपने उत्तरों का विलय नहीं करना चाहिए?
माइकल आर। चेर्निक

2
@ मीकल हाँ, आम तौर पर मैंने पहला उत्तर (वर्तमान एक) संपादित किया होगा। लेकिन प्रत्येक उत्तर लंबा है और वे अलग-अलग दृष्टिकोणों का उपयोग करते हैं, अलग-अलग प्रदर्शन विशेषताओं के साथ, इसलिए दूसरे को एक अलग उत्तर के रूप में पोस्ट करना सबसे अच्छा लगता था। वास्तव में, मुझे दूसरा (अनुकूली) एक के बाद पहला हटाने के लिए लुभाया गया था, लेकिन इसकी सापेक्ष गति कुछ लोगों से अपील कर सकती है, इसलिए इसे पूरी तरह से हटाना अनुचित होगा।
व्हीबर

यह मूल रूप से वही है जो मैं चाहता था, लेकिन इसके उपयोग के पीछे तर्क क्या है sin? क्या मैं सही हूं कि एक सामान्य सीडीएफ एक बेहतर कार्य होगा, अगर आपने मान लिया कि एक्स सामान्य रूप से वितरित किया गया था? क्या आपने सिर्फ पाप को चुना क्योंकि गणना करना आसान है?
naught101

क्या यह आपके अन्य उत्तर के समान डेटा होना चाहिए? यदि हां, तो प्लॉट इतने अलग क्यों हैं? x> 6 के सभी डेटा का क्या हुआ?
naught101

(3-2एक्स)एक्स2

11

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

डीn

(एक्स,y)टीy

विशेष रूप से विभिन्न लंबाई के डेटासेट के साथ सामना करने के लिए, देखभाल करने के लिए कुछ विवरण हैं। मैं इसे लंबे समय तक संबंधित क्वांटाइल्स द्वारा छोटे को प्रतिस्थापित करके करता हूं: वास्तव में, इसके वास्तविक डेटा मानों के बजाय छोटे वाले के EDF का एक टुकड़े-टुकड़े रैखिक सन्निकटन का उपयोग किया जाता है। ("छोटा" और "लंबा" सेटिंग द्वारा उलटा किया जा सकता है use.shortest=TRUE।)

यहाँ एक Rकार्यान्वयन है।

qq <- function(x0, y0, t.y=0.0005, use.shortest=FALSE) {
  qq.int <- function(x,y, i.min,i.max) {
    # x, y are sorted and of equal length
    n <-length(y)
    if (n==1) return(c(x=x, y=y, i=i.max))
    if (n==2) return(cbind(x=x, y=y, i=c(i.min,i.max)))
    beta <- ifelse( x[1]==x[n], 0, (y[n] - y[1]) / (x[n] - x[1]))
    alpha <- y[1] - beta*x[1]
    fit <- alpha + x * beta
    i <- median(c(2, n-1, which.max(abs(y-fit))))
    if (abs(y[i]-fit[i]) > thresh) {
      assemble(qq.int(x[1:i], y[1:i], i.min, i.min+i-1), 
               qq.int(x[i:n], y[i:n], i.min+i-1, i.max))
    } else {
      cbind(x=c(x[1],x[n]), y=c(y[1], y[n]), i=c(i.min, i.max))
    }
  }
  assemble <- function(xy1, xy2) {
    rbind(xy1, xy2[-1,])
  }
  #
  # Pre-process the input so that sorting is done once
  # and the most detail is extracted from the data.
  #
  is.reversed <- length(y0) < length(x0)
  if (use.shortest) is.reversed <- !is.reversed
  if (is.reversed) {
    y <- sort(x0)
    n <- length(y)
    x <- quantile(y0, prob=(1:n-1)/(n-1))    
  } else {
    y <- sort(y0)
    n <- length(y)
    x <- quantile(x0, prob=(1:n-1)/(n-1))    
  }
  #
  # Convert the relative threshold t.y into an absolute.
  #
  thresh <- t.y * diff(range(y))
  #
  # Recursively obtain points on the QQ plot.
  #
  xy <- qq.int(x, y, 1, n)
  if (is.reversed) cbind(x=xy[,2], y=xy[,1], i=xy[,3]) else xy
}

एक उदाहरण के रूप में मैं अपने पहले के उत्तर के रूप में सिम्युलेटेड डेटा का उपयोग करता हूं ( इस समय yमें अत्यधिक उच्च बहिर्वाह के साथ और थोड़ा अधिक संदूषण के xसाथ):

set.seed(17)
n.x <- 1.21 * 10^6
n.y <- 1.20 * 10^6
k <- floor(0.01*n.x)
x <- c(rnorm(n.x-k), rnorm(k, mean=2, sd=2))
x <- x[x <= -3 | x >= -2.5]
y <- c(rbeta(n.y, 10,13), 1)

चलो दहलीज के छोटे और छोटे मूल्यों का उपयोग करते हुए, कई संस्करणों की साजिश करते हैं। .0005 के मान पर और 1000 पिक्सेल लंबे मॉनिटर पर प्रदर्शित करने पर, हम प्लॉट पर हर जगह एक से आधे वर्टिकल पिक्सेल से अधिक की त्रुटि की गारंटी देंगे । इसे ग्रे में दिखाया गया है (केवल 522 अंक, लाइन सेगमेंट में शामिल हुए); मोटे सन्निकटन को इसके ऊपर प्लॉट किया गया है: पहले काले रंग में, फिर लाल रंग में (लाल बिंदु काले लोगों का एक उपसमूह होगा और उन्हें ओवरप्लोट करेगा), फिर नीले रंग में (जो फिर से एक सबसेट और ओवरप्लॉट हैं)। समय 6.5 (नीला) से 10 सेकंड (ग्रे) तक होता है। यह देखते हुए कि वे इतनी अच्छी तरह से स्केल करते हैं, एक बस एक आधे पिक्सेल के बारे में थ्रेशोल्ड के लिए एक सार्वभौमिक डिफ़ॉल्ट के रूप में उपयोग कर सकता है ( जैसे कि एक 1000-पिक्सेल उच्च मॉनिटर के लिए 1/2000) और इसके साथ किया जा सकता है।

qq.1 <- qq(x,y)
plot(qq.1, type="l", lwd=1, col="Gray",
     xlab="x", ylab="y", main="Adaptive QQ Plot")
points(qq.1, pch=".", cex=6, col="Gray")
points(qq(x,y, .01), pch=23, col="Black")
points(qq(x,y, .03), pch=22, col="Red")
points(qq(x,y, .1), pch=19, col="Blue")

QQ प्लॉट

संपादित करें

मैंने के लिए मूल कोड को संशोधित किया है qq अनुक्रमणिका के तीसरे स्तंभ को मूल दो सरणियों के सबसे लंबे (या सबसे कम, निर्दिष्ट के रूप में) में वापस करने , xऔरy , चुने गए बिंदुओं के अनुरूप। ये सूचकांक डेटा के "दिलचस्प" मूल्यों को इंगित करते हैं और इसलिए आगे के विश्लेषण के लिए उपयोगी हो सकते हैं।

मैंने बार-बार होने वाले मूल्यों के साथ होने वाली एक बग को हटा दिया x(जिसके कारण betaअपरिभाषित था)।


मैं qqकिसी दिए गए वेक्टर के लिए तर्कों की गणना कैसे करूं ? इसके अलावा, क्या आप पैकेज के qqसाथ अपने फ़ंक्शन का उपयोग करने की सलाह दे सकते हैं ggplot2? मैं का उपयोग कर के बारे में सोच रहा था ggplot2's stat_functionइस के लिए।
४४ पर

10

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

x <- rnorm(1200000)
mean.x <- mean(x)
sd.x <- sd(x)
quantiles.x <- quantile(x, probs = seq(0,1,b=0.000001))
quantiles.empirical <- qnorm(seq(0,1,by=0.000001),mean.x,sd.x)
plot(quantiles.x~quantiles.empirical) 

आपको पूंछ में कितनी गहराई तक जाना है, इसके आधार पर आपको seq को समायोजित करना होगा। यदि आप चतुर होना चाहते हैं तो आप प्लॉट को गति देने के लिए बीच में उस क्रम को भी पतला कर सकते हैं। उदाहरण के लिए उपयोग करना

plogis(seq(-17,17,by=.1))

एक संभावना है।


क्षमा करें, मेरा मतलब डेटा सेट से बिंदुओं को हटाना नहीं है, बस भूखंडों से।
n

यहां तक ​​कि उन्हें भूखंड से हटाना एक बुरा विचार है। लेकिन क्या आपने अपने डेटा सेट से पारदर्शिता परिवर्तन और / या यादृच्छिक नमूना लेने की कोशिश की है?
पीटर फ्लॉम -

2
भूखंड में अतिव्यापी बिंदुओं से निरर्थक स्याही को हटाने में क्या बात है, @Peter?
whuber

1

आप एक hexbinप्लॉट कर सकते हैं ।

x <- rnorm(1200000)
mean.x <- mean(x)
sd.x <- sd(x)
quantiles.x <- quantile(x, probs = seq(0,1,b=0.000001))
quantiles.empirical <- qnorm(seq(0,1,by=0.000001),mean.x,sd.x)

library(hexbin)
bin <- hexbin(quantiles.empirical[-c(1,length(quantiles.empirical))],quantiles.x[-c(1,length(quantiles.x))],xbins=100)
plot(bin)

मुझे नहीं पता कि क्या यह वास्तव में qq- प्लॉट किए गए डेटा पर लागू है (मेरे प्रश्न पर मेरी टिप्पणी भी देखें कि यह मेरे विशिष्ट कार्य के लिए क्यों नहीं चलेगा)। दिलचस्प बात हालांकि। मैं देख सकता हूं कि क्या मैं इसे व्यक्तिगत मॉडल बनाम अवलोकन पर काम कर सकता हूं।
n

1

एक अन्य विकल्प एक समानांतर बॉक्सप्लॉट है; आपने कहा कि आपके पास दो डेटा सेट हैं, इसलिए कुछ इस तरह है:

y <- rnorm(1200000)
x <- rnorm(1200000)
grpx <- cut(y,20)
boxplot(y~grpx)

और आप अपने डेटा के साथ इसे बेहतर बनाने के लिए विभिन्न विकल्पों को समायोजित कर सकते हैं।


मैं कभी भी लगातार डेटा का बड़ा प्रशंसक नहीं रहा, लेकिन यह एक दिलचस्प विचार है।
n
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.