Come visualizzi i risultati binari rispetto a un predittore continuo?


10

Ho alcuni dati che devo visualizzare e non sono sicuro del modo migliore per farlo. Ho una serie di elementi di base con rispettive frequenze e risultati . Ora devo tracciare quanto bene il mio metodo "trova" (cioè un risultato 1) gli oggetti a bassa frequenza. Inizialmente avevo solo un asse x di frequenza e un asse y di 0-1 con grafici a punti, ma sembrava orribile (specialmente quando si confrontano i dati di due metodi). Cioè, ogni elemento ha un risultato (0/1) ed è ordinato in base alla sua frequenza.F = { f 1 , , f n } O { 0 , 1 } n q QQ={q1,,qn}F={f1,,fn}O{0,1}nqQ

Ecco un esempio con i risultati di un singolo metodo:

inserisci qui la descrizione dell'immagine

La mia prossima idea era quella di dividere i dati in intervalli e calcolare una sensibilità locale sugli intervalli, ma il problema con quell'idea è che la distribuzione della frequenza non è necessariamente uniforme. Quindi, come dovrei scegliere meglio gli intervalli?

Qualcuno conosce un modo migliore / più utile per visualizzare questo tipo di dati per rappresentare l'efficacia della ricerca di oggetti rari (cioè a frequenza molto bassa)?

EDIT: Per essere più concreti, sto mettendo in mostra la capacità di alcuni metodi di ricostruire sequenze biologiche di una determinata popolazione. Per la convalida utilizzando dati simulati, devo mostrare la capacità di ricostruire varianti indipendentemente dalla sua abbondanza (frequenza). Quindi in questo caso sto visualizzando gli oggetti mancati e trovati, ordinati in base alla loro frequenza. Questo terreno non includerà varianti ricostruiti che non sono in .Q


1
Non capisco del tutto. I "risultati" stanno trovando qualcosa? Quali sono gli "oggetti rari"?
Peter Flom

1
IMO dovresti includere il grafico che hai detto sembra orribile - darà a tutti un'idea migliore dei dati che stai tentando di visualizzare.
Andy W,

@PeterFlom, l'ho modificato per renderlo più chiaro. I risultati 0-1 per ciascun elemento indicano "non trovato" e "trovato". Un oggetto raro è semplice un articolo a frequenza molto bassa.
Nicholas Mancuso,

@AndyW, modificato per includere l'immagine. Dato che i valori sull'asse y non riflettono davvero il concetto di trovato e non trovato, ma almeno per trasmettere ciò che voglio presentare (ai fini di questa domanda), hai avuto l'idea ...
Nicholas Mancuso

1
OK, sembra che tu abbia provato un grafico a dispersione sui dati in cui il valore y può essere solo 0 o 1. Esatto? E vuoi confrontare questo tipo di grafici tra più metodi sugli stessi punti? Ma ogni metodo può essere giusto o sbagliato in un modo o due modi? Cioè, ogni punto o è o non è (qualunque cosa). Quindi un metodo potrebbe dire che un punto è (qualunque) o non è (qualunque) e una scelta potrebbe essere giusta o sbagliata?
Peter Flom

Risposte:


10

Quello che ho fatto in passato è fondamentalmente quello che hai fatto con l'aggiunta di un loess . A seconda della densità dei punti, utilizzerei i punti traslucidi (alfa), come mostrato di seguito, e / o i simboli di tubo ("|") per ridurre al minimo la sovrapposizione.

library(ggplot2) # plotting package for R

N=100
data=data.frame(Q=seq(N), Freq=runif(N,0,1), Success=sample(seq(0,1), 
size=N, replace=TRUE))

ggplot(data, aes(x=Freq, y=Success))+geom_point(size=2, alpha=0.4)+
  stat_smooth(method="loess", colour="blue", size=1.5)+
  xlab("Frequency")+
  ylab("Probability of Detection")+
  theme_bw()

inserisci qui la descrizione dell'immagine

(Non credo che le barre di errore dovrebbero allargarsi sui bordi qui, ma non c'è un modo semplice che conosco per farlo con la funzione stat_smooth interna di ggplot. Se avessi usato questo metodo per reali in R, potremmo farlo stimando il loess e la sua barra di errore prima di tracciare).

( Modifica: e altri per i commenti di Andy W. sul tentativo di jitter verticale se la densità dei dati lo rende utile e di Mimshot sugli intervalli di confidenza adeguati.)


3
+1 - Suggerirei anche di utilizzare il jitter per i punti (oltre alla trasparenza). In questo esempio vorrei sostituire geom_point(size=2, alpha=0.4)con geom_jitter(size=2, alpha=0.4, position = position_jitter(height = .02)).
Andy W,

3
+1 ma dovresti usare i limiti di confidenza dall'inverso della distribuzione binomiale piuttosto che il rumore gaussiano implicito.
Mimshot,

@Mimshot Puoi mostrare come calcolare correttamente gli intervalli di confidenza?
ragazzo delle api il

1
@Mimshot conosci un modo ggplot2per fornire gli EC corretti? Ho un complotto con EC al di fuori del [0,1]quale chiaramente provengono da calcoli sbagliati
MichaelChirico,

[0,1]

2

Considera anche quali scale sono più appropriate per il tuo caso d'uso. Supponiamo che tu stia eseguendo un'ispezione visiva ai fini della modellazione nella regressione logistica e desideri visualizzare un predittore continuo per determinare se è necessario aggiungere una spline o un termine polinomiale al modello. In questo caso, è possibile che si desideri una scala delle probabilità del log anziché della probabilità / proporzione.

La funzione in sintesi usa alcune euristiche limitate per dividere il predittore continuo in bin, calcolare la proporzione media, convertire in quota-log, quindi tracciare geom_smoothsu questi punti aggregati.

Esempio di come appare questo grafico se una covariata ha una relazione quadratica (+ rumore) con le probabilità del log di un obiettivo binario:

devtools::source_gist("https://gist.github.com/brshallo/3ccb8e12a3519b05ec41ca93500aa4b3")

# simulated dataset with quadratic relationship between x and y
set.seed(12)
samp_size <- 1000
simulated_df <- tibble(x = rlogis(samp_size), 
                       y_odds = 0.2*x^2,
                       y_probs = exp(y_odds)/(1 + exp(y_odds))) %>% 
  mutate(y = rbinom(samp_size, 1, prob = y_probs)) 

# looking at on balanced dataset
simulated_df_balanced <- simulated_df %>% 
  group_by(y) %>% 
  sample_n(table(simulated_df$y) %>% min())


ggplot_continuous_binary(df = simulated_df,
                         covariate = x, 
                         response = y,
                         snip_scales = TRUE)
#> [1] "bin size: 18"
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'

Creato il 06-02-2019 dal pacchetto reprex (v0.2.1)

Per fare un confronto, ecco come sarebbe quella relazione quadratica se avessi appena tracciato 1/0 e aggiunto un geom_smooth:

simulated_df %>% 
  ggplot(aes(x, y))+
  geom_smooth()+
  geom_jitter(height = 0.01, width = 0)+
  coord_cartesian(ylim = c(0, 1), xlim = c(-3.76, 3.59))
# set xlim to be generally consistent with prior chart
#> `geom_smooth()` using method = 'gam' and formula 'y ~ s(x, bs = "cs")'

Creato il 25-02-2019 dal pacchetto reprex (v0.2.1)

La relazione con il logit è meno chiara e l'utilizzo geom_smoothpresenta alcuni problemi.


0

Concordo sul fatto che pubblicare solo poche righe di dati di esempio farebbe molto. Se capisco la domanda, penso che sarebbe più semplice tracciare la frequenza in base alla proporzione trovata.

Innanzitutto genererò alcuni dati di esempio in R; per favore correggimi se non ti ho capito bene.

# Create some sample data
data=data.frame(Q=1:20,F=seq(5,100,by=5))
set.seed(1)
data$found<-round(sapply(data$F,function(x) runif(1,1,x)))
data$prop<-data$found/data$F
# Looks like:
Q   F found      prop
1   1   5     2 0.4000000
2   2  10     4 0.4000000
3   3  15     9 0.6000000
4   4  20    18 0.9000000
5   5  25     6 0.2400000
6   6  30    27 0.9000000
7   7  35    33 0.9428571
8   8  40    27 0.6750000
9   9  45    29 0.6444444
10 10  50     4 0.0800000
11 11  55    12 0.2181818
12 12  60    11 0.1833333
13 13  65    45 0.6923077
14 14  70    28 0.4000000
15 15  75    58 0.7733333
16 16  80    40 0.5000000
17 17  85    61 0.7176471
18 18  90    89 0.9888889
19 19  95    37 0.3894737
20 20 100    78 0.7800000

E ora semplicemente traccia la frequenza ( F) di proportion:

# Plot frequency by proportion found.
plot(data$F,data$prop,xlab='Frequency',ylab='Proportion Found',type='l',col='red',lwd=2)

inserisci qui la descrizione dell'immagine


4
Quella trama è orribile! Sono necessari alcuni livellamenti, come nelle risposte precedenti.
kjetil b halvorsen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.