2015-09-30 18 views
6

Dire che ho un array semplice, con una distribuzione di probabilità corrispondente.R: genera dati da una distribuzione di densità di probabilità

library(stats)  
data <- c(0,0.08,0.15,0.28,0.90) 
pdf_of_data <- density(data, from= 0, to=1, bw=0.1) 

C'è un modo per generare un altro insieme di dati utilizzando la stessa distribuzione. Poiché l'operazione è probabilistica, non è necessario che corrisponda esattamente alla distribuzione iniziale, ma verrà generata da essa.

Ho avuto successo nel trovare una soluzione semplice per conto mio. Grazie!

risposta

6

La cosa migliore è quello di generare la funzione di densità cumulativa empirica, approssimare l'inverso, e poi trasformare l'ingresso.

L'espressione composto si presenta come

random.points <- approx(
    cumsum(pdf_of_data$y)/sum(pdf_of_data$y), 
    pdf_of_data$x, 
    runif(10000) 
)$y 

rendimenti

hist(random.points, 100) 

enter image description here

+0

Questo è fantastico! Grazie! – puslet88

+2

Questa è una risposta fantastica! Lo aggiungerò al pacchetto 'stackoverflow'. –

8

Dagli esempi nella documentazione di ?density si ottiene (o quasi) la risposta.

Quindi, qualcosa di simile a questo dovrebbe farlo:

library("stats")  
data <- c(0,0.08,0.15,0.28,0.90) 
pdf_of_data <- density(data, from= 0, to=1, bw=0.1) 

# From the example. 
N <- 1e6 
x.new <- rnorm(N, sample(data, size = N, replace = TRUE), pdf_of_data$bw) 

# Histogram of the draws with the distribution superimposed. 
hist(x.new, freq = FALSE) 
lines(pdf_of_data) 

Imgur

È appena possibile rifiutare l'pareggi fuori della vostra intervallo come in rejection sampling. In alternativa, è possibile utilizzare l'algoritmo descritto nel link.

+2

Non è questo solo l'aggiunta di rumore gaussiano ai dati, non attingendo alla curva di densità levigata? –

+1

@NealFultz Ricorda che la curva di densità livellata è una miscela di distribuzioni gaussiane --- una per ogni osservazione. Quindi stiamo campionando direttamente da ciascun componente. Ma sì, hai anche ragione. –

+0

Sembra buono per le impostazioni predefinite ('kernel =" gaussian "'). –

3

Per disegnare dalla curva:

sample(pdf_of_data$x, 1e6, TRUE, pdf_of_data$y) 
+3

Nota che questo approccio dipende fortemente dall'argomento 'n' in' density'. Non otterrai mai più di un valore unico e n. Stai solo campionando da una funzione di probabilità discreta con valori 'n' e probabilità corrispondenti. A seconda dell'applicazione, potrebbe andare bene. –

+0

Questo è un buon punto e 'n' potrebbe essere manipolato per adattarsi ai dati. Anche per i miei scopi funziona davvero. Troppe risposte corrette e utili per scegliere da qui. Molte grazie ancora! – puslet88