लाइन ग्राफ में बहुत अधिक लाइनें हैं, क्या इसका बेहतर समाधान है?


30

मैं समय के साथ (इस मामले में, "पसंद") उपयोगकर्ताओं द्वारा कार्यों की संख्या को ग्राफ़ करने की कोशिश कर रहा हूं।

इसलिए मेरे पास y- अक्ष के रूप में "कार्यों की संख्या" है, मेरा x- अक्ष समय (सप्ताह) है, और प्रत्येक पंक्ति एक उपयोगकर्ता का प्रतिनिधित्व करती है।

मेरी समस्या यह है कि मैं लगभग 100 उपयोगकर्ताओं के सेट के लिए इस डेटा को देखना चाहता हूं। एक लाइन ग्राफ 100 लाइनों के साथ जल्दी से गड़बड़ हो जाता है। क्या इस जानकारी को प्रदर्शित करने के लिए मैं एक बेहतर प्रकार का ग्राफ़ उपयोग कर सकता हूँ? या क्या मुझे व्यक्तिगत लाइनों को चालू / बंद करने में सक्षम होना चाहिए?

मैं एक बार में सभी डेटा देखना चाहता हूं, लेकिन उच्च परिशुद्धता के साथ कार्यों की संख्या को समझने में सक्षम होना बहुत महत्वपूर्ण नहीं है।

मैं ऐसा क्यों कर रहा हूं

अपने उपयोगकर्ताओं (शीर्ष उपयोगकर्ताओं) के सबसेट के लिए, मैं यह पता लगाना चाहता हूं कि जिन लोगों को एप्लिकेशन का एक नया संस्करण निश्चित तिथि पर लुढ़का हुआ था, उन्हें पसंद नहीं आया होगा। मैं अलग-अलग उपयोगकर्ताओं द्वारा कार्यों की संख्या में महत्वपूर्ण गिरावट की तलाश कर रहा हूं।


5
क्या आपने उन अल्फा को बदलकर लाइनों को अर्ध-पारदर्शी बनाने पर विचार किया है जो उन्हें प्लॉट करने के लिए उपयोग की जा रही हैं?
फोमाइट

1
@EpiGrad उचित सुझाव लेकिन यह वास्तव में यह देखने के लिए कोई भी आसान नहीं होगा कि मैं क्या देख रहा हूं।
रेगुलेटेथिस

1
@regulatethis मैं ggplot2 के facet_wrapफ़ंक्शन का उपयोग करके "छोटे बहु" दृष्टिकोण का सुझाव दूंगा, प्रति चार्ट 5 ~ उपयोगकर्ताओं के साथ 4 x 5 चार्ट (4 पंक्तियों, 5 कॉलम - वांछित पहलू अनुपात के आधार पर समायोजित) का एक ब्लॉक बनाने के लिए। यह पर्याप्त रूप से स्पष्ट होना चाहिए और आप इसे प्रति चार्ट में लगभग 10 उपयोगकर्ताओं तक ले जा सकते हैं, 4x5 प्लॉट के साथ 200 या 6x6 प्लॉट के साथ 360 के लिए जगह दे सकते हैं।
SlowLearner

जवाबों:


31

मैं (a) उपयोगकर्ताओं के बीच (a) भिन्नता के मुख्य प्रभावों को हटाने के लिए (मानक) प्रारंभिक विश्लेषण का सुझाव देना चाहूंगा, (b) परिवर्तन के लिए सभी उपयोगकर्ताओं के बीच विशिष्ट प्रतिक्रिया, और (c) एक समय अवधि से अगली अवधि तक विशिष्ट बदलाव ।

ऐसा करने के लिए एक सरल (लेकिन किसी भी तरह से सबसे अच्छा) तरीका उपयोगकर्ता मध्यस्थों और समय अवधि के मध्यस्थों को बाहर निकालने के लिए डेटा पर "माध्यिका पॉलिश" के कुछ पुनरावृत्तियों को करना है, फिर समय के साथ अवशिष्टों को चिकना करना। उन स्मूथियों को पहचानें जो बहुत बदल जाती हैं: वे ऐसे उपयोगकर्ता हैं जिन्हें आप ग्राफ़िक में ज़ोर देना चाहते हैं।

क्योंकि ये गणना डेटा हैं, उन्हें एक वर्गमूल का उपयोग करके फिर से व्यक्त करना एक अच्छा विचार है।

परिणाम क्या हो सकता है, इसके उदाहरण के रूप में, यहां 240 उपयोगकर्ताओं के 60-सप्ताह का डेटासेट है जो आमतौर पर प्रति सप्ताह 10 से 20 कार्रवाई करते हैं। सप्ताह 40 के बाद सभी उपयोगकर्ताओं में परिवर्तन हुआ। इनमें से तीन को "" बताया गया था जो कि परिवर्तन के प्रति नकारात्मक प्रतिक्रिया व्यक्त करते हैं। बायां प्लॉट कच्चे डेटा को दिखाता है: समय के साथ उपयोगकर्ता द्वारा कार्रवाई की गणना (रंग द्वारा प्रतिष्ठित उपयोगकर्ताओं के साथ)। प्रश्न में कहा गया है, यह एक गड़बड़ है। सही प्लॉट इस EDA के परिणामों को पहले के समान रंगों में दिखाता है - असामान्य रूप से उत्तरदायी उपयोगकर्ताओं के साथ स्वचालित रूप से पहचाने और हाइलाइट किए गए। पहचान - यह कुछ हद तक है, हालांकि तदर्थ --is पूर्ण और सही (इस उदाहरण में)।

आकृति 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 पहलुओं को आकर्षित करना है, लेकिन एक बार में एक एनीमेशन में एक समय में उन सभी को देखने के बजाय उन सभी को पृष्ठ पर लाने की कोशिश करना।

हमने वास्तव में अपने काम में इस तकनीक का उपयोग किया है - हमने मूल रूप से एक घटना के लिए पृष्ठभूमि के रूप में 60 अलग-अलग लाइन भूखंडों को दिखाते हुए एनीमेशन बनाया (एक नई डेटा श्रृंखला का शुभारंभ), फिर पाया कि ऐसा करते हुए हमने वास्तव में डेटा की कुछ विशेषताओं को उठाया है यह प्रति पृष्ठ 15 या 30 पहलुओं के साथ faceted भूखंडों में दिखाई नहीं दिया था।

तो यहां कच्चे डेटा को प्रस्तुत करने का एक वैकल्पिक तरीका है, इससे पहले कि आप उपयोगकर्ता को निकालना शुरू करें और @whuber द्वारा अनुशंसित समय प्रभाव। यह कच्चे डेटा की अपनी प्रस्तुति के लिए एक अतिरिक्त विकल्प के रूप में प्रस्तुत किया गया है - मैं पूरी तरह से अनुशंसा करता हूं कि आप फिर उन लाइनों के विश्लेषण के साथ आगे बढ़ें जैसे कि वह सुझाव देते हैं।

इस समस्या को हल करने का एक तरीका यह है कि 100 (या # व्हिबर के उदाहरण में 240) श्रृंखला श्रृंखला के भूखंडों को अलग से तैयार किया जाए और उन्हें एक एनीमेशन में एक साथ बुनना। नीचे दिया गया कोड इस तरह की 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)अपने लूप के निचले भाग पर रखने की आवश्यकता होगी ताकि आप वास्तव में पुनरावृत्तियों को देख सकें। बेशक, यह रणनीति वास्तव में एक फिल्म फ़ाइल को सहेजती नहीं है - आपको बस इसे हर बार फिर से चलाना होगा जो आप इसे फिर से देखना चाहते हैं।
गुंग - को पुनः स्थापित मोनिका

+1 बहुत अच्छा विचार - मैं इसे प्राप्त करने का अगला मौका कोशिश करूँगा। (GTW, मेथेमेटिका , उदाहरण के लिए, बनाने और इस तरह के एनिमेशन बचत से कम काम करता है।)
whuber

अद्भुत विचार - इन पंक्तियों के साथ एक एनीमेशन (या कोड और उत्पन्न करने के लिए डेटा) एक प्रकाशन के लिए एक बहुत ही सेक्सी ऑनलाइन परिशिष्ट बना देगा।
एन ब्रूवर

7

सबसे आसान चीजों में से एक बॉक्सप्लॉट है। आप तुरंत देख सकते हैं कि आपका नमूना किस तरह से चलता है और किस दिन सबसे अधिक आउटलेयर होता है।

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
दिलचस्प समाधान, लेकिन जो मैं वास्तव में देखना चाहता हूं वह प्रति उपयोगकर्ता आधार पर "परिवर्तन" कैसे हो सकता है। मैं व्यक्तिगत उपयोगकर्ताओं के लिए गतिविधि में उतार-चढ़ाव देखना चाहता हूं। इसलिए मैंने शुरुआत में एक लाइन को चुना, लेकिन दृश्य अभी बहुत क्लट है।
regulatethis

ठीक है, यह वास्तव में इस बात पर निर्भर करता है कि आप अपने डेटा में कौन से पैटर्न देखना चाहते हैं, शायद अगर आप हमें बता सकें कि आप क्या पता लगाने की कोशिश कर रहे हैं, तो हम समाधान के साथ आ सकते हैं।
jem77bfp

अपने उपयोगकर्ताओं (शीर्ष उपयोगकर्ताओं) के सबसेट के लिए, मैं यह पता लगाना चाहता हूं कि जिन लोगों को एप्लिकेशन का एक नया संस्करण निश्चित तिथि पर लुढ़का हुआ था, उन्हें पसंद नहीं आया होगा। मैं अलग-अलग उपयोगकर्ताओं द्वारा कार्यों की संख्या में महत्वपूर्ण गिरावट की तलाश कर रहा हूं।
regulatethis

साइट @ jem77bfp पर आपका स्वागत है। उसने कहा कि वह सभी डेटा देखना चाहता था। लेकिन अधिक जानकारी होना अच्छा होगा, मैं सहमत हूं।
पीटर फ़्लॉम - २०:१२ को मोनिका

+1 - बॉक्स भूखंडों को देखने के बजाय हालांकि यह रेखाचित्रों में सारांश आँकड़ों को जोड़ने के लिए उपयोगी हो सकता है। देखें मेरा यह जवाब नीचे एक उदाहरण और चर्चा के लिए।
एंडी डब्ल्यू

7

ज़रूर। सबसे पहले, औसत क्रियाओं के आधार पर छाँटें। फिर 4 रेखांकन करें, प्रत्येक को 25 पंक्तियों के साथ, प्रत्येक चतुर्थांश के लिए एक। इसका मतलब है कि आप y- अक्ष (लेकिन y अक्ष लेबल को स्पष्ट कर सकते हैं) को सिकोड़ सकते हैं। और 25 लाइनों के साथ, आप उन्हें लाइन प्रकार और रंग और शायद साजिश के प्रतीक द्वारा भिन्न कर सकते हैं और कुछ स्पष्टता प्राप्त कर सकते हैं

फिर रेखांकन को एकल समय अक्ष के साथ लंबवत रूप से स्टैक करें।

यह R या SAS में बहुत आसान होगा (कम से कम यदि आपके पास SAS का v। 9 है)।


2
+1 - मैं सुझाव दूंगा कि प्रति छोटी बहु भी कम रेखाएँ हैं! विषय पर मेरी संबंधित ब्लॉग पोस्ट और एक उदाहरण देखें। छंटाई भी एक महान विचार है, और अन्य संभावित लोगों में आधारभूत या अनुवर्ती, या परिवर्तन के उपाय (जैसे सकारात्मक या नकारात्मक ढलान, प्रतिशत परिवर्तन, आदि) शामिल हो सकते हैं।
एंडी डब्ल्यू

अच्छा! सामुदायिक ब्लॉग क्या है? इसके लिए कोई कैसे पहुंच या लिख ​​सकता है?
पीटर फ्लॉम - मोनिका

3
द्वारा रोकने के लिए स्वतंत्र महसूस हो रहा है ब्लॉग में शामिल होने के तरीके के विवरण के लिए स्केवड डिस्ट्रीब्यूशन चैट रूम । हम हमेशा समुदाय के सदस्यों से अधिक योगदान के लिए खुले हैं ।
एंडी डब्ल्यू

0

मुझे लगता है कि जब आपके बाहर चल रहा है अगर प्रकार के बारे में विकल्प अगर ग्राफ और ग्राफ सेटिंग्स एनीमेशन के माध्यम से समय का परिचय प्रदर्शित करने का सबसे अच्छा तरीका है क्योंकि यह आपको काम करने के लिए एक अतिरिक्त आयाम देता है और आपको आसानी से पालन करने के तरीके में अधिक जानकारी प्रदर्शित करने की अनुमति देता है। । आपका प्राथमिक ध्यान अंत उपयोगकर्ता अनुभव पर होना चाहिए।


क्या आपके मन में कुछ है जो समाधान से अलग है पीटर एलिस ने यहां पोस्ट किया है ? यदि हां, तो क्या आप इस बारे में विस्तार से बता सकते हैं?
व्हीबर

0

यदि आप अलग-अलग उपयोगकर्ताओं के लिए परिवर्तन में रुचि रखते हैं, तो शायद स्पार्कलाइन्स के संग्रह के लिए यह एक अच्छी स्थिति है ( उदाहरण के लिए पुडिंग से ):

स्पार्कलाइन्स का उदाहरण pudding.cool से

ये बहुत विस्तृत हैं, लेकिन आप अक्ष लेबल और इकाइयों को हटाकर एक बार में बहुत अधिक चार्ट दिखा सकते हैं।

कई डेटा टूल ने उन्हें बनाया है ( Microsoft Excel में स्पार्कलाइन ) बनाया है, लेकिन मैं अनुमान लगा रहा हूं कि आप उन्हें आर में बनाने के लिए पैकेज में खींचना चाहते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.