12

ヒストグラムとして表すことができる物理実験の結果があります[i, amount_of(i)]。結果は、4 ~ 6 個のガウス関数の混合によって推定できると思います。

入力としてヒストグラムを取り、混合分布の各ガウス分布の平均と分散を返す Python のパッケージはありますか?

元のデータ。例:

サンプルデータ

4

1 に答える 1

18

これはガウス分布の混合であり、期待値最大化アプローチを使用して推定できます(基本的に、分布の中心と平均を見つけると同時に、それらがどのように混合されるかを推定します)。

これは、PyMixパッケージに実装されています。以下では、法線の混合の例を生成し、PyMixを使用して混合モデルをそれらに適合させます。これには、サブポピュレーションのサイズである、関心のあるものを把握することも含まれます。

# requires numpy and PyMix (matplotlib is just for making a histogram)
import random
import numpy as np
from matplotlib import pyplot as plt
import mixture

random.seed(010713)  # to make it reproducible

# create a mixture of normals:
#  1000 from N(0, 1)
#  2000 from N(6, 2)
mix = np.concatenate([np.random.normal(0, 1, [1000]),
                      np.random.normal(6, 2, [2000])])

# histogram:
plt.hist(mix, bins=20)
plt.savefig("mixture.pdf")

上記のコードはすべて、混合物を生成してプロットすることです。次のようになります。

ここに画像の説明を入力してください

次に、実際にPyMixを使用して、パーセンテージを把握します。

data = mixture.DataSet()
data.fromArray(mix)

# start them off with something arbitrary (probably based on a guess from the figure)
n1 = mixture.NormalDistribution(-1,1)
n2 = mixture.NormalDistribution(1,1)
m = mixture.MixtureModel(2,[0.5,0.5], [n1,n2])

# perform expectation maximization
m.EM(data, 40, .1)
print m

これの出力モデルは次のとおりです。

G = 2
p = 1
pi =[ 0.33307859  0.66692141]
compFix = [0, 0]
Component 0:
  ProductDist: 
  Normal:  [0.0360178848449, 1.03018725918]

Component 1:
  ProductDist: 
  Normal:  [5.86848468319, 2.0158608802]

2つの法線が非常に正しく検出されたことに注意してください(おおよそN(0, 1)1つと1つ)。N(6, 2)またpi、2つの分布のそれぞれの割合であるを推定しました(コメントで最も興味のあることを述べています)。最初のディストリビューションには1000、2番目のディストリビューションには2000があり、ほぼ正確に分割されています[ 0.33307859 0.66692141]。この値を直接取得する場合は、を実行しますm.pi

いくつかの注意:

  • このアプローチは、ヒストグラムではなく、値のベクトルを取ります。[(1.4, 2), (2.6, 3)]データを1Dベクトルに変換する(つまり、に変換する[1.4, 1.4, 2.6, 2.6, 2.6])のは簡単なはずです。
  • ガウス分布の数を事前に推測する必要がありました(2の混合を要求した場合、4の混合はわかりません)。
  • 分布の初期推定値をいくつか入力する必要がありました。リモートで合理的な推測を行う場合でも、正しい見積もりに収束するはずです。
于 2013-01-07T07:08:48.740 に答える