Próbuję utworzyć dystrybucję na podstawie niektórych danych, które mam, a następnie losowo losować z tej dystrybucji. Oto co mam:Tworzenie nowych dystrybucji w scipy
from scipy import stats
import numpy
def getDistribution(data):
kernel = stats.gaussian_kde(data)
class rv(stats.rv_continuous):
def _cdf(self, x):
return kernel.integrate_box_1d(-numpy.Inf, x)
return rv()
if __name__ == "__main__":
# pretend this is real data
data = numpy.concatenate((numpy.random.normal(2,5,100), numpy.random.normal(25,5,100)))
d = getDistribution(data)
print d.rvs(size=100) # this usually fails
myślę, że robi to, co chcę go, ale często pojawia się błąd (patrz niżej), gdy próbuję zrobić d.rvs()
i d.rvs(100)
nigdy nie działa. czy robię coś źle? Czy istnieje lepszy lub lepszy sposób na zrobienie tego? Jeśli jest to błąd w scipie, czy jest jakiś sposób na obejście tego?
Wreszcie, czy jest gdzieś więcej dokumentacji na temat tworzenia niestandardowych dystrybucji? Najlepsze, co znalazłem, to dokumentacja scipy.stats.rv_continuous, która jest dość spartańska i nie zawiera użytecznych przykładów.
traceback:
Traceback (most recent call last): File "testDistributions.py", line 19, in print d.rvs(size=100) File "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py", line 696, in rvs vals = self._rvs(*args) File "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py", line 1193, in _rvs Y = self._ppf(U,*args) File "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py", line 1212, in _ppf return self.vecfunc(q,*args) File "/usr/local/lib/python2.6/dist-packages/numpy-1.6.1-py2.6-linux-x86_64.egg/numpy/lib/function_base.py", line 1862, in call theout = self.thefunc(*newargs) File "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py", line 1158, in _ppf_single_call return optimize.brentq(self._ppf_to_solve, self.xa, self.xb, args=(q,)+args, xtol=self.xtol) File "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/optimize/zeros.py", line 366, in brentq r = _zeros._brentq(f,a,b,xtol,maxiter,args,full_output,disp) ValueError: f(a) and f(b) must have different signs
Edit
Dla tych, nowoczesny, po poradę w poniższej odpowiedzi, oto kod, który działa:
from scipy import stats
import numpy
def getDistribution(data):
kernel = stats.gaussian_kde(data)
class rv(stats.rv_continuous):
def _rvs(self, *x, **y):
# don't ask me why it's using self._size
# nor why I have to cast to int
return kernel.resample(int(self._size))
def _cdf(self, x):
return kernel.integrate_box_1d(-numpy.Inf, x)
def _pdf(self, x):
return kernel.evaluate(x)
return rv(name='kdedist', xa=-200, xb=200)
Więc kiedy robimy powyższe i nazywając 'randoms = getDistribution (Mydata)', a następnie 'randoms = randoms.rvs (size = 1000)' czy wykonuje on trzy 'def' wewnątrz klasy? tj. obliczanie pdf, integrowanie go itp.? – ThePredator
Dostaję moje randy, aby śledzić dystrybucję danych, ale chciałbym ją wygładzić, aby nie śledzić dokładnie dystrybucji danych. W tym celu ręcznie dostosowuję przepustowość w 'kernelu'. Na przykład coś w rodzaju tego, jak określamy funkcję PDF, a następnie używamy funkcji PDF do tworzenia randów za pomocą Metropolis Hastings. – ThePredator