Como você visualiza resultados binários versus um preditor contínuo?

10

Tenho alguns dados que preciso visualizar e não tenho certeza da melhor maneira de fazê-lo. Eu tenho um conjunto de itens base com as respectivas frequências e os resultados . Agora eu preciso traçar o quão bem meu método "encontra" (isto é, um resultado 1) os itens de baixa frequência. Inicialmente, eu só tinha um eixo x de frequência e um eixo y de 0-1 com gráficos de pontos, mas parecia horrível (especialmente ao comparar dados de dois métodos). Ou seja, cada item is tem um resultado (0/1) e é ordenado por sua frequência.F = { f 1 , , f n } O { 0 , 1 } n q QQ={q1,,qn}F={f1,,fn}O{0,1}nqQ

Aqui está um exemplo com os resultados de um único método:

insira a descrição da imagem aqui

Minha próxima idéia foi dividir os dados em intervalos e calcular uma sensibilidade local sobre os intervalos, mas o problema com essa idéia é que a distribuição de frequência não é necessariamente uniforme. Então, como devo escolher melhor os intervalos?

Alguém conhece uma maneira melhor / mais útil de visualizar esse tipo de dados para retratar a eficácia de encontrar itens raros (ou seja, de frequência muito baixa)?

EDIT: Para ser mais concreto, estou demonstrando a capacidade de algum método para reconstruir sequências biológicas de uma determinada população. Para validação usando dados simulados, preciso mostrar a capacidade de reconstruir variantes, independentemente de sua abundância (frequência). Portanto, neste caso, estou visualizando os itens perdidos e encontrados, ordenados por sua frequência. Este lote não irá incluir variantes reconstruídos que não estão em .Q

Nicholas Mancuso
fonte
11
Eu não entendo completamente. Os "resultados" estão encontrando alguma coisa? Quais são os "itens raros"?
Peter Flom - Restabelece Monica
11
Na IMO, você deve incluir o gráfico que você disse que parece horrível - isso dará a todos uma idéia melhor dos dados que você está tentando exibir.
Andy W
@ PeterFlom, editei para torná-lo mais claro. Os resultados de 0 a 1 para cada item indicam "não encontrado" e "encontrado". Um item raro é simples, um item de frequência muito baixa.
Nicholas Mancuso
@ AndyW, editado para incluir a imagem. Dado que os valores no eixo y não refletem realmente o conceito de encontrado e não encontrado, mas pelo menos para transmitir o que eu quero apresentar (para fins dessas perguntas), você entendeu ...
Nicholas Mancuso
11
OK, parece que você tentou um gráfico de dispersão nos dados em que o valor y pode ser apenas 0 ou 1. Está certo? E você deseja comparar esse tipo de plotagem entre vários métodos nos mesmos pontos? Mas cada método pode estar certo ou errado de uma ou duas maneiras? Ou seja, cada ponto é ou não é (o que seja). Então, um método poderia dizer que um ponto é (seja o que for) ou não seja (o que seja) e qualquer uma das opções pode estar certa ou errada?
Peter Flom - Restabelece Monica

Respostas:

10

O que eu fiz no passado é basicamente o que você fez com a adição de um loess . Dependendo da densidade dos pontos, eu usaria pontos translúcidos (alfa), como mostrado abaixo, e / ou símbolos de tubo ("|") para minimizar a sobreposição.

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

insira a descrição da imagem aqui

(Eu não acho que as barras de erro devam aumentar nas bordas aqui, mas não há uma maneira fácil de fazer isso com a função stat_smooth interna do ggplot. Se você usou esse método para reais em R, poderíamos fazê-lo calculando o loess e sua barra de erro antes da plotagem.)

( Editar: e mais alguns pelos comentários de Andy W. sobre a tentativa de instabilidade vertical se a densidade dos dados o tornar útil e de Mimshot sobre intervalos de confiança adequados.)

MattBagg
fonte
3
+1 - Eu também sugeriria o jitter para os pontos (além da transparência). Neste exemplo, eu substituiria geom_point(size=2, alpha=0.4)por geom_jitter(size=2, alpha=0.4, position = position_jitter(height = .02)).
Andy W
3
+1, mas você deve usar limites de confiança a partir da inversão da distribuição binomial, em vez do ruído gaussiano implícito.
Mimshot
@Mimshot Você pode mostrar como calcular corretamente os intervalos de confiança?
Guy Bee
11
@Mimshot, você conhece uma maneira ggplot2de fornecer os ICs corretos? Eu tenho um lote com CIs fora do [0,1]que claramente são provenientes do cálculo errado
MichaelChirico
[0,1]
2

Considere também quais escalas são mais apropriadas para o seu caso de uso. Digamos que você esteja fazendo uma inspeção visual para fins de modelagem em regressão logística e deseje visualizar um preditor contínuo para determinar se você precisa adicionar um spline ou termo polinomial ao seu modelo. Nesse caso, você pode querer uma escala em probabilidades de log em vez de probabilidade / proporção.

A função na essência abaixo usa algumas heurísticas limitadas para dividir o preditor contínuo em compartimentos, calcular a proporção média, converter em log-odds e depois traçar geom_smoothesses pontos agregados.

Exemplo de como esse gráfico se parece se uma covariável tiver uma relação quadrática (+ ruído) com as chances de log de um alvo binário:

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'

Criado em 06/02/2019 pelo pacote reprex (v0.2.1)

Para comparação, eis a aparência dessa relação quadrática se você apenas plotasse os 1s / 0s e adicionasse um 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")'

Criado em 2019-02-25 pelo pacote reprex (v0.2.1)

O relacionamento com o logit é menos claro e o uso geom_smoothtem alguns problemas.

Bryan Shalloway
fonte
0

Concordo que a publicação de apenas algumas linhas de dados de amostra ajudaria bastante. Se eu entendi a pergunta, acho que seria mais simples traçar a frequência pela proporção encontrada.

Primeiro vou gerar alguns dados de amostra em R; corrija-me se não o entendi corretamente.

# 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 agora, basta plotar a frequência ( F) por proportion:

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

insira a descrição da imagem aqui

nograpes
fonte
4
Essa trama é horrível! Alguma suavização, como nas respostas anteriores, é necessária.
precisa saber é o seguinte