私が持っているデータに基づいて分布を作成し、その分布からランダムに描画しようとしています。ここに私が持っているものがあります:
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
これは私がやりたいことをやっていると思いますが、やろうとするとエラーが頻繁に発生し (以下を参照) d.rvs()
、d.rvs(100)
まったく機能しません。私は何か間違ったことをしていますか?これを行うためのより簡単またはより良い方法はありますか? scipy のバグである場合、回避する方法はありますか?
最後に、カスタム ディストリビューションの作成に関するドキュメントは他にありますか? 私が見つけた最高のものは scipy.stats.rv_continuous のドキュメントです。これは非常に質素で、有用な例が含まれていません。
トレースバック:
トレースバック (最新の呼び出しが最後): ファイル "testDistributions.py"、19 行目、出力 d.rvs(size=100) 内 ファイル "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0 -py2.6-linux-x86_64.egg/scipy/stats/distributions.py"、696 行目、rvs vals = self._rvs(*args) ファイル "/usr/local/lib/python2.6/dist-packages /scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py"、1193 行目、_rvs Y = self._ppf(U,*args) ファイル"/usr/local/lib /python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py"、1212 行目、_ppf で self.vecfunc(q,*args) ファイルを返す「/usr/local/lib/python2.6/dist-packages/numpy-1.6.1-py2.6-linux-x86_64.egg/numpy/lib/function_base.py」、1862行目、呼び出し中 theout = self.thefunc(*newargs) ファイル "/usr/local/lib/python2.6/dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/stats/distributions.py" 、1158 行目、_ppf_single_call で return optimize.brentq(self._ppf_to_solve, self.xa, self.xb, args=(q,)+args, xtol=self.xtol) ファイル "/usr/local/lib/python2.6 /dist-packages/scipy-0.10.0-py2.6-linux-x86_64.egg/scipy/optimize/zeros.py"、366 行目、brentq r = _zeros._brentq(f,a,b,xtol,maxiter 内) ,args,full_output,disp) ValueError: f(a) と f(b) には異なる符号が必要です
編集
好奇心旺盛な人のために、以下の回答のアドバイスに従って、動作するコードを次に示します。
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)