Python 将曲面图边缘化并在其上使用核密度估计(kde)

Python 将曲面图边缘化并在其上使用核密度估计(kde),python,matplotlib,scipy,statistics,Python,Matplotlib,Scipy,Statistics,作为一个最小可重复性示例,假设我有以下多元正态分布: 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])

作为一个最小可重复性示例,假设我有以下多元正态分布:

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()
这将给出以下曲面图:

我的目标是边缘化这一点,并使用核密度估计,以获得一个很好的和平滑的一维高斯分布。我遇到了两个问题:

  • 我不确定我的边缘化技巧是否有意义
  • 边缘化后,我只剩下一个条形图,但高斯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()
这是我得到的条形图:

接下来,我将按照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的比例不同

为了进一步强调这一点,我修改了方差协方差矩阵,这样我们就知道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()
这使得:


这意味着条形图的比例不正确。是什么编码问题导致条形图的比例错误?

如何在曲面图边缘化的情况下进行内核密度估计?编码问题是,我不明白为什么它的比例错误,当我遵循一个有效的示例时,但如何修剪代码?人们需要完整的代码才能理解示例好吧,我已经澄清了它,并添加了一些额外的见解好工作(+1);现在,让我们返回并删除所有这些(现在不必要的)注释…;)