Как вернуть среднее значение (или ожидаемое значение) распределения, оцененного с помощью функции KernelDensity sklearn, в python? - PullRequest
1 голос
/ 22 апреля 2019

У меня вопрос, как вернуть среднее значение и дисперсию оценочного "kde"? Или есть какой-то другой пакет, который вам известен, который может легко вывести среднее значение или значение отклонения, например print kde.mean() или print kde.get_parameter(mean)?

import numpy as np
from scipy.stats import norm
from sklearn.neighbors import KernelDensity

N = 100
np.random.seed(1)
X = np.concatenate((np.random.normal(0, 1, int(0.3 * N)),np.random.normal(5, 1, int(0.7 * N))))[:, np.newaxis]

X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]
kde = KernelDensity(kernel='gaussian', bandwidth=0.5).fit(X)

1 Ответ

1 голос
/ 22 апреля 2019

В общем, вам нужно сделать это численно.Я предлагаю 2 различных подхода:

  • Интеграция
  • Моделирование Монте-Карло

Эти подходы работают для любого ядра и любого bandwidth .

Интеграция

Использует тот факт, что как только мы знаем функцию плотности вероятности , мы можем легко вычислить среднее и дисперсию посредством интегрирования.

mean and variance

Обратите внимание, что в scikit-learn метод score_samples возвращает log pdf и, следовательно, его нужно "exp".

Monte CarloМоделирование

Идея состоит в том, чтобы просто произвести выборку из вашего KDE и оценить среднее значение и дисперсию популяции через среднее значение и дисперсию выборки.


Код

import numpy as np
from scipy.integrate import quad
from sklearn.neighbors import KernelDensity

N = 100
np.random.seed(1)
X = np.concatenate((np.random.normal(0, 1, int(0.3 * N)),np.random.normal(5, 1, int(0.7 * N))))[:, np.newaxis]

X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]

kde = KernelDensity(kernel='gaussian', bandwidth=0.5).fit(X)

# Mean and Variance - Integration
pdf = lambda x : np.exp(kde.score_samples([[x]]))[0]
mean_integration = quad(lambda x: x * pdf(x), a=-np.inf, b=np.inf)[0]
variance_integration = quad(lambda x: (x ** 2) * pdf(x), a=-np.inf, b=np.inf)[0] - mean_integration ** 2

# Mean and Variance - Monte Carlo
n_samples = 10000000
samples = kde.sample(n_samples)

mean_mc = samples.mean()
variance_mc = samples.var()


print('Mean:\nIntegration: {}\nMonte Carlo: {}\n'.format(mean_integration, mean_mc))
print('Variance\nIntegration: {}\nMonte Carlo: {}\n'.format(variance_integration, variance_mc))

Вывод:

Значение: интеграция: 3.560582852075697 Монте-Карло: 3.5595633705830934

Дисперсия: интеграция: 6.645066811078639 Монте-Карло: 6.646732489654485

...