1

二項分布の混合を生成したい。なぜそれが必要なのかというと、ガウス分布の通常の離散混合が必要だからです。利用可能なscipyライブラリはありますか、それともアルゴリズムについて教えてください。

一般的に、定義済みのディストリビューションでは ppf を使用できることを知っています。しかし、この関数については、ppf を使用する簡単な方法はないと思います。

それぞれからサンプリングしてそれらを混合することも、さまざまなディストリビューションからいくつのインスタンスを選択する必要があるかわからないため、問題があるようです。

最後に、私が持ちたいのは次のようなものです: ここに画像の説明を入力

4

3 に答える 3

3

これは、二項分布 (およびその他の分布) の任意の混合を生成する簡単な方法です。混合物 P(x)=sum(w[i]*P_i(x), i=1..Nmix) からサンプル (Nsamp) を取得したい場合は、サンプリングによってそれを行うことができるという事実に依存しています。 P_i(x) のそれぞれからの Nsamp。次に、確率 w[i] で i に等しい別の確率変数の別の Nsamp サンプルを取得します。この確率変数を使用して、指定されたサンプルがどの P_i(x) から来るかを選択できます。

import numpy as np,numpy.random, matplotlib.pyplot as plt

#parameters of the binomial distributions: pairs of (n,p)
binomsP = np.array([.5, .5, .5])
binomsCen = np.array([15, 45, 95]) # centers of binomial distributions
binomsN = (binomsCen/binomsP).astype(int)

fractions = [0.2, 0.3, 0.5]
#mixing fractions of the binomials
assert(sum(fractions)==1)

nbinoms = len(binomsN)
npoints = 10000
cumfractions = np.cumsum(fractions)
def mapper(x):
    # convert the random number between 0 and 1 to
    # the ID of the distribution according to the mixing fractions
    return np.digitize(x, cumfractions)

x0 = np.random.binomial(binomsN[None, :],
        binomsP[None, :], size=(npoints, nbinoms))

x = x0[:, mapper(np.random.uniform(size=npoints))]
plt.hist(x, bin=150, range=(0, 150))

ここに画像の説明を入力

于 2013-03-14T20:50:24.007 に答える
1

逆累積分布関数を計算するスマートな方法を見つけない限り (その場合はお知らせください!)、棄却サンプリングは確実な方法です。ウィキペディアのエントリは、一般的な説明を提供します。私が実際に発見したことは、「インストゥルメンタル」分布には少し注意する必要があることです。具体的には、ターゲット分布よりもはるかに速く減衰しないようにする必要があります。そうすると、テールの寄与を失う可能性があります。 .

私が行う方法は、フラットなインストルメンタル分布から開始します。一様乱数xとのペアを生成しますy。ここで、yは [0, 1)から、xは からです。次に、 と を比較し、収束するまで繰り返します。これでうまくいけば準備完了です。それが十分でない場合は、フラットでない機器分布を使用してください。混合物のテールがガウス分布である場合は、おそらくガウス分布を使用するのが最善です。 [0, L)Lycdf(x)

補足として、二項分布を扱っている場合は、オーバー/アンダーフローに注意する必要があります --- パラメータによっては、ガウス近似を使用する必要がある場合があります。

于 2013-03-14T17:07:09.557 に答える
0

@sega_sai、@askewchan、@Zhenya のおかげで、私は自分でコードを作成しました。実装により、これが最も効率的なものになると信じています。最初の関数は、すべて同じ N=maximum-minimum パラメータと同じ p=0.5 を持つ "binoNumber" 二項分布の混合を作成しますが、生成したランダムな中心に従ってシフトされます。

global binoInitiated
binoInitiated=False;
def binoMixture(minimum,maximum,sampleSize):
    global centers
    binoNumber=10;
    if (not binoInitiated):
        centers=np.random.randint(minimum,maximum+1,binoNumber)
    sigma=maximum-minimum-2
    sam=np.array([]);
    while sam.size<sampleSize:
        i=np.random.choice(binoNumber);
        temp=np.random.binomial(sigma, 0.5,1)+centers[i]-sigma/2+1
        sam=np.append(sam,temp)
    return sam

事前に作成した分布に対して近似PDFを描画する機能です。この部分を作成するために彼のコードを使用した @EnricoGiampieri に感謝します。

def binoMixtureDrawer(minimum,maximum):
    global binoInitiated
    global centers
    sam=binoMixture(minimum,maximum,50000)    
    # this create the kernel, given an array it will estimate the probability over that values
    kde = gaussian_kde( sam )
    # these are the values over wich your kernel will be evaluated
    dist_space = linspace( min(sam), max(sam), 500 )
    # plot the results
    fig.plot( dist_space, kde(dist_space),'g')
于 2013-03-15T16:52:25.940 に答える