python - 多元 KDE Scipy Stats - 如果它不是高斯的怎么办?
问题描述
我有一些我正在使用的 2D 数据进行平滑处理:
from scipy.stats import gaussian_kde
kde = gaussian_kde(data)
但是如果我的数据不是高斯/tophat/其他选项怎么办?我的在平滑之前看起来更椭圆,所以我真的应该在 x 和 y 中有不同的带宽吗?一个方向的方差要高很多,x轴的值也高,所以感觉一个简单的高斯可能会漏掉什么?
解决方案
这就是我通过您定义的X
and得到的Y
。看起来不错。你期待不同的东西吗?
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
def generate(n):
# generate data
np.random.seed(42)
x = np.random.normal(size=n, loc=1, scale=0.01)
np.random.seed(1)
y = np.random.normal(size=n, loc=200, scale=100)
return x, y
x, y = generate(100)
xmin = x.min()
xmax = x.max()
ymin = y.min()
ymax = y.max()
X, Y = np.mgrid[xmin:xmax:100j, ymin:ymax:100j]
positions = np.vstack([X.ravel(), Y.ravel()])
values = np.vstack([x, y])
kernel = stats.gaussian_kde(values)
Z = np.reshape(kernel(positions).T, X.shape)
fig, ax = plt.subplots(figsize=(7, 7))
ax.imshow(np.rot90(Z), cmap=plt.cm.gist_earth_r,
extent=[xmin, xmax, ymin, ymax],
aspect='auto', alpha=.75
)
ax.plot(x, y, 'ko', ms=5)
ax.set_xlim([xmin, xmax])
ax.set_ylim([ymin, ymax])
plt.show()
x
和的分布y
是高斯的。seaborn
你也可以验证
import pandas as pd
import seaborn as sns
# I pass a DataFrame because passing
# (x,y) alone will be soon deprecated
g = sns.jointplot(data=pd.DataFrame({'x':x, 'y':y}), x='x', y='y')
g.plot_joint(sns.kdeplot, color="r", zorder=0, levels=6)
更新
二维数据的核密度估计沿每个轴单独完成,然后连接在一起。
让我们用我们已经使用的数据集做一个例子。
正如我们在联合图中看到的seaborn
那样,您不仅有估计的 2d-kde,还有和(直方图)的边际分布。x
y
因此,让我们一步一步地估计密度,x
然后y
评估线性空间上的密度
kde_x = sps.gaussian_kde(x)
kde_x_space = np.linspace(x.min(), x.max(), 100)
kde_x_eval = kde_x.evaluate(kde_x_space)
kde_x_eval /= kde_x_eval.sum()
kde_y = sps.gaussian_kde(y)
kde_y_space = np.linspace(y.min(), y.max(), 100)
kde_y_eval = kde_y.evaluate(kde_y_space)
kde_y_eval /= kde_y_eval.sum()
fig, ax = plt.subplots(1, 2, figsize=(12, 4))
ax[0].plot(kde_x_space, kde_x_eval, 'k.')
ax[0].set(title='KDE of x')
ax[1].plot(kde_y_space, kde_y_eval, 'k.')
ax[1].set(title='KDE of y')
plt.show()
所以我们现在有 和 的边际x
分布y
。这些是概率密度函数,因此 x 和 y 的联合概率可以看作是独立事件的交集x
和y
,因此我们可以将估计的 x 和 y 的概率密度乘以 2d 矩阵并绘制在 3d 投影上
# Grid of x and y
X, Y = np.meshgrid(kde_x_space, kde_y_space)
# Grid of probability density
kX, kY = np.meshgrid(kde_x_eval, kde_y_eval)
# Intersection
Z = kX * kY
fig, ax = plt.subplots(
2, 2,
subplot_kw={"projection": "3d"},
figsize=(10, 10))
for i, (elev, anim, title) in enumerate(zip([10, 10, 25, 25],
[0, -90, 25, -25],
['y axis', 'x axis', 'view 1', 'view 2']
)):
# Plot the surface.
surf = ax.flat[i].plot_surface(X, Y, Z, cmap=plt.cm.gist_earth_r,
linewidth=0, antialiased=False, alpha=.75)
ax.flat[i].scatter(x, y, zs=0, zdir='z', c='k')
ax.flat[i].set(
xlabel='x', ylabel='y',
title=title
)
ax.flat[i].view_init(elev=elev, azim=anim)
plt.show()
这是一个非常简单和幼稚的方法,但只是为了了解它的工作原理以及为什么 x 和 y 比例对于 2d-KDE 无关紧要。
推荐阅读
- cypress - 赛普拉斯支持哪些 Chromium 版本
- java - 使用 mockito 为 findById() JPA 方法编写 Junit 测试用例时,我收到错误 java.util.NoSuchElementException: No value present
- machine-learning - 具有多种数据类型的分类器(机器学习/数据科学)
- docker - asp core spa application docker build error 语法错误:“)”意外(预期“然后”)
- c++ - 致命错误 LNK1169:找到一个或多个多重定义的符号 1>完成构建项目“project.vcxproj”--失败
- javascript - 如何在按钮单击时使用 jQuery 添加具有相同 ID 的两行或多行
- python - 是否可以使用 coloured-traceback.py 以彩色打印`traceback.format_exc()`
- java - struts2,Could not execute action: /newAction 没有为动作名称newAction映射的动作。- [未知位置]
- c - 头部单链表中的元素删除不起作用
- kotlin - 在 kotlin 中求和映射值