Маргинализовать участок поверхности и использовать оценку плотности ядра (kde) на нем - PullRequest
3 голосов
/ 22 марта 2019

В качестве минимального воспроизводимого примера, предположим, что у меня есть следующее многомерное нормальное распределение:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from scipy.stats import multivariate_normal, gaussian_kde

# Choose mean vector and variance-covariance matrix
mu = np.array([0, 0])
sigma = np.array([[2, 0], [0, 3]])
# Create surface plot data
x = np.linspace(-5, 5, 100)
y = np.linspace(-5, 5, 100)
X, Y = np.meshgrid(x, y)
rv = multivariate_normal(mean=mu, cov=sigma)
Z = np.array([rv.pdf(pair) for pair in zip(X.ravel(), Y.ravel())])
Z = Z.reshape(X.shape)
# Plot it
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
pos = ax.plot_surface(X, Y, Z)
plt.show()

Это дает следующий график поверхности: joint

Myцель состоит в том, чтобы обойти это и использовать оценку плотности ядра, чтобы получить хороший и плавный 1D гауссов.Я сталкиваюсь с 2 проблемами:

  • Не уверен, что моя методика маргинализации имеет смысл.
  • После маргинализации у меня остается барплот, но gaussian_kde требует фактических данных (а не их частоты)для того, чтобы соответствовать KDE, поэтому я не могу использовать эту функцию.

Вот как я его изолирую:

# find marginal distribution over y by summing over all x
y_distribution = Z.sum(axis=1) / Z.sum()  # Do I need to normalize?
# plot bars
plt.bar(y, y_distribution)
plt.show()

и вот барплот, который я получаю:

marginal

Далее я следую этому вопросу StackOverflow, чтобы найти KDE только по данным "гистограммы".Для этого мы повторно сэмплируем гистограмму и подгоняем KDE для повторных сэмплов:

# sample the histogram
resamples = np.random.choice(y, size=1000, p=y_distribution)
kde = gaussian_kde(resamples)
# plot bars
fig, ax = plt.subplots(nrows=1, ncols=2)
ax[0].bar(y, y_distribution)
ax[1].plot(y, kde.pdf(y))
plt.show()

Это дает следующий график:

kde

который выглядит "хорошо", но эти два графика явно не в одном масштабе.

Проблема кодирования

Почему KDE выходит в другом масштабе?Или, скорее, почему барплот в другом масштабе, чем KDE?

Чтобы еще раз подчеркнуть это, я изменил ковариационную матрицу дисперсии, чтобы мы знали, что предельное распределение по y является нормальным распределением с центром в0 с дисперсией 3. На данный момент мы можем сравнить KDE с фактическим нормальным распределением следующим образом:

plt.plot(y, norm.pdf(y, loc=0, scale=np.sqrt(3)), label='norm')
plt.plot(y, kde.pdf(y), label='kde')
plt.legend()
plt.show()

Это дает:

norm

Это означает, что гистограмма имеет неправильный масштаб.Какая проблема кодирования сделала барплот в неправильном масштабе?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...