Получение PDF-файла из модели смеси Гаусса в sklearn

avatar
learner
8 августа 2021 в 19:57
374
1
2

Я подогнал модель смеси Гаусса (GMM) к ряду данных, который у меня есть. Используя GMM, я пытаюсь получить вероятности другого вектора по элементам. Matlab достигает этого с помощью следующих строк кода.

a = reshape(0:1:15, 14, 1);
gm = fitgmdist(a, 13);  % 13 specifies the number of components (means and covs for example) in the fit model

% Testing with new data
b = reshape(-5:1:5, 11, 1);
pdf(gm, b) 

    0.0000
    0.0000
    0.0000
    0.0000
    0.0018
    0.0643
    0.0658
    0.0671
    0.0666
    0.0662
    0.0672

Это ожидаемо, поскольку отрицательные значения от -5 до 0 отсутствуют в данных, предоставленных при подборе, и, следовательно, дают почти нулевые значения.

Я пытаюсь воспроизвести это с помощью python с sklearn. Ниже приведены мои достижения.

from sklearn.mixture import GaussianMixture
import numpy as np

gm = GaussianMixture(n_components=13).fit(np.arange(16).reshape(-1, 1))

# Generate test data
b = np.arange(-5, 6)[:, None]
prob = gm.predict_proba(b).tolist()

"""
prob=
[[8.539939840944505e-152, 0.0, 1.9638856033086253e-68, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[2.238593143299414e-141, 0.0, 3.166463050557315e-63, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[5.868073258732079e-131, 0.0, 5.106947259415683e-58, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[1.5382109014584666e-120, 0.0, 8.239047963148164e-53, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[4.0321459413005606e-110, 0.0, 1.3296012030592655e-47, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[8.790691487706948e-139, 0.0, 1.7850932827696813e-81, 8.316994953954272e-40, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[6.040819196361928e-118, 0.0, 7.556403579572576e-66, 2.180313173877784e-29, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0], 
[7.616317001277741e-99, 0.0, 5.870491452246584e-52, 1.0486913731065672e-20, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[1.761856615767359e-81, 0.9999999999999076, 8.370258307836422e-40, 9.254498458447064e-14, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
[7.477776611058069e-66, 0.0, 2.190323924113167e-29, 1.4984230843298664e-08, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.9999999850157694, 0.0, 0.0], 
[5.823053603579932e-52, 0.0, 1.0519204995101235e-20, 4.4513567127132954e-05, 0.0, 0.0, 0.9999554864328727, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]]
"""

Массив prob возвращает матрицу, в которой каждая строка означает вероятность принадлежности к одному из n_components классов (подразумевается, что сумма по строке = 1). Однако это не ожидаемый результат. Я хотел бы знать вероятность того, что каждый элемент b будет сгенерирован из подходящей модели gm, как это делает Matlab.

Как я могу добиться этого с помощью Python? Спасибо.

Источник
sai
8 августа 2021 в 20:47
0

Я думаю (может ошибаться), что ваше понимание того, что здесь делает число 13, как в коде Matlab, так и в коде sklearns, немного ошибочно. После просмотра документов число 13, которое вы использовали здесь, по сути, передает модель для поиска 13 различных распределений Гаусса в 16 образцах одномерных данных, которые вы даете модели.

Nagabhushan S N
9 августа 2021 в 00:58
1

Разве это не то, что описал ОП? Я имею в виду, я не понял, чем ваше понимание отличается от понимания ОП.

learner
9 августа 2021 в 05:45
0

@сай, это правда. У меня нет проблем с установкой GMM на оба этих языка. Например, в обоих языках в качестве средства используется вектор 13x1. Мой вопрос связан со следующим шагом. Мне нужен поэлементный PDF-файл из подходящей модели gm, которую предоставляет Matlab в Python. Надеюсь, на этот раз мои намерения ясны.

sai
9 августа 2021 в 22:27
1

Я вижу сейчас. Спасибо за объяснение.

Ответы (1)

avatar
TC Arlen
9 августа 2021 в 12:46
1

predict_proba находит вероятность того, что отдельная строка данных назначена каждому компоненту, на котором основана GMM (в вашем случае 13 компонентов). Дополнительную информацию см. в отличной главе Джейка ВандерПласа.

Чтобы получить PDF-файл, вам нужно использовать функцию score_samples, которая возвращает взвешенную логарифмическую вероятность того, что каждая строка будет извлечена из подобранного GMM:

b = np.arange(-5, 6)[:, None]
log_probs = gm.score_samples(b)
sum_of_scores = (np.exp(log_probs)).sum()
probs = np.exp(log_probs) / sum_of_scores
print('Probs sum: ', probs.sum()) # confirm sums to 1
print('pdf: ', probs.tolist())

Обратите внимание, что в этом игрушечном примере из-за недетерминированного характера кластеризации K-средних в начальной части алгоритма подбора GMM вы, скорее всего, не воспроизведете точные результаты из Matlab, но если у вас есть более реалистичный, разнообразный, хорошо отобранный набор данных для перекрестной проверки с реализацией MATLAB, они согласятся намного лучше.

learner
9 августа 2021 в 13:31
0

Итак, вы предлагаете softmax для его нормализации?

TC Arlen
9 августа 2021 в 13:39
0

Да, верно, softmax, потому что это LogLikelihood.