इस सूत्र में कहीं और मैंने बिंदुओं को कम करने के एक सरल लेकिन कुछ हद तक तदर्थ समाधान का प्रस्ताव दिया । यह तेज़ है, लेकिन महान भूखंडों के उत्पादन के लिए कुछ प्रयोग की आवश्यकता है। वर्णित किया जाने वाला समाधान परिमाण धीमा (1.2 मिलियन अंकों के लिए 10 सेकंड तक) का एक क्रम है, लेकिन अनुकूली है और स्वचालित है। बड़े डेटासेट के लिए, यह पहली बार अच्छे परिणाम देने के लिए चाहिए और ऐसा बहुत जल्दी करना चाहिए।
डीn
( एक्स , वाई)टी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
अनुक्रमणिका के तीसरे स्तंभ को मूल दो सरणियों के सबसे लंबे (या सबसे कम, निर्दिष्ट के रूप में) में वापस करने , x
औरy
, चुने गए बिंदुओं के अनुरूप। ये सूचकांक डेटा के "दिलचस्प" मूल्यों को इंगित करते हैं और इसलिए आगे के विश्लेषण के लिए उपयोगी हो सकते हैं।
मैंने बार-बार होने वाले मूल्यों के साथ होने वाली एक बग को हटा दिया x
(जिसके कारण beta
अपरिभाषित था)।
approx()
फ़ंक्शन फ़ंक्शन में आताqqplot()
है।