2012-11-20 6 views
7

Mam pytanie dotyczące dopasowania i otrzymywania liczb losowych.funkcja gęstości prawdopodobieństwa z histogramu w pythonie dla dopasowania do innego histrogramu

Sytuacja jest taka:

Po pierwsze mam histogram z punktami danych. Chciałbym zinterpretować ten histogram jako funkcję gęstości prawdopodobieństwa (z np. 2 niezależnymi parametrami), aby móc go użyć do generowania liczb losowych ORAZ również chciałbym użyć tej funkcji do dopasowania innego histogramu.

+7

Może ta misja powinna zostać ponownie otwarta i ulepszona. –

+2

Jeśli nie rozumiesz pytania, to nie masz pewności, że to nie jest pytanie, tylko dlatego, że tego nie zrobiłeś. Spróbuj najpierw zrozumieć. Dołączam do Saullo. – Geeocode

Odpowiedz

4

Można użyć funkcji gęstości skumulowanej do generowania liczb losowych z dowolnej dystrybucji, jako described here.

Korzystanie z histogramu w celu uzyskania płynnej funkcji gęstości skumulowanej nie jest całkowicie banalne; możesz użyć interpolacji, na przykład scipy.interpolate.interp1d() dla wartości pomiędzy środkami twoich binów i to będzie działało dobrze dla histogramu z rozsądnie dużą liczbą pojemników i przedmiotów. Jednak musisz zdecydować się na kształt ogona funkcji prawdopodobieństwa, tj. Dla wartości mniejszych niż najmniejszy pojemnik lub większy niż największy pojemnik. Możesz podać swój rozkład głosów gaussowskich na podstawie na przykład dopasowania gaussa do histogramu) lub jakąkolwiek inną formę ogona odpowiednią do twojego problemu, lub po prostu skrócić rozkład.

Przykład:

import numpy 
import scipy.interpolate 
import random 
import matplotlib.pyplot as pyplot 

# create some normally distributed values and make a histogram 
a = numpy.random.normal(size=10000) 
counts, bins = numpy.histogram(a, bins=100, density=True) 
cum_counts = numpy.cumsum(counts) 
bin_widths = (bins[1:] - bins[:-1]) 

# generate more values with same distribution 
x = cum_counts*bin_widths 
y = bins[1:] 
inverse_density_function = scipy.interpolate.interp1d(x, y) 
b = numpy.zeros(10000) 
for i in range(len(b)): 
    u = random.uniform(x[0], x[-1]) 
    b[i] = inverse_density_function(u) 

# plot both   
pyplot.hist(a, 100) 
pyplot.hist(b, 100) 
pyplot.show() 

nie obsługiwać ogony, i może obsługiwać bin krawędzie lepiej, ale to dobry początek na wykorzystaniu histogram generować więcej wartości z tej samej dystrybucji.

P.S. Możesz także spróbować dopasować konkretną znaną dystrybucję opisaną przez kilka wartości (co, jak myślę, było tym, o czym wspomniałeś w pytaniu), ale powyższe podejście nieparametryczne ma bardziej ogólny cel.

+0

, dziękuję za szybką odpowiedź, interpolacja była również w moim umyśle, ale jak powiedziałeś po pierwsze, nie może zająć się wartościami odstającymi, a także, że tak naprawdę nie jest funkcją gęstości, ale raczej kopią początkowego histogramu. – madzone

+2

to jest moja ostateczna wersja, działa płynnie, dzięki jeszcze raz. 'bins = np.linspace (0, .5, num = 800) counts18, bin = np.histogram (Z_DATA [InData18], bins = bins) x = np.cumsum (counts18) * 1./np. suma (counts18) * 1. y = biny [zakres (len (x) +1)] y = y [1:] dopasowanie = scipy.interpolate.interp1d (x, y) plt.hist (fit (np.random.uniform (x [0], x [-1], len (dane))), pojemniki = y) plt.hist (dane, alfa = 0,3, pojemniki = y) plt.show() ' – madzone

Powiązane problemy