Comment visualisez-vous les résultats binaires par rapport à un prédicteur continu?


10

J'ai quelques données à visualiser et je ne sais pas comment le faire. J'ai un ensemble d'éléments de base avec les fréquences respectives et les résultats . Maintenant, je dois déterminer dans quelle mesure ma méthode "trouve" (c'est-à-dire un résultat à 1) les éléments de basse fréquence. Au départ, je venais d'avoir un axe de fréquence et un axe y de 0-1 avec des tracés ponctuels, mais cela avait l'air horrible (surtout lorsque l'on comparait les données de deux méthodes). C'est-à-dire que chaque élément est a un résultat (0/1) et est ordonné par sa fréquence.F = { f 1 , , f n } O { 0 , 1 } n q QQ={q1,,qn}F={F1,,Fn}O{0,1}nqQ

Voici un exemple avec les résultats d'une seule méthode:

entrez la description de l'image ici

Mon idée suivante était de diviser les données en intervalles et de calculer une sensibilité locale sur les intervalles, mais le problème avec cette idée est que la distribution de fréquence n'est pas nécessairement uniforme. Alors, comment choisir au mieux les intervalles?

Quelqu'un connaît-il un moyen meilleur / plus utile de visualiser ce type de données pour dépeindre l'efficacité de la recherche d'éléments rares (c.-à-d. À très basse fréquence)?

EDIT: Pour être plus concret, je présente la capacité d'une méthode à reconstruire les séquences biologiques d'une certaine population. Pour la validation à l'aide de données simulées, je dois montrer la capacité de reconstruire des variantes quelle que soit son abondance (fréquence). Dans ce cas, je visualise les éléments manqués et trouvés, classés par leur fréquence. Cette parcelle ne comprend pas les variantes reconstruites qui ne sont pas dans .Q


1
Je ne comprends pas tout à fait. Les «résultats» trouvent-ils quelque chose? Quels sont les "objets rares"?
Peter Flom - Réintègre Monica

1
OMI, vous devriez inclure le graphique que vous avez dit horrible - cela donnera à tout le monde une meilleure idée des données que vous essayez d'afficher.
Andy W

@PeterFlom, j'ai édité pour le rendre plus clair. Les résultats 0-1 pour chaque élément indiquent «introuvable» et «trouvé». Un élément rare est un élément très basse fréquence.
Nicholas Mancuso

@AndyW, modifié pour inclure l'image. Étant donné que les valeurs sur l'axe des y ne reflètent pas vraiment le concept de trouvé et non trouvé, mais au moins pour transmettre ce que je veux présenter (pour les besoins de ces questions), vous avez l'idée ...
Nicholas Mancuso

1
OK, il semble que vous ayez essayé un nuage de points sur des données où la valeur y ne peut être que 0 ou 1. Est-ce vrai? Et vous voulez comparer ces sortes de tracés à travers plusieurs méthodes sur les mêmes points? Mais chaque méthode peut-elle être bonne ou mauvaise dans un sens ou dans deux sens? Autrement dit, chaque point est ou n'est pas (peu importe). Une méthode pourrait donc dire qu'un point est (peu importe) ou pas (peu importe) et que l'un ou l'autre choix pourrait être bon ou mauvais?
Peter Flom - Réintégrer Monica

Réponses:


10

Ce que j'ai fait dans le passé, c'est essentiellement ce que vous avez fait avec l'ajout d'un loess . Selon la densité des points, j'utiliserais des points translucides (alpha), comme indiqué ci-dessous, et / ou des symboles de tuyau ("|") pour minimiser le chevauchement.

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()

entrez la description de l'image ici

(Je ne pense pas que les barres d'erreur devraient s'élargir sur les bords ici, mais je ne sais pas comment le faire avec la fonction interne stat_smooth de ggplot. Si vous avez utilisé cette méthode pour les réels dans R, nous pourrions le faire en estimant le loess et sa barre d'erreur avant de tracer.)

( Edit: Et des plus pour les commentaires d'Andy W. sur l'essai de la gigue verticale si la densité des données le rend utile et de Mimshot sur les intervalles de confiance appropriés.)


3
+1 - Je suggère également d'utiliser la gigue pour les points (en plus de la transparence). Dans cet exemple, je remplacerais geom_point(size=2, alpha=0.4)par geom_jitter(size=2, alpha=0.4, position = position_jitter(height = .02)).
Andy W

3
+1 mais vous devez utiliser les limites de confiance de l'inverse de la distribution binomiale plutôt que le bruit gaussien implicite.
Mimshot

@Mimshot Pouvez-vous montrer comment calculer correctement les intervalles de confiance?
mec abeille

1
@Mimshot connaissez-vous un moyen ggplot2de fournir les bons CI? J'ai un complot avec des CI en dehors [0,1]desquels viennent clairement du mauvais calcul
MichaelChirico

[0,1]

2

Considérez également les échelles les plus appropriées pour votre cas d'utilisation. Supposons que vous effectuez une inspection visuelle à des fins de modélisation en régression logistique et que vous souhaitez visualiser un prédicteur continu pour déterminer si vous devez ajouter un terme spline ou polynomial à votre modèle. Dans ce cas, vous souhaiterez peut-être une échelle en log-odds plutôt qu'une probabilité / proportion.

La fonction ci-dessous utilise quelques heuristiques limitées pour diviser le prédicteur continu en bacs, calculer la proportion moyenne, convertir en log-odds, puis tracer geom_smoothsur ces points agrégés.

Exemple de ce à quoi ressemble ce graphique si une covariable a une relation quadratique (+ bruit) avec les log-odds d'une cible binaire:

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'

Créé le 2019-02-06 par le package reprex (v0.2.1)

À titre de comparaison, voici à quoi ressemblerait cette relation quadratique si vous venez de tracer les 1/0 et d'ajouter 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")'

Créé le 2019-02-25 par le package reprex (v0.2.1)

La relation avec logit est moins claire et l'utilisation geom_smoothpose certains problèmes.


0

Je suis d'accord que la publication de quelques lignes d'exemples de données suffirait grandement. Si je comprends la question, je pense qu'il serait plus simple de tracer la fréquence par la proportion trouvée.

Je vais d'abord générer des exemples de données dans R; veuillez me corriger si je ne vous ai pas bien compris.

# 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

Et maintenant, tracez simplement la fréquence ( F) par proportion:

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

entrez la description de l'image ici


4
Ce complot est horrible! Un certain lissage, comme dans les réponses précédentes, est nécessaire.
kjetil b halvorsen
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.