กราฟเส้นมีจำนวนบรรทัดมากเกินไปมีวิธีแก้ไขที่ดีกว่าไหม


30

ฉันพยายามกราฟจำนวนการกระทำของผู้ใช้ (ในกรณีนี้ "ไลค์") เมื่อเวลาผ่านไป

ดังนั้นฉันจึงมี "จำนวนการกระทำ" เป็นแกน y ของฉันแกน x ของฉันคือเวลา (สัปดาห์) และแต่ละบรรทัดแสดงถึงผู้ใช้หนึ่งคน

ปัญหาของฉันคือฉันต้องการดูข้อมูลนี้สำหรับกลุ่มผู้ใช้ประมาณ 100 คน กราฟเส้นจะกลายเป็นยุ่งเหยิงอย่างรวดเร็วด้วย 100 บรรทัด มีกราฟชนิดที่ดีกว่าที่ฉันสามารถใช้แสดงข้อมูลนี้หรือไม่ หรือฉันควรดูที่ความสามารถในการสลับเปิด / ปิดแต่ละบรรทัด?

ฉันต้องการดูข้อมูลทั้งหมดในครั้งเดียว แต่ความสามารถในการมองเห็นจำนวนการกระทำที่มีความแม่นยำสูงนั้นไม่สำคัญอย่างยิ่ง

ทำไมฉันถึงทำสิ่งนี้

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


5
คุณคิดว่าจะทำให้เส้นกึ่งโปร่งใสโดยการเปลี่ยนอัลฟาที่ใช้ในการพล็อตหรือไม่?
Fomite

1
@EpiGrad คำแนะนำที่สมเหตุสมผล แต่นั่นไม่ได้ทำให้ง่ายขึ้นที่จะเห็นสิ่งที่ฉันกำลังมองหา
กฎข้อบังคับนี้

1
@regulatethis ฉันขอแนะนำวิธี "เล็ก ๆ น้อย ๆ " โดยใช้facet_wrapฟังก์ชั่นของ ggplot2 เพื่อสร้างบล็อกของแผนภูมิ 4 x 5 (4 แถว 5 คอลัมน์ - ปรับขึ้นอยู่กับอัตราส่วนภาพที่ต้องการ) โดยมีผู้ใช้ประมาณ 5 คนต่อแผนภูมิ ควรมีความชัดเจนเพียงพอและคุณสามารถปรับขนาดผู้ใช้ได้สูงสุดประมาณ 10 คนต่อแผนภูมิทำให้มีที่ว่างสำหรับ 200 ที่มี 4x5 plot หรือ 360 กับ 6x6 plot
SlowLearner

คำตอบ:


31

ฉันอยากจะแนะนำการวิเคราะห์เบื้องต้น (มาตรฐาน) เพื่อลบเอฟเฟกต์หลักของ (a) การเปลี่ยนแปลงระหว่างผู้ใช้ (ข) การตอบสนองทั่วไปในหมู่ผู้ใช้ทั้งหมดต่อการเปลี่ยนแปลงและ (c) การเปลี่ยนแปลงทั่วไปจากช่วงเวลาหนึ่งไปยังอีก .

วิธีที่ง่ายที่สุด (แต่ไม่ดีที่สุด) ในการทำเช่นนี้คือการทำซ้ำ "median polish" บนข้อมูลเพื่อกวาดล้างมีเดียกลางของผู้ใช้และมีเดียไทม์ช่วงเวลา ระบุความราบรื่นที่เปลี่ยนแปลงไปมาก: พวกเขาคือผู้ใช้ที่คุณต้องการเน้นในกราฟิก

เนื่องจากสิ่งเหล่านี้เป็นข้อมูลที่นับเป็นความคิดที่ดีที่จะแสดงอีกครั้งโดยใช้รากที่สอง

ตัวอย่างของสิ่งที่อาจส่งผลต่อไปนี้เป็นชุดข้อมูลจำลอง 60 สัปดาห์ของผู้ใช้ 240 คนซึ่งโดยทั่วไปจะดำเนินการ 10 ถึง 20 การกระทำต่อสัปดาห์ การเปลี่ยนแปลงในผู้ใช้ทั้งหมดเกิดขึ้นหลังจากสัปดาห์ที่ 40 มีการ "บอก" สามอย่างเพื่อตอบสนองต่อการเปลี่ยนแปลง พล็อตด้านซ้ายแสดงข้อมูลดิบ: จำนวนการกระทำของผู้ใช้ (โดยผู้ใช้แยกตามสี) เมื่อเวลาผ่านไป ตามที่ถูกกล่าวหาในคำถามมันเป็นระเบียบ พล็อตที่ถูกต้องแสดงผลลัพธ์ของ EDA นี้ - ในสีเดียวกับก่อน - โดยผู้ใช้ที่ตอบสนองผิดปกติจะถูกระบุและไฮไลต์โดยอัตโนมัติ ข้อมูลระบุตัว - แม้ว่าจะเป็นแบบเฉพาะกิจ - มันสมบูรณ์และถูกต้อง (ในตัวอย่างนี้)

รูปที่ 1

นี่คือRรหัสที่สร้างข้อมูลเหล่านี้และทำการวิเคราะห์ สามารถปรับปรุงได้หลายวิธี ได้แก่

  • ใช้การขัดแบบมัธยฐานเต็มรูปแบบเพื่อค้นหาสิ่งตกค้างมากกว่าการทำซ้ำเพียงครั้งเดียว

  • การทำให้เศษตกค้างเกลี้ยงก่อนและหลังจุดเปลี่ยน

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

การทดสอบแสดงให้เห็นว่าวิธีการแก้ปัญหานี้ทำงานได้ดีสำหรับการนับจำนวนผู้ใช้ที่หลากหลาย, 12 - 240 หรือมากกว่า

n.users <- 240        # Number of users (here limited to 657, the number of colors)
n.periods <- 60       # Number of time periods
i.break <- 40         # Period after which change occurs
n.outliers <- 3       # Number of greatly changed users
window <- 1/5         # Temporal smoothing window, fraction of total period
response.all <- 1.1   # Overall response to the change
threshold <- 2        # Outlier detection threshold

# Create a simulated dataset
set.seed(17)
base <- exp(rnorm(n.users, log(10), 1/2))
response <- c(rbeta(n.users - n.outliers, 9, 1),
              rbeta(n.outliers, 5, 45)) * response.all
actual <- cbind(base %o% rep(1, i.break), 
                base * response %o% rep(response.all, n.periods-i.break))
observed <- matrix(rpois(n.users * n.periods, actual), nrow=n.users)

# ---------------------------- The analysis begins here ----------------------------#
# Plot the raw data as lines
set.seed(17)
colors = sample(colors(), n.users) # (Use a different method when n.users > 657)
par(mfrow=c(1,2))
plot(c(1,n.periods), c(min(observed), max(observed)), type="n",
     xlab="Time period", ylab="Number of actions", main="Raw data")
i <- 0
apply(observed, 1, function(a) {i <<- i+1; lines(a, col=colors[i])})
abline(v = i.break, col="Gray")  # Mark the last period before a change

# Analyze the data by time period and user by sweeping out medians and smoothing
x <- sqrt(observed + 1/6)                        # Re-express the counts
mean.per.period <- apply(x, 2, median)
residuals <- sweep(x, 2, mean.per.period)
mean.per.user <- apply(residuals, 1, median)
residuals <- sweep(residuals, 1, mean.per.user)

smooth <- apply(residuals, 1, lowess, f=window)  # Smooth the residuals
smooth.y <- sapply(smooth, function(s) s$y)      # Extract the smoothed values
ends <- ceiling(window * n.periods / 4)          # Prepare to drop near-end values
range <- apply(smooth.y[-(1:ends), ], 2, function(x) max(x) - min(x))

# Mark the apparent outlying users
thick <- rep(1, n.users)
thick[outliers <- which(range >= threshold * median(range))] <- 3
type <- ifelse(thick==1, 3, 1)

cat(outliers) # Print the outlier identifiers (ideally, the last `n.outliers`)

# Plot the residuals
plot(c(1,n.periods), c(min(smooth.y), max(smooth.y)), type="n",
     xlab="Time period", ylab="Smoothed residual root", main="Residuals")
i <- 0
tmp <- lapply(smooth, 
       function(a) {i <<- i+1; lines(a, lwd=thick[i], lty=type[i], col=colors[i])})
abline(v = i.break, col="Gray")

3
threshold2.5n.users <- 500n.outliers <- 100threshold <- 2.5

16

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

เราใช้เทคนิคนี้กับงานของฉันจริงๆแล้ว - ตอนแรกเราได้สร้างอนิเมชั่นที่แสดงพล็อตบรรทัดที่แตกต่างกัน 60 แบบเป็นพื้นหลังสำหรับกิจกรรม (การเปิดตัวชุดข้อมูลใหม่) จากนั้นก็พบว่าการทำเช่นนั้น ที่ไม่ได้ปรากฏในพล็อตเหลี่ยมเพชรพลอยที่มี 15 หรือ 30 facets ต่อหน้า

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

วิธีหนึ่งในการแก้ไขปัญหานี้คือการสร้างอนุกรมเวลา 100 (หรือ 240 ในตัวอย่างของ @ whuber) แยกจากกันแล้วถักเข้าด้วยกันเป็นภาพเคลื่อนไหว รหัสด้านล่างนี้จะสร้างภาพแยกประเภทนี้ 240 ภาพจากนั้นคุณสามารถใช้ซอฟต์แวร์สร้างภาพยนตร์ฟรีเพื่อเปลี่ยนเป็นภาพยนตร์ น่าเสียดายที่วิธีเดียวที่ฉันสามารถทำได้และรักษาคุณภาพที่ยอมรับได้คือไฟล์ขนาด 9MB แต่ถ้าคุณไม่จำเป็นต้องส่งมันผ่านอินเทอร์เน็ตที่อาจไม่เป็นปัญหาและต่อไปฉันแน่ใจว่ามีวิธีแก้ไขอีกมากมาย แอนิเมชั่เข้าใจ แพคเกจภาพเคลื่อนไหวใน R อาจมีประโยชน์ที่นี่ (ให้คุณทำทุกอย่างจากการโทรจาก R) แต่ฉันได้ทำให้มันง่ายสำหรับภาพประกอบนี้

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

นี่คือภาพนิ่งบางส่วนจากภาพยนตร์ซึ่งใช้ข้อมูลเดียวกับที่ @whuber สร้างขึ้น: ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่ ป้อนคำอธิบายรูปภาพที่นี่

# ---------------------------- Data generation - by @whuber ----------------------------#

n.users <- 240        # Number of users (here limited to 657, the number of colors)
n.periods <- 60       # Number of time periods
i.break <- 40         # Period after which change occurs
n.outliers <- 3       # Number of greatly changed users
window <- 1/5         # Temporal smoothing window, fraction of total period
response.all <- 1.1   # Overall response to the change
threshold <- 2        # Outlier detection threshold

# Create a simulated dataset
set.seed(17)
base <- exp(rnorm(n.users, log(10), 1/2))
response <- c(rbeta(n.users - n.outliers, 9, 1),
              rbeta(n.outliers, 5, 45)) * response.all
actual <- cbind(base %o% rep(1, i.break), 
                base * response %o% rep(response.all, n.periods-i.break))
observed <- matrix(rpois(n.users * n.periods, actual), nrow=n.users)

# ---------------------------- The analysis begins here ----------------------------#

# Alternative presentation of original data 
# 
setwd("eg animation")

for (i in 1:n.users){
    png(paste("line plot", i, ".png"),600,600,res=60)
    plot(c(1,n.periods), c(min(observed), max(observed)), 
        xlab="Time period", ylab="Number of actions", 
        main="Raw data", bty="l", type="n")
    if(i>1){apply(observed[1:i,], 1, function(a) {lines(a, col=rgb(0,100,0,50,maxColorValue=255))})}
    lines(observed[i,], col="black", lwd=2)
    abline(v = i.break, col="Gray")  # Mark the last period before a change
    text(1,60,i)
    dev.off()
}

##
# Then proceed to further analysis eg as set out by @whuber

+1 นี่เป็นความคิดที่ดี คุณยังสามารถเริ่มต้นหน้าต่างอุปกรณ์ใหม่โดยใช้windows()หรือquartz()จากนั้นซ้อนfor()ลูปของคุณไว้ภายใน หมายเหตุคุณจะต้องใส่Sys.sleep(1)ที่ด้านล่างของวงของคุณเพื่อที่คุณจะได้เห็นการวนซ้ำ แน่นอนว่ากลยุทธ์นี้ไม่ได้บันทึกไฟล์ภาพยนตร์จริงๆ - คุณต้องเรียกใช้ซ้ำทุกครั้งที่คุณต้องการรับชมอีกครั้ง
gung - Reinstate Monica

+1 แนวคิดที่ดีมาก - ฉันจะลองทำสิ่งนี้ในโอกาสต่อไปที่ฉันได้รับ (เช่น GTW, Mathematicaทำให้งานสั้น ๆ ในการสร้างและบันทึกภาพเคลื่อนไหวดังกล่าว)
whuber

แนวคิดที่น่าทึ่งภาพเคลื่อนไหวในบรรทัดเหล่านี้ (หรือรหัสและข้อมูลที่จะสร้าง) จะทำให้ภาคผนวกออนไลน์สุดเซ็กซี่สำหรับสิ่งพิมพ์
N Brouwer

7

หนึ่งในสิ่งที่ง่ายที่สุดที่จะทำคือ boxplot คุณสามารถดูได้ทันทีว่ามัธยฐานตัวอย่างของคุณเคลื่อนไหวอย่างไรและวันใดมีค่าผิดปกติมากที่สุด

day <- rep(1:10, 100)
likes <- rpois(1000, 10)
d <- data.frame(day, likes)
library(ggplot2)
qplot(x=day, y=likes, data=d, geom="boxplot", group=day)

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

สำหรับการวิเคราะห์ส่วนบุคคลฉันแนะนำให้นำตัวอย่างสุ่มขนาดเล็กจากข้อมูลของคุณและวิเคราะห์อนุกรมเวลาแยกกัน


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

มันขึ้นอยู่กับรูปแบบที่คุณต้องการให้เห็นในข้อมูลของคุณบางทีถ้าคุณสามารถบอกเราได้ว่าคุณพยายามค้นหาอะไรเราสามารถหาวิธีแก้ปัญหาได้
jem77bfp

สำหรับชุดย่อยของผู้ใช้ของฉัน (ผู้ใช้อันดับต้น ๆ ) ฉันต้องการค้นหาว่าแอปพลิเคชันใดที่อาจไม่ชอบเวอร์ชันใหม่ของแอพพลิเคชั่นที่เปิดตัวในวันที่กำหนด ฉันกำลังมองหาจำนวนการกระทำที่ลดลงอย่างมากจากผู้ใช้แต่ละคน
ฏระเบียบ

ยินดีต้อนรับสู่เว็บไซต์ @ jem77bfp เขาบอกว่าเขาต้องการดูข้อมูลทั้งหมด แต่จะดีกว่าถ้ามีรายละเอียดเพิ่มเติมฉันเห็นด้วย
Peter Flom - Reinstate Monica

+1 - แทนที่จะแสดงให้เห็นแผนการแปลงแม้ว่ามันจะมีประโยชน์ในการเชื่อมต่อสถิติสรุปในกราฟเส้น ดูคำตอบของฉันสำหรับตัวอย่างและการสนทนาด้านล่าง
Andy W

7

แน่ใจ ก่อนเรียงลำดับตามจำนวนการกระทำโดยเฉลี่ย จากนั้นสร้าง (พูด) 4 กราฟแต่ละเส้นมี 25 บรรทัดหนึ่งบรรทัดสำหรับแต่ละควอไทล์ นั่นหมายความว่าคุณสามารถลดแกน y (แต่ทำให้ฉลากแกน y ชัดเจน) และด้วย 25 บรรทัดคุณสามารถเปลี่ยนแปลงได้ตามประเภทของเส้นและสีและอาจจะเป็นสัญลักษณ์การพล็อต

จากนั้นสแต็กกราฟในแนวตั้งด้วยแกนเวลาเดียว

นี่จะค่อนข้างง่ายใน R หรือ SAS (อย่างน้อยถ้าคุณมี v. 9 ของ SAS)


2
+1 - ฉันอยากจะแนะนำให้มีจำนวนบรรทัดน้อยลงต่อหลายเส้น ดูโพสต์บล็อกที่เกี่ยวข้องในเรื่องและตัวอย่าง การเรียงลำดับยังเป็นแนวคิดที่ยอดเยี่ยมและสิ่งที่มีศักยภาพอื่น ๆ อาจรวมถึงค่าที่พื้นฐานหรือการติดตามหรือมาตรการการเปลี่ยนแปลง (เช่นความชันเชิงบวกหรือเชิงลบการเปลี่ยนแปลงเปอร์เซ็นต์ ฯลฯ )
Andy W

ดี! บล็อกชุมชนคืออะไร หนึ่งเข้าถึงหรือเขียนมันได้อย่างไร
Peter Flom - Reinstate Monica

3
อย่าลังเลที่จะแวะไปที่ห้องแชทแจกเบ้อย่าเพื่อดูรายละเอียดเกี่ยวกับวิธีเข้าร่วมบล็อก เรามีเสมอเปิดให้บริการสำหรับผลงานเพิ่มเติมจากสมาชิกในชุมชน
Andy W

0

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


คุณมีบางสิ่งในใจที่แตกต่างจากวิธีการแก้ปัญหาของ Peter Ellis ที่โพสต์ไว้ที่นี่หรือไม่? ถ้าเป็นเช่นนั้นคุณช่วยอธิบายเกี่ยวกับมันได้ไหม?
whuber

0

หากคุณสนใจการเปลี่ยนแปลงสำหรับผู้ใช้รายบุคคลมากที่สุดนี่อาจเป็นสถานการณ์ที่ดีสำหรับคอลเล็กชัน Sparklines (เช่นตัวอย่างจาก The Pudding ):

ตัวอย่างของเส้นแบบประกายไฟจาก pudding.cool

รายละเอียดเหล่านี้ค่อนข้างละเอียด แต่คุณสามารถแสดงแผนภูมิได้มากขึ้นในคราวเดียวโดยการลบป้ายกำกับแกนและหน่วยออก

มีเครื่องมือสร้างข้อมูลหลายตัวในตัว ( Microsoft Excel มีเส้นแบบประกายไฟ ) แต่ฉันเดาว่าคุณต้องการดึงแพคเกจเพื่อสร้างในอาร์

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