在Python中单独混合高斯人

Bel*_*nar 10 python statistics normal-distribution

有一些物理实验的结果,可以表示为直方图[i, amount_of(i)].我想结果可以通过4-6个高斯函数的混合来估计.

Python中是否有一个包,它以直方图作为输入,并返回混合分布中每个高斯分布的均值和方差?

原始数据,例如:

样本数据

Dav*_*son 14

这是一个高斯混合物,并且可以使用一个来估计期望最大化方法(基本上,它找到的中心,并在同一时间上的分布的装置,因为它是估计它们是如何混合在一起).

这是在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")
Run Code Online (Sandbox Code Playgroud)

以上所有代码都生成并绘制混合物.它看起来像这样:

在此输入图像描述

现在实际使用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
Run Code Online (Sandbox Code Playgroud)

这个输出模型是:

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]
Run Code Online (Sandbox Code Playgroud)

请注意,它发现两个法线非常正确(大约一个N(0, 1)和一个N(6, 2)).它还估计pi,这是两个发行版中每个发行版的分数(你在评论中提到的是你最感兴趣的内容).我们在第一个发行版中有1000个,在第二个发行版中有2000个,它使得该部门几乎完全正确:[ 0.33307859 0.66692141].如果您想直接获得此值,请执行此操作m.pi.

几点说明:

  • 这种方法采用值的向量,而不是直方图.将数据转换为一维向量应该很容易(也就是说,转换[(1.4, 2), (2.6, 3)][1.4, 1.4, 2.6, 2.6, 2.6])
  • 我们必须提前猜测高斯分布的数量(如果要求混合2,它将不会计算出4的混合).
  • 我们不得不对分布进行一些初步估计.如果您进行远程合理的猜测,它应该收敛到正确的估计值.