วิธีตีความพล็อต QQ


172

ฉันกำลังทำงานกับชุดข้อมูลขนาดเล็ก (21 ข้อสังเกต) และมีพล็อต QQ ปกติต่อไปนี้ใน R:

ป้อนคำอธิบายรูปภาพที่นี่

เมื่อเห็นว่าพล็อตไม่รองรับความเป็นมาตรฐานฉันจะสรุปอะไรเกี่ยวกับการแจกแจงพื้นฐาน สำหรับฉันแล้วดูเหมือนว่าการแจกแจงที่เบ้ไปทางขวาจะเหมาะกว่าดีกว่าใช่มั้ย นอกจากนี้เราสามารถสรุปอะไรอีกจากข้อมูล


9
คุณถูกต้องว่ามันบ่งบอกถึงความเบ้ที่ถูกต้อง ฉันจะพยายามค้นหาบางส่วนของโพสต์ในการตีความแปลง QQ
Glen_b

3
คุณไม่จำเป็นต้องสรุป คุณเพียงแค่ต้องตัดสินใจว่าจะลองทำอะไรต่อไป ที่นี่ฉันจะพิจารณาการรูทสแควร์หรือบันทึกข้อมูล
Nick Cox

11
(1.5,2)(1.5,220)(0,70)

3
@Glen_b คำตอบสำหรับคำถามของฉันมีข้อมูลบางอย่าง: stats.stackexchange.com/questions/71065/ …และลิงก์ในคำตอบมีแหล่งข้อมูลที่ดีอีกอันหนึ่ง: stats.stackexchange.com/questions/52212/qq-plot-does-not
-match

อะไรนะ พล็อต QQ แสดงข้อมูลที่กระจายอย่างไม่เป็นทางการหรือไม่? ! ป้อนคำอธิบายรูปภาพที่นี่
David

คำตอบ:


292

หากค่าอยู่ในแนวเส้นการแจกแจงจะมีรูปร่างเหมือนกัน (ขึ้นอยู่กับตำแหน่งและสเกล) ตามการกระจายเชิงทฤษฎีที่เราได้คาดคะเนไว้

พฤติกรรมในท้องถิ่น : เมื่อดูค่าตัวอย่างที่เรียงลำดับแล้วบนแกน y และ (ประมาณ) คาดว่าปริมาณบนแกน x เราสามารถระบุได้ว่าค่าในบางส่วนของพล็อตแตกต่างจากแนวโน้มเชิงเส้นโดยรวมโดยดูว่า ค่าจะกระจุกตัวมากกว่าหรือน้อยกว่าการแจกแจงเชิงทฤษฎีที่สมมติในส่วนของพล็อต:

ส่วนต่างๆจากสี่แปลง QQ

อย่างที่เราเห็นคะแนนความเข้มข้นน้อยเพิ่มคะแนนความเข้มข้นมากขึ้นและมากกว่าที่ควรจะเพิ่มขึ้นอย่างรวดเร็วน้อยกว่าความสัมพันธ์เชิงเส้นโดยรวมที่จะแนะนำและในกรณีที่มากที่สุดนั้นจะตรงกับช่องว่างในความหนาแน่นของตัวอย่าง หรือขัดขวางค่าคงที่ (ค่าจัดชิดแนวนอน) สิ่งนี้ช่วยให้เรามองเห็นหางที่หนักหรือหางแสงและด้วยเหตุนี้ความเบ้มากขึ้นหรือเล็กลงกว่าการกระจายเชิงทฤษฎีและอื่น ๆ

ลักษณะโดยรวม:

นี่คือลักษณะของ QQ-plot (สำหรับตัวเลือกการกระจายโดยเฉพาะ) โดยเฉลี่ย :

ป้อนคำอธิบายรูปภาพที่นี่

แต่การสุ่มมีแนวโน้มที่จะปิดบังสิ่งต่าง ๆ โดยเฉพาะอย่างยิ่งกับกลุ่มตัวอย่างขนาดเล็ก:

ป้อนคำอธิบายรูปภาพที่นี่

n=21

ป้อนคำอธิบายรูปภาพที่นี่

n=21

คุณอาจพบว่าข้อเสนอแนะที่นี่มีประโยชน์เมื่อพยายามตัดสินใจว่าคุณควรกังวลเกี่ยวกับความโค้งหรือ wigginess จำนวนเท่าใด

คู่มือที่เหมาะสมกว่าสำหรับการตีความโดยทั่วไปจะรวมถึงการแสดงผลที่ขนาดตัวอย่างที่เล็กกว่าและขนาดใหญ่กว่า


18
นี่เป็นแนวทางที่ใช้งานได้จริงขอบคุณมากสำหรับการรวบรวมข้อมูลทั้งหมด
JohnK

4
ฉันเข้าใจว่ามันเป็นรูปร่างและประเภทของการเบี่ยงเบนจากความเป็นเชิงเส้นสิ่งที่สำคัญที่นี่ แต่ก็ยังแปลกที่แกนทั้งสองมีป้ายกำกับว่า "... ควิกไทล์" และแกนหนึ่งไปที่ 0.2 0.4 0.6 และอีกอันไปเป็น -2 -1 0 1 2. อีกครั้งดูเหมือนว่าตกลงที่จุดข้อมูลบางจุดอยู่ในช่วงกลาง 40% ของการแจกแจงเชิงทฤษฎี แต่พวกมันสามารถกระจายระหว่าง 3% ของการกระจายตัวของพวกเขาเองได้อย่างไรในขณะที่แกน y บนพล็อตขวาล่างของคุณ
Macond

2
@Macond แกน y แสดงค่า raw ของข้อมูลไม่ใช่ quantile ผมยอมรับว่ามาตรฐานแกน y จะทำให้สิ่งที่มากชัดเจนและผมก็มีความคิดว่าทำไม R ไม่ทำเช่นนี้ไปโดยปริยาย มีใครบางคนให้ความกระจ่างในเรื่องนี้หรือไม่?
Gordon Gustafson

4
@GordonGustafson เกี่ยวกับความคิดเห็นแรกของคุณกับ Macond มีเหตุผลที่ดีมากที่คุณไม่ได้มาตรฐานข้อมูล - เพราะพล็อต QQ คือการแสดงข้อมูล ! มันถูกออกแบบมาเพื่อแสดงข้อมูลในข้อมูลที่คุณให้กับฟังก์ชั่น (มันจะสมเหตุสมผลในการสร้างมาตรฐานข้อมูลที่คุณให้กับ boxplot หรือฮิสโตแกรม) หากคุณแปลงมันจะไม่แสดงข้อมูลอีกต่อไป (แม้ว่ารูปร่างในพล็อตอาจจะคล้ายกัน แต่คุณจะไม่แสดงตำแหน่งหรือสเกลบนพล็อตอีกต่อไป) ฉันไม่แน่ใจว่าสิ่งที่คุณคิดว่าจะชัดเจนในพล็อตมาตรฐาน - คุณสามารถชี้แจง?
Glen_b

2
@ZiyaoWei ไม่เครื่องแบบมีหางที่เบามาก ๆ - เนื้อหาไม่มีหางเลย ทุกอย่างอยู่ในระยะ 2 MADs ของศูนย์ ย่อหน้าแรกของคำตอบนี้ให้วิธีคิดที่ชัดเจนโดยทั่วไปเกี่ยวกับความหมายของ 'ที่หนักกว่า'
Glen_b

63

ฉันสร้างแอพมันวาวเพื่อช่วยแปลความหมายของแผน QQ ปกติ ลองนี้การเชื่อมโยง

ในแอพนี้คุณสามารถปรับความเบ้, ความเทล (kurtosis) และความทันสมัยของข้อมูลและคุณสามารถดูว่าฮิสโตแกรมและ QQ เปลี่ยนไปอย่างไร ในทางกลับกันคุณสามารถใช้มันในลักษณะที่กำหนดรูปแบบของพล็อต QQ จากนั้นตรวจสอบว่าควรมีความเบ้ ฯลฯ

สำหรับรายละเอียดเพิ่มเติมดูเอกสารประกอบในนั้น


ฉันรู้ว่าฉันมีพื้นที่ว่างไม่เพียงพอที่จะให้แอปนี้ออนไลน์ ตามคำขอของผมจะให้ทั้งสามชิ้นรหัส: sample.R, server.Rและui.Rที่นี่ ผู้ที่สนใจใช้งานแอพนี้อาจโหลดไฟล์เหล่านี้ลงใน Rstudio จากนั้นรันบนพีซีของคุณเอง

sample.Rไฟล์:

# 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.Rไฟล์:

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

ในที่สุดui.Rไฟล์:

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

1
ดูเหมือนความสามารถของแอพ Shiny ของคุณจะเต็มแล้ว บางทีคุณอาจเพียงแค่ให้รหัส
rsoren

1
@rsoren เพิ่มหวังว่าจะช่วยได้และฉันหวังว่าจะได้รับคำแนะนำ
Zhanxiong

ดีมาก! ฉันขอแนะนำให้เพิ่มตัวเลือกสำหรับการเปลี่ยนขนาดตัวอย่างและระดับการสุ่ม
Itamar

ไม่มีลิงก์ !!!! @Zhanxiong
Alireza Sanaee

ดูเหมือนว่าลิงก์จะไม่ตอบสนองหลังจากมีจำนวนคลิก จำกัด ทุกเดือน นั่นคือเหตุผลที่ฉันวางรหัสต้นฉบับที่นี่ (ตามที่ผู้ใช้คนอื่นร้องขอซึ่งพบปัญหาเดียวกันกับคุณ) คุณสามารถวางมันลงในสตูดิโอ R ของคุณและรันมันบนพีซีของคุณเอง
Zhanxiong

6

คำอธิบายที่เป็นประโยชน์ (และใช้งานง่าย) นั้นให้โดยศ Philippe Rigollet ในหลักสูตร MIT MOOC: 18.650 สถิติสำหรับการใช้งาน, ฤดูใบไม้ร่วง 2016 - ดูวิดีโอที่ 45 นาที

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

ฉันคัดลอกไดอะแกรมที่โหดร้ายซึ่งฉันเก็บไว้ในบันทึกของฉันเพราะฉันพบว่ามันมีประโยชน์มาก

แผนภาพร่างพล็อต QQ

ในตัวอย่างที่ 1 ในแผนภาพด้านบนซ้ายเราจะเห็นว่าในทางด้านขวาควอไทล์เชิงประจักษ์ (หรือตัวอย่าง) มีค่าน้อยกว่าควอนตัมเชิงทฤษฎี

Qe <Qt

α

ป้อนคำอธิบายรูปภาพที่นี่


3

เนื่องจากเธรดนี้ได้รับการพิจารณาแล้วว่าเป็น "วิธีตีความคิวคิวธรรมดา" โพสต์ StackExchange ฉันต้องการให้ผู้อ่านชี้ไปที่ความสัมพันธ์ทางคณิตศาสตร์ที่ดีและแม่นยำระหว่างพล็อตคิวคิวปกติและสถิติเคิร์ตซีเกิน

นี่มันคือ:

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

สรุปสั้น ๆ (และง่ายเกินไป) ได้รับดังต่อไปนี้ (ดูลิงค์สำหรับคำสั่งทางคณิตศาสตร์ที่แม่นยำยิ่งขึ้น): คุณสามารถเห็นความเกินจริงในพล็อตคิวคิวปกติเป็นระยะทางเฉลี่ยระหว่างควอนไทล์ข้อมูลและ โดยระยะทางจากข้อมูลถึงค่าเฉลี่ย ดังนั้นเมื่อค่าสัมบูรณ์ในส่วนท้ายของพล็อต qq โดยทั่วไปเบี่ยงเบนไปจากค่าปกติที่คาดหวังอย่างมากในทิศทางที่รุนแรงคุณจะมีความโด่งเป็นบวก

เนื่องจากความโด่งเป็นค่าเฉลี่ยของการเบี่ยงเบนเหล่านี้ซึ่งถ่วงน้ำหนักโดยระยะทางจากค่าเฉลี่ยค่าที่อยู่ใกล้กับจุดศูนย์กลางของแผนคิวคิวมีผลกระทบต่อการเกิดคูร์ติซีเพียงเล็กน้อย ดังนั้นความโด่งเกินจึงไม่เกี่ยวข้องกับจุดศูนย์กลางของการกระจายโดยที่ "จุดสูงสุด" คือ แต่ความรุนแรงเกินกำหนดเกือบทั้งหมดโดยการเปรียบเทียบส่วนท้ายของการแจกแจงข้อมูลกับการแจกแจงแบบปกติ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.