Jak interpretować wykres QQ

172

Pracuję z małym zestawem danych (21 obserwacji) i mam następujący normalny wykres QQ w R:

wprowadź opis zdjęcia tutaj

Widząc, że fabuła nie obsługuje normalności, co mogę wnioskować o rozkładzie podstawowym? Wydaje mi się, że rozkład bardziej przesunięty w prawo byłby lepszym rozwiązaniem, prawda? Jakie inne wnioski możemy wyciągnąć z danych?

JohnK
źródło
9
Masz rację, że oznacza to prawidłową skośność. Spróbuję zlokalizować niektóre posty dotyczące interpretacji wykresów QQ.
Glen_b
3
Nie musisz kończyć; musisz tylko zdecydować, co następnie spróbować. Tutaj rozważę kwadratowe rootowanie lub rejestrowanie danych.
Nick Cox
11
Metoda trzypunktowa Tukey'a bardzo dobrze sprawdza się w przypadku używania wykresów QQ, aby pomóc ci zidentyfikować sposoby ponownego wyrażenia zmiennej w sposób, który czyni ją w przybliżeniu normalną. Na przykład wybierając przedostatnie punkty na ogonach i środkowy punkt na tej grafice (którą , i ), łatwo przekonasz się, że pierwiastek kwadratowy jest bliski ich linearyzacji. Można zatem wnioskować, że rozkład leżący u podstaw jest w przybliżeniu pierwiastkiem kwadratowym normalnym. ( 1,5 , 220 ) ( 0 , 70 )(1.5,2)(1.5,220)(0,70)
whuber
3
@Glen_b Odpowiedź na moje pytanie zawiera pewne informacje: stats.stackexchange.com/questions/71065/…, a link w odpowiedzi ma inne dobre źródło: stats.stackexchange.com/questions/52212/qq-plot-does-not -match-histogram
tpg2114
A co z tego Czy wykres QQ pokazuje niesymetrycznie rozłożone dane? ! wprowadź opis zdjęcia tutaj
David

Odpowiedzi:

292

Jeśli wartości leżą wzdłuż linii, rozkład ma ten sam kształt (do położenia i skali), co przypuszczalny rozkład teoretyczny.

Zachowanie lokalne : patrząc na posortowane wartości próbek na osi y i (przybliżone) oczekiwane kwantyle na osi x, możemy stwierdzić, w jaki sposób wartości w niektórych częściach wykresu różnią się lokalnie od ogólnego trendu liniowego, sprawdzając, czy wartości są bardziej lub mniej skoncentrowane niż teoretyczny rozkład przypuszczałby w tej części wykresu:

sekcje z czterech wykresów QQ

Jak widzimy, punkty mniej skoncentrowane wzrastają coraz bardziej punkty skoncentrowane, niż przypuszcza wzrost mniej gwałtownie, niż sugerowałaby ogólna relacja liniowa, aw skrajnych przypadkach odpowiadają luce w gęstości próbki (pokazuje skok prawie pionowy) lub skok stałych wartości (wartości wyrównane poziomo). To pozwala nam dostrzec ciężki ogon lub lekki ogon, a zatem skośność większą lub mniejszą niż rozkład teoretyczny i tak dalej.

Ogólny wygląd:

Oto co QQ-Działki wyglądać (dla poszczególnych wyborów dystrybucja) średnio :

wprowadź opis zdjęcia tutaj

Ale przypadkowość ma tendencję do zaciemniania rzeczy, szczególnie w przypadku małych próbek:

wprowadź opis zdjęcia tutaj

Zauważ, że przy wyniki mogą być znacznie bardziej zmienne niż tam pokazane - wygenerowałem kilka takich zestawów sześciu wykresów i wybrałem „ładny” zestaw, w którym można było zobaczyć kształt na wszystkich sześciu wykresach jednocześnie. Czasami proste relacje wyglądają na zakrzywione, relacje zakrzywione wyglądają prosto, ciężkie ogony po prostu wyglądają krzywo i tak dalej - przy tak małych próbkach często sytuacja może być znacznie mniej wyraźna:n=21

wprowadź opis zdjęcia tutaj

Można rozpoznać więcej funkcji niż te (na przykład dyskrecja, na przykład), ale przy nawet takie podstawowe cechy mogą być trudne do wykrycia; nie powinniśmy próbować „nadinterpretować” co najmniejszego poruszenia. Ponieważ rozmiary próbek stają się większe, ogólnie wykresy „stabilizują się”, a cechy stają się bardziej zrozumiałe niż reprezentujące hałas. [W przypadku niektórych bardzo ciężkich rozkładów rzadka duża wartość odstająca może uniemożliwić ładną stabilizację obrazu nawet przy dość dużych próbkach.]n=21

Można również znaleźć sugestię tu przydatne, gdy stara się zdecydować, ile należy się martwić o określonej wysokości krzywizny lub wiggliness.

Bardziej odpowiedni przewodnik dla interpretacji ogólnie obejmowałby również wyświetlacze przy mniejszych i większych rozmiarach próbek.

Glen_b
źródło
18
To bardzo praktyczny przewodnik, bardzo dziękuję za zebranie wszystkich tych informacji.
JohnK
4
Rozumiem, że liczy się tutaj kształt i rodzaj odchylenia od liniowości, ale nadal wygląda to dziwnie, że obie osie są oznaczone jako „... kwantyle”, a jedna oś ma wartość 0,2 0,4 0,6, a druga jako -2 -1 0 1 2. Znowu wygląda na to, że niektóre punkty danych mieszczą się w środkowym 40% rozkładu teoretycznego, ale jak można je rozdzielić między 3% ich własnego rozkładu, jak sugeruje oś y na twoim prawym dolnym wykresie?
Macond
2
@Macond Oś y pokazuje surowe wartości danych, a nie ich kwantyle. Zgadzam się, że ujednolicenie osi y spowodowałoby, że rzeczy byłyby znacznie jaśniejsze i nie mam pojęcia, dlaczego R domyślnie tego nie robi. Czy ktoś mógłby rzucić na to trochę światła?
Gordon Gustafson,
4
@GordonGustafson w odniesieniu do twojego pierwszego komentarza do Maconda istnieje bardzo dobry powód, dla którego nie ujednolicasz danych - ponieważ wykres QQ to wyświetlanie danych ! Jest przeznaczony do wyświetlania informacji w danych, które podajesz do funkcji (równie sensowne byłoby ujednolicenie danych, które dostarczasz do wykresu pudełkowego lub histogramu). Jeśli go przekształcisz, nie będzie to już wyświetlanie danych (chociaż kształt na wykresie może być podobny, nie wyświetlasz już położenia ani skali na wykresie). Nie jestem pewien, co według ciebie byłoby jaśniejsze w znormalizowanym wątku - czy możesz to wyjaśnić?
Glen_b
2
@ ZiyaoWei Nie, mundur ma naprawdę bardzo lekkie ogony - prawdopodobnie nie ma w ogóle ogonów. Wszystko znajduje się w odległości 2 MAD od centrum. Pierwszy akapit tej odpowiedzi daje jasny, ogólny sposób myślenia o tym, co oznacza „grubszy ogon”.
Glen_b
63

Zrobiłem błyszczącą aplikację, aby pomóc interpretować normalny wykres QQ. Wypróbuj ten link.

W tej aplikacji możesz dostosować skośność, ogonowość (kurtoza) i modalność danych, a także zobaczyć, jak zmienia się histogram i wykres QQ. I odwrotnie, możesz użyć go w sposób uwzględniający wzorzec wykresu QQ, a następnie sprawdź, jak powinna wyglądać skośność itp.

Więcej informacji znajduje się w dokumentacji w nim zawartej.


Zdałem sobie sprawę, że nie mam wystarczającej ilości wolnego miejsca, aby zapewnić tę aplikację online. Jako wniosek, podam wszystkie trzy kawałki kodu: sample.R, server.Ri ui.Rtu. Osoby zainteresowane uruchomieniem tej aplikacji mogą po prostu załadować te pliki do Rstudio, a następnie uruchomić je na własnym komputerze.

sample.RPliku:

# Compute the positive part of a real number x, which is $\max(x, 0)$.
positive_part <- function(x) {ifelse(x > 0, x, 0)}

# This function generates n data points from some unimodal population.
# Input: ----------------------------------------------------
# n: sample size;
# mu: the mode of the population, default value is 0.
# skewness: the parameter that reflects the skewness of the distribution, note it is not
#           the exact skewness defined in statistics textbook, the default value is 0.
# tailedness: the parameter that reflects the tailedness of the distribution, note it is
#             not the exact kurtosis defined in textbook, the default value is 0.

# When all arguments take their default values, the data will be generated from standard 
# normal distribution.

random_sample <- function(n, mu = 0, skewness = 0, tailedness = 0){
  sigma = 1

  # The sampling scheme resembles the rejection sampling. For each step, an initial data point
  # was proposed, and it will be rejected or accepted based on the weights determined by the
  # skewness and tailedness of input. 
  reject_skewness <- function(x){
      scale = 1
      # if `skewness` > 0 (means data are right-skewed), then small values of x will be rejected
      # with higher probability.
      l <- exp(-scale * skewness * x)
      l/(1 + l)
  }

  reject_tailedness <- function(x){
      scale = 1
      # if `tailedness` < 0 (means data are lightly-tailed), then big values of x will be rejected with
      # higher probability.
      l <- exp(-scale * tailedness * abs(x))
      l/(1 + l)
  }

  # w is another layer option to control the tailedness, the higher the w is, the data will be
  # more heavily-tailed. 
  w = positive_part((1 - exp(-0.5 * tailedness)))/(1 + exp(-0.5 * tailedness))

  filter <- function(x){
    # The proposed data points will be accepted only if it satified the following condition, 
    # in which way we controlled the skewness and tailedness of data. (For example, the 
    # proposed data point will be rejected more frequently if it has higher skewness or
    # tailedness.)
    accept <- runif(length(x)) > reject_tailedness(x) * reject_skewness(x)
    x[accept]
  }

  result <- filter(mu + sigma * ((1 - w) * rnorm(n) + w * rt(n, 5)))
  # Keep generating data points until the length of data vector reaches n.
  while (length(result) < n) {
    result <- c(result, filter(mu + sigma * ((1 - w) * rnorm(n) + w * rt(n, 5))))
  }
  result[1:n]
}

multimodal <- function(n, Mu, skewness = 0, tailedness = 0) {
  # Deal with the bimodal case.
  mumu <- as.numeric(Mu %*% rmultinom(n, 1, rep(1, length(Mu))))
  mumu + random_sample(n, skewness = skewness, tailedness = tailedness)
}

server.RPliku:

library(shiny)
# Need 'ggplot2' package to get a better aesthetic effect.
library(ggplot2)

# The 'sample.R' source code is used to generate data to be plotted, based on the input skewness, 
# tailedness and modality. For more information, see the source code in 'sample.R' code.
source("sample.R")

shinyServer(function(input, output) {
  # We generate 10000 data points from the distribution which reflects the specification of skewness,
  # tailedness and modality. 
  n = 10000

  # 'scale' is a parameter that controls the skewness and tailedness.
  scale = 1000

  # The `reactive` function is a trick to accelerate the app, which enables us only generate the data
  # once to plot two plots. The generated sample was stored in the `data` object to be called later.
  data <- reactive({
    # For `Unimodal` choice, we fix the mode at 0.
    if (input$modality == "Unimodal") {mu = 0}

    # For `Bimodal` choice, we fix the two modes at -2 and 2.
    if (input$modality == "Bimodal") {mu = c(-2, 2)}

    # Details will be explained in `sample.R` file.
    sample1 <- multimodal(n, mu, skewness = scale * input$skewness, tailedness = scale * input$kurtosis)
    data.frame(x = sample1)})

  output$histogram <- renderPlot({
    # Plot the histogram.
    ggplot(data(), aes(x = x)) + 
      geom_histogram(aes(y = ..density..), binwidth = .5, colour = "black", fill = "white") + 
      xlim(-6, 6) +
      # Overlay the density curve.
      geom_density(alpha = .5, fill = "blue") + ggtitle("Histogram of Data") + 
      theme(plot.title = element_text(lineheight = .8, face = "bold"))
  })

  output$qqplot <- renderPlot({
    # Plot the QQ plot.
    ggplot(data(), aes(sample = x)) + stat_qq() + ggtitle("QQplot of Data") + 
      theme(plot.title = element_text(lineheight=.8, face = "bold"))
    })
})

Wreszcie ui.Rplik:

library(shiny)

# Define UI for application that helps students interpret the pattern of (normal) QQ plots. 
# By using this app, we can show students the different patterns of QQ plots (and the histograms,
# for completeness) for different type of data distributions. For example, left skewed heavy tailed
# data, etc. 

# This app can be (and is encouraged to be) used in a reversed way, namely, show the QQ plot to the 
# students first, then tell them based on the pattern of the QQ plot, the data is right skewed, bimodal,
# heavy-tailed, etc.


shinyUI(fluidPage(
  # Application title
  titlePanel("Interpreting Normal QQ Plots"),

  sidebarLayout(
    sidebarPanel(
      # The first slider can control the skewness of input data. "-1" indicates the most left-skewed 
      # case while "1" indicates the most right-skewed case.
      sliderInput("skewness", "Skewness", min = -1, max = 1, value = 0, step = 0.1, ticks = FALSE),

      # The second slider can control the skewness of input data. "-1" indicates the most light tail
      # case while "1" indicates the most heavy tail case.
      sliderInput("kurtosis", "Tailedness", min = -1, max = 1, value = 0, step = 0.1, ticks = FALSE),

      # This selectbox allows user to choose the number of modes of data, two options are provided:
      # "Unimodal" and "Bimodal".
      selectInput("modality", label = "Modality", 
                  choices = c("Unimodal" = "Unimodal", "Bimodal" = "Bimodal"),
                  selected = "Unimodal"),
      br(),
      # The following helper information will be shown on the user interface to give necessary
      # information to help users understand sliders.
      helpText(p("The skewness of data is controlled by moving the", strong("Skewness"), "slider,", 
               "the left side means left skewed while the right side means right skewed."), 
               p("The tailedness of data is controlled by moving the", strong("Tailedness"), "slider,", 
                 "the left side means light tailed while the right side means heavy tailedd."),
               p("The modality of data is controlledy by selecting the modality from", strong("Modality"),
                 "select box.")
               )
  ),

  # The main panel outputs two plots. One plot is the histogram of data (with the nonparamteric density
  # curve overlaid), to get a better visualization, we restricted the range of x-axis to -6 to 6 so 
  # that part of the data will not be shown when heavy-tailed input is chosen. The other plot is the 
  # QQ plot of data, as convention, the x-axis is the theoretical quantiles for standard normal distri-
  # bution and the y-axis is the sample quantiles of data. 
  mainPanel(
    plotOutput("histogram"),
    plotOutput("qqplot")
  )
)
)
)
Zhanxiong
źródło
1
Wygląda na to, że pojemność Twojej aplikacji Błyszcząca się wyczerpała. Może mógłbyś po prostu podać kod
rsoren
1
@rsoren dodał, mam nadzieję, że to pomoże i czekam na sugestie.
Zhanxiong
Bardzo dobrze! Sugerowałbym również dodanie opcji zmiany wielkości próby i stopnia losowości.
Itamar
Link nie jest dostępny !!!! @Zhanxiong
Alireza Sanaee
Wygląda na to, że link nie reaguje po ograniczonej liczbie kliknięć co miesiąc. Dlatego wkleiłem tutaj kod źródłowy (zgodnie z żądaniem innych użytkowników, którzy napotkali ten sam problem). Możesz wkleić je do swojego studia R i uruchomić na własnym komputerze (po wcześniejszym załadowaniu wymaganych pakietów).
Zhanxiong,
6

Bardzo pomocne (i intuicyjne) wyjaśnienie podaje prof. Philippe Rigollet na kursie MIT MOOC: 18.650 Statystyka aplikacji, jesień 2016 - zobacz wideo po 45 minutach

https://www.youtube.com/watch?v=vMaKx9fmJHE

Skrupulatnie skopiowałem jego schemat, który przechowuję w swoich notatkach, ponieważ uważam go za bardzo przydatny.

Schemat szkicu wykresu QQ

W przykładzie 1, na lewym górnym diagramie widzimy, że w prawym ogonie kwantyl empiryczny (lub próbka) jest mniejszy niż kwantyl teoretyczny

Qe <Qt

Można to zinterpretować za pomocą funkcji gęstości prawdopodobieństwa. W przypadku tej samej wartości , kwantyl empiryczny znajduje się na lewo od kwantyla teoretycznego, co oznacza, że ​​prawy ogon rozkładu empirycznego jest „lżejszy” niż prawy ogon rozkładu teoretycznego, tj. Spada szybciej do wartości zbliżonych do zero.α

wprowadź opis zdjęcia tutaj

Xavier Bourret Sicotte
źródło
3

Ponieważ wątek ten został uznany za definitywny post na StackExchange „jak interpretować normalny wykres qq”, chciałbym wskazać czytelnikom ładny, precyzyjny związek matematyczny między normalnym wykresem qq a statystyką nadmiaru kurtozy.

Oto on:

https://stats.stackexchange.com/a/354076/102879

Krótkie (i zbyt uproszczone) podsumowanie podano w następujący sposób (patrz link, aby uzyskać bardziej precyzyjne stwierdzenia matematyczne): W rzeczywistości można zobaczyć nadmiar kurtozy na normalnym wykresie qq jako średnią odległość między kwantylami danych a odpowiadającymi im teoretycznymi kwantami normalnymi, ważonymi według odległości od danych do średniej. Tak więc, gdy wartości bezwzględne w ogonach wykresu qq zasadniczo odbiegają od oczekiwanych wartości normalnych znacznie w skrajnych kierunkach, masz dodatnią nadwyżkę kurtozy.

Ponieważ kurtoza jest średnią tych odchyleń ważoną odległościami od średniej, wartości w pobliżu środka wykresu qq mają niewielki wpływ na kurtozę. Stąd nadmiar kurtozy nie jest związany ze środkiem rozkładu, w którym znajduje się „szczyt”. Nadmiar kurtozy jest raczej prawie całkowicie determinowany przez porównanie ogonów rozkładu danych do rozkładu normalnego.

Peter Westfall
źródło