Çizgi grafikte çok fazla çizgi var, daha iyi bir çözüm var mı?


30

Zaman içinde, kullanıcıların (bu durumda, "beğenmeler") eylemlerinin sayısını grafik çizmeye çalışıyorum.

Dolayısıyla, y eksenim olarak "işlem sayısı" var, x eksenim zaman (hafta) ve her satır bir kullanıcıyı temsil ediyor.

Benim sorunum bu verilere yaklaşık 100 kullanıcı grubu için bakmak istiyorum. Bir çizgi grafiği hızla 100 çizgi ile karışık bir karışıklık haline gelir. Bu bilgiyi görüntülemek için kullanabileceğim daha iyi bir grafik türü var mı? Yoksa ayrı ayrı satırları açıp kapatabildiğime mi bakmalıyım?

Tüm verileri bir kerede görmek isterdim, ancak yüksek hassasiyetle işlem sayısını ayırt edebilmek çok önemli değil.

Bunu neden yapıyorum

Kullanıcılarımın bir alt kümesi için (en iyi kullanıcılar), hangisinin belirli bir tarihte kullanıma sunulan yeni bir sürümünü beğenmediğini öğrenmek istiyorum. Tek tek kullanıcıların yaptıkları işlem sayısında önemli düşüşler arıyorum.


5
Çizgileri çizmek için kullanılan alfa değerini değiştirerek çizgileri yarı saydam hale getirmeyi düşündünüz mü?
Fomite

1
@EpiGrad Makul bir öneri ama bu, aradığımı görmeyi daha kolay hale getirmezdi.
düzenler

1
@regulatethis ggplot2 facet_wrapişlevini kullanarak 4 x 5 grafik (4 sıra, 5 sütun - istenen en boy oranına göre ayarlama) bir blok oluşturmak için grafik başına ~ 5 kullanıcı içeren bir "küçük çoklu" yaklaşım öneririm . Bu yeterince açık olmalı ve bunu grafik başına yaklaşık 10 kullanıcıya kadar ölçeklendirebilir, 200'e 4x5 arsa veya 360'lara 6x6 arsa ile yer verebilirsiniz.
SlowLearner

Yanıtlar:


31

(A) kullanıcılar arasındaki değişimin temel etkilerini ortadan kaldırmak için (standart) bir ön analiz önermek istiyorum, (b) tüm kullanıcılar arasındaki değişime tipik tepki, ve (c) bir zaman diliminden diğerine tipik değişim .

Bunu yapmanın basit (ancak hiçbir şekilde en iyisi) yolu, kullanıcı medyanlarını ve zaman periyodu medyanlarını süpürmek için veriler üzerinde birkaç "orta cila" yinelemesi yapmak ve sonra artıkları zamanla pürüzsüz hale getirmektir. Değişen pürüzsüzlükleri belirleyin: bunlar grafikte vurgulamak istediğiniz kullanıcılar.

Bunlar sayım verileri olduğundan, bunları karekök kullanarak yeniden ifade etmek iyi bir fikirdir.

Neyin sonuçlanabileceğinin bir örneği olarak, tipik olarak haftada 10 ila 20 işlem gerçekleştiren 240 kullanıcının simüle edilmiş 60 haftalık bir 60 veri kümesidir. Tüm kullanıcılarda bir değişiklik 40. haftadan sonra gerçekleşti. Bunlardan üçünün değişime olumsuz yanıt vermesi "söylendi". Soldaki grafik ham verileri gösterir: zaman içinde kullanıcı tarafından (renkle ayırt edilen kullanıcılar) yapılan işlem sayısı. Soruda iddia edildiği gibi, bu bir karışıklık. Sağdaki grafik, bu EDA'nın sonuçlarını - önceki gibi aynı renklerde - alışılmadık şekilde yanıt veren kullanıcıların otomatik olarak tanımlayıp vurguladıklarını gösterir. Tanımlama - biraz geçici olmasına rağmen - tam ve doğru (bu örnekte).

Şekil 1

İşte Rbu verileri üreten ve analizi yapan kod. Dahil olmak üzere, çeşitli şekillerde geliştirilebilir

  • Kalıntıları bulmak için yalnızca bir yinelemeden ziyade tam bir cila kullanmak.

  • Değişim noktasından önce ve sonra artıkları ayrı ayrı yumuşatın.

  • Belki daha karmaşık bir dış hat tespit algoritması kullanıyor olabilirsiniz. Mevcut olan, yalnızca artık aralıkları medyan aralığın iki katından fazla olan tüm kullanıcıları işaretler. Basit de olsa, sağlam ve iyi çalışıyor gibi görünüyor. (Kullanıcı tarafından ayarlanabilen bir değer,threshold bu kimliği daha az veya daha katı yapmak için ayarlanabilir.)

Yine de test yapmak, bu çözümün 12 - 240 veya daha fazla kullanıcı sayısında çok işe yaradığını gösteriyor.

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

Genel olarak, bir arsanın tek bir yüzeyinde iki veya üçten fazla satır bulmaya başladım (hala her zaman yapmama rağmen). Bu, kavramsal olarak 100 model bir arsa olabilecek bir şeye sahip olduğunuzda ne yapmanız gerektiğine dair ilginç bir örnektir. Olası bir yol da, 100 yüzün tümünü çizmektir, ancak hepsini bir kerede bir sayfa üzerinde göstermeye çalışmak yerine, bir kerede bir animasyonda onlara bakmaktır.

Aslında bu tekniği işimde kullandık - başlangıçta 60 farklı çizgi grafiği gösteren bir etkinlik için arka plan olarak gösterdik (yeni bir veri serisinin lansmanı). sayfa başına 15 veya 30 faset içeren fasetli parsellerde görünmüyordu.

İşte size ham verileri sunmanın alternatif bir yoludur; kullanıcıyı ve @whuber tarafından önerilen tipik zaman etkilerini kaldırmaya başlamadan önce. Bu, ham verileri sunmasına ek bir alternatif olarak sunulmaktadır - önerdiği gibi satırlar boyunca analize devam etmenizi kesinlikle tavsiye ederim.

Bu sorunu aşmanın bir yolu, 100 (veya 240 in @ whuber örneğinde) zaman serilerini ayrı ayrı üretmek ve bunları bir animasyona bağlamaktır. Aşağıdaki kod, bu tür 240 ayrı görüntü üretecek ve daha sonra filmi filme dönüştürmek için ücretsiz film oluşturma yazılımını kullanabilirsiniz. Maalesef bunu yapabilmemin ve kabul edilebilir kaliteyi korumamın tek yolu 9 MB'lık bir dosyaydı, ancak internet üzerinden bir sorun olmayacak ve yine de biraz daha fazla yol bulmaya başladığına eminim animasyon anlayışlı. R'deki animasyon paketi burada yararlı olabilir (hepsini R'den yapılan bir aramada yapmanıza izin verir) ancak bu gösterim için basit tuttum.

Animasyonu, her çizgiyi ağır siyah olacak şekilde çizdim, sonra soluk yarı saydam bir yeşil gölge bıraktıktan sonra göz biriken verilerin aşamalı bir görüntüsünü elde etti. Bunda hem riskler hem de fırsatlar var - satırların eklenme sırası farklı bir izlenim bırakacaktır, bu yüzden bir şekilde anlamlı kılmayı düşünmelisiniz.

@Whuber tarafından oluşturulan aynı verileri kullanan filmden bazı fotoğraflar: görüntü tanımını buraya girin görüntü tanımını buraya girin görüntü tanımını buraya girin görüntü tanımını buraya girin görüntü tanımını buraya girin

# ---------------------------- 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, bu iyi bir fikir. Ayrıca , windows()veya tuşlarını kullanarak yeni bir cihaz penceresi başlatabilir quartz()ve ardından döngünüzü for()içine yerleştirebilirsiniz. Not, Sys.sleep(1)yinelemeleri gerçekten görebilmeniz için döngünüzün en altına bir satır koymanız gerekir . Tabii ki, bu strateji aslında bir film dosyasını kaydetmiyor - tekrar izlemek istediğiniz her seferinde yeniden çalıştırmanız gerekiyor.
gung - Monica’yı eski durumuna getirme

+1 Çok iyi fikir - Bunu bir sonraki şansımda deneyeceğim. ( Örneğin, GTW, Mathematica , bu tür animasyonları oluşturma ve kaydetme
işini kısaltır

Şaşırtıcı fikir - bu satırlar boyunca bir animasyon (veya oluşturulacak kod ve veriler) bir yayına çok seksi bir çevrimiçi ek yapacaktır.
N Brouwer 19

7

En kolay şeylerden biri bir kutu grafiğidir. Örnek medyanınızın nasıl hareket ettiğini ve hangi günlerde en fazla aykırı değere sahip olduğunu hemen görebilirsiniz.

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)

görüntü tanımını buraya girin

Bireysel analiz için verilerinizden küçük bir rastgele örnek almanızı ve ayrı zaman serilerini analiz etmenizi öneririm.


1
İlginç bir çözüm, ancak gerçekte kullanıcı bazında "değişimin" nasıl olduğunu görebilmek için gerçekten istediğim şey. Bireysel kullanıcılar için aktivitedeki dalgalanmaları görmek istiyorum. Bu yüzden başlangıçta bir çizgi seçtim, ancak görselleştirme şimdi çok fazla karışık.
regulatethis

Aslında, verilerinizde hangi kalıpları görmek istediğinize bağlı, belki de bize ne bulmaya çalıştığınızı söylerseniz, çözüm bulabiliriz.
jem77bfp

Kullanıcılarımın bir alt kümesi için (en iyi kullanıcılar), hangisinin belirli bir tarihte kullanıma sunulan yeni bir sürümünü beğenmediğini öğrenmek istiyorum. Tek tek kullanıcıların yaptıkları işlem sayısında önemli düşüşler arıyorum.
düzenleniyor

@ Jem77bfp Sitesine Hoşgeldiniz. tüm verileri görmek istediğini söyledi. Ama daha fazla detayın olması iyi olurdu, katılıyorum.
Peter Flom - Monica'yı yeniden yerleştirme

+1 - Kutu grafiklerini görselleştirmek yerine, özet istatistiklerini çizgi grafiklere bağlamak faydalı olabilir. Bkz benim bu cevabı aşağıda bir örnek ve tartışma için.
Andy W,

7

Emin. İlk olarak, ortalama işlem sayısına göre sıralayın. Sonra her biri çeyrek için birer tane olmak üzere 25 çizgi içeren 4 grafik yapın. Bu, y eksenlerini daraltabileceğiniz anlamına gelir (ancak y ekseni etiketini temizleyin). 25 çizgi ile bunları çizgi türüne ve rengine göre değiştirebilir ve belki de sembolü çizebilir ve biraz netlik elde edebilirsiniz.

Ardından, grafikleri tek bir zaman ekseni ile dikey olarak istifleyin.

Bu, R veya SAS’de oldukça kolay olacaktır (en azından SAS 9’unuz varsa).


2
+1 - Yine de küçük çoklu başına daha az satır önerebilirim! Konuyla ilgili blog yazıma bakınız ve bir örnek. Sıralama aynı zamanda harika bir fikirdir ve diğer potansiyel olanlar başlangıçtaki veya takipteki değeri veya değişim ölçütlerini (pozitif veya negatif eğim, yüzde değişim vb. Gibi) içerebilir.
Andy W,

Güzel! Topluluk blogu nedir? Bir kişi buna nasıl erişir veya yazı yazar?
Peter Flom - Monica'yı yeniden yerleştir

3
Blog'a nasıl katılacağınız hakkında ayrıntılar için Skewed Distribution sohbet odasında beklemekten çekinmeyin . Biz her zaman topluluk üyelerinin daha katkılarından dolayı açık.
Andy W

0

Eğer grafik ve grafik ayarları, animasyonla zamanın tanıtılmasının en iyi yol olup olmadığını, eğer tür ile ilgili seçeneklerin bitmesi durumunda çalışmanız için ekstra bir boyut sağladığını ve takip etmesi kolay bir şekilde daha fazla bilgi görüntülemenizi sağladığını biliyorum. . Öncelikli odak noktanız son kullanıcı deneyiminde olmalıdır.


Peter Ellis'in burada yayınladığı çözümden farklı bir aklınızvar ? Eğer öyleyse, lütfen üzerinde çalışabilir misiniz?
whuber

0

Tek tek kullanıcılar için yapılan değişiklikle en çok ilgileniyorsanız, belki bu bir Sparklines koleksiyonu için iyi bir durumdur ( The Pudding’ten bu örnek gibi ):

Pudding.cool'dan sparklines örneği

Bunlar oldukça ayrıntılı, ancak eksen etiketlerini ve birimlerini kaldırarak bir kerede çok daha fazla grafik gösterebilirsiniz.

Birçok veri aracı yerleşiktir ( Microsoft Excel'in küçük çizgileri vardır ), ancak bunları R'de oluşturmak için bir paket çekmek isteyeceğinizi tahmin ediyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.