วิธีการที่ดีสำหรับแปลงความหนาแน่นของตัวแปรที่ไม่เป็นลบใน R?


36
plot(density(rexp(100))

เห็นได้ชัดว่าความหนาแน่นทั้งหมดทางด้านซ้ายของศูนย์แสดงถึงอคติ

ฉันต้องการสรุปข้อมูลบางอย่างสำหรับผู้ที่ไม่ใช่นักสถิติและฉันต้องการหลีกเลี่ยงคำถามเกี่ยวกับสาเหตุที่ข้อมูลที่ไม่ใช่เชิงลบมีความหนาแน่นทางด้านซ้ายของศูนย์ แปลงสำหรับการตรวจสอบแบบสุ่ม ฉันต้องการแสดงการกระจายของตัวแปรโดยกลุ่มการรักษาและกลุ่มควบคุม การแจกแจงแบบ exponential-ish ฮิสโทแกรมมีความซับซ้อนด้วยเหตุผลหลายประการ

ค้นหา Google อย่างรวดเร็วทำให้ผมทำงานโดยสถิติในเมล็ดที่ไม่ใช่เชิงลบเช่น: นี้

แต่มีการนำมาใช้ใน R หรือไม่? ของวิธีการดำเนินการใด ๆ ของพวกเขา "ดีที่สุด" อย่างใดสำหรับสถิติเชิงพรรณนา?

แก้ไข: แม้ว่าfromคำสั่งสามารถแก้ไขปัญหาปัจจุบันของฉันได้ก็คงจะดีที่จะรู้ว่ามีใครใช้เมล็ดในวรรณคดีโดยใช้การประมาณความหนาแน่นแบบไม่ลบ


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

6
plot(density(rexp(100), from=0))?
Stéphane Laurent

4
สิ่งหนึ่งที่บางครั้งฉันทำสำเร็จค่อนข้างประสบความสำเร็จคือการได้รับ kde บนท่อนซุงและจากนั้นเปลี่ยนการประมาณความหนาแน่น (ไม่ลืมจาโคเบียน) ความเป็นไปได้อีกอย่างก็คือการใช้การตั้งค่าการประเมินความหนาแน่นของ log-spline เพื่อให้ทราบเกี่ยวกับขอบเขต
Glen_b


1
ฉันพูดถึงวิธีการแปลงที่กล่าวถึงโดย @Glen_b ในstata-journal.com/sjpdf.html?articlenum=gr0003 (ดู pp.76-78) ศูนย์อาจได้รับการอำนวยความสะดวกโดยใช้บันทึก (x + 1) แทนที่จะบันทึกและแก้ไข Jacobian
Nick Cox

คำตอบ:


21

xx

Kh(y,x)=exp(12((yx)/h)2)/2π

w(x)=1/0K(y,x)dy=11Φx,h(0)

Φxh

000

รูป

0


รหัส R

densityฟังก์ชั่นในRจะบ่นว่าผลรวมของน้ำหนักที่ไม่ได้เป็นความสามัคคีเพราะต้องการหนึ่งมากกว่าตัวเลขจริงทั้งหมดจะเป็นความสามัคคีในขณะที่วิธีการนี้จะทำให้หนึ่งมากกว่าตัวเลขบวกเท่ากับความสามัคคี ในฐานะที่เป็นเช็คอินทิกรัลหลังจะถูกประเมินเป็นผลรวมของ Riemann

set.seed(17)
x <- rexp(1000)
#
# Compute a bandwidth.
#
h <- density(x, kernel="gaussian")$bw # $
#
# Compute edge weights.
#
w <- 1 / pnorm(0, mean=x, sd=h, lower.tail=FALSE)
#
# The truncated weighted density is what we want.
#
d <- density(x, bw=h, kernel="gaussian", weights=w / length(x))
d$y[d$x < 0] <- 0
#
# Check: the integral ought to be close to 1:
#
sum(d$y * diff(d$x)[1])
#
# Plot the two density estimates.
#
par(mfrow=c(1,1))
plot(d, type="n", main="Default and truncated densities", xlim=c(-1, 5))
polygon(density(x, kernel="gaussian", bw=h), col="#6060ff80", border=NA)
polygon(d, col="#ff606080", border=NA)
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)

21

อีกทางเลือกหนึ่งคือวิธีการของ Kooperberg และเพื่อนร่วมงานโดยใช้การประเมินความหนาแน่นโดยใช้เส้นโค้งเพื่อประมาณความหนาแน่นของบันทึกข้อมูล ฉันจะแสดงตัวอย่างโดยใช้ข้อมูลจากคำตอบของ @ whuber ซึ่งจะช่วยให้การเปรียบเทียบของวิธีการ

set.seed(17)
x <- rexp(1000)

คุณจะต้องlogsplineแพคเกจติดตั้งสำหรับการนี้ ติดตั้งหากไม่ได้:

install.packages("logspline")

โหลดแพ็คเกจและประเมินความหนาแน่นโดยใช้logspline()ฟังก์ชั่น:

require("logspline")
m <- logspline(x)

ในต่อไปนี้ฉันคิดว่าวัตถุdจากคำตอบของ @ whuber มีอยู่ในพื้นที่ทำงาน

plot(d, type="n", main="Default, truncated, and logspline densities", 
     xlim=c(-1, 5), ylim = c(0, 1))
polygon(density(x, kernel="gaussian", bw=h), col="#6060ff80", border=NA)
polygon(d, col="#ff606080", border=NA)
plot(m, add = TRUE, col = "red", lwd = 3, xlim = c(-0.001, max(x)))
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)
rug(x, side = 3)

พล็อตที่ได้จะแสดงด้านล่างพร้อมกับความหนาแน่นของสายการบินที่แสดงโดยเส้นสีแดง

ค่าเริ่มต้นตัดทอนและความหนาแน่นของสายบันทึก

นอกจากนี้การสนับสนุนสำหรับความหนาแน่นสามารถระบุได้ผ่านการขัดแย้งและlbound uboundหากเราต้องการสมมติว่าความหนาแน่นเป็น 0 ทางซ้ายของ 0 และมีความไม่ต่อเนื่องที่ 0 เราสามารถใช้lbound = 0ในการเรียกไปlogspline()เช่น

m2 <- logspline(x, lbound = 0)

ให้การประมาณค่าความหนาแน่นต่อไปนี้ (แสดงไว้ที่นี่พร้อมกับสายบันทึกดั้งเดิมmพอดีเนื่องจากตัวเลขก่อนหน้านี้ไม่ว่าง)

plot.new()
plot.window(xlim = c(-1, max(x)), ylim = c(0, 1.2))
title(main = "Logspline densities with & without a lower bound",
      ylab = "Density", xlab = "x")
plot(m,  col = "red",  xlim = c(0, max(x)), lwd = 3, add = TRUE)
plot(m2, col = "blue", xlim = c(0, max(x)), lwd = 2, add = TRUE)
curve(exp(-x), from=0, to=max(x), lty=2, add=TRUE)
rug(x, side = 3)
axis(1)
axis(2)
box()

พล็อตที่เกิดจะแสดงด้านล่าง

การเปรียบเทียบค่าประมาณความหนาแน่นของไฟล์บันทึกที่มีและไม่มีขอบเขตต่ำกว่าในส่วนสนับสนุน

xx=0x


1
01

@whuber คำถามที่ดี ฉันเพิ่งเจอวิธีนี้เมื่อเร็ว ๆ นี้ตัวเอง ฉันสงสัยว่าเป็นคำถามที่ดีที่จะถามที่นี่เนื่องจากวิธีการที่ถูกตัดทอนและ logpline เป็นเพียงการประมาณการของความหนาแน่นที่แท้จริงมีความแตกต่างอย่างมีนัยสำคัญในทางสถิติหรือไม่? ฉันไม่แน่ใจว่าทำไมมันถึงทำได้ดีที่ศูนย์แม้ว่า ฉันก็ซาบซึ้งที่รู้ว่าเพราะอะไร
Reinstate Monica - G. Simpson

@GavinSimpson ขอบคุณสำหรับคำตอบที่ดีนี้ คุณสามารถทำซ้ำพล็อตสุดท้ายด้วยเวอร์ชันล่าสุดได้logsplineหรือไม่? x = 0สำหรับผมความหนาแน่นของทั้งสองที่ล้อมรอบและมากมายรุ่นไปที่ศูนย์ที่
cel

4

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


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

1
ฉันชอบแปลงความหนาแน่นด้วย แต่คุณต้องพิจารณาผู้ชมของคุณ
Peter Flom - Reinstate Monica

1
ต้องเห็นด้วยกับ @PeterFlom ในอันนี้ อย่าซับซ้อนเกินไปหากผู้ชมของคุณไม่มีความรู้ทางสถิติ นอกจากนี้คุณยังสามารถทำกล่องแปลงเปรียบเทียบ / ขนานกับการวางซ้อนของแปลงผีเสื้อที่ด้านบน ด้วยวิธีนี้สามารถสรุปข้อมูลสรุปพล็อตบ็อกซ์พร้อมข้อมูลทั้งหมดได้
doug.numbers

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

2

ในฐานะที่เป็นความคิดเห็นStéphaneคุณสามารถใช้from = 0และนอกจากนี้คุณสามารถแสดงค่าของคุณภายใต้เส้นโค้งความหนาแน่นด้วยrug (x)


4
แก้ไขให้ถูกต้องหากฉันผิด แต่from=0ดูเหมือนว่าจะระงับการวางแผนสำหรับค่าที่ต่ำกว่า 0; มันไม่ได้แก้ไขการคำนวณสำหรับความจริงที่ว่าบางส่วนของการจัดจำหน่ายที่ได้รับป้ายด้านล่าง 0.
นิคค็อกซ์

1
ถูกต้อง. การใช้fromคำสั่งให้พล็อตที่ดูเหมือนว่ามันมีจุดสูงสุดอยู่ทางด้านขวาของศูนย์ แต่ถ้าคุณดูฮิสโทแกรมที่มีถังขยะขนาดเล็กอย่างต่อเนื่องข้อมูลจำนวนมากจะแสดงจุดสูงสุด AT เป็นศูนย์ นี่fromเป็นเพียงกลลวงกราฟิก
generic_user

@ NickCox ฉันไม่แน่ใจ แต่ฉันไม่คิดว่าจะfrom=0ระงับสิ่งใด มันเพิ่งเริ่ม "กริด" ที่ศูนย์
Stéphane Laurent

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

@NickCox คำสั่งdensity(rexp(100), from=0)ไม่มีส่วนเกี่ยวข้องกับกราฟิก
Stéphane Laurent
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.