Отдельная смесь гауссиан в Python

Существует результат некоторого физического эксперимента, который может быть представлен как гистограмма [i, amount_of(i)] . Я полагаю, что этот результат можно оценить с помощью смеси 4 – 6 гауссовских функций.

Есть ли пакет в Python, который берет гистограмму в качестве ввода и возвращает среднее и дисперсию каждого распределения Гаусса в распределении смеси?

Исходные данные, например:

Пример данных

One Solution collect form web for “Отдельная смесь гауссиан в Python”

Это смесь гауссианцев и может быть оценена с использованием подхода максимизации ожидания (в основном, он находит центры и средства распространения в то же время, когда оценивает, как они смешиваются вместе).

Это реализовано в пакете 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] 

Обратите внимание, что он нашел две нормали вполне корректно (один 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]
  • Нам приходилось заранее гадать количество гауссовых дистрибутивов (он не будет определять комбинацию из 4, если вы попросите сочетание из 2).
  • Нам пришлось внести некоторые начальные оценки для распределений. Если вы сделаете даже отдаленно разумные догадки, он должен сходиться к правильным оценкам.
Python - лучший язык программирования в мире.