python - 为什么我的 kde 图显示为垂直线而不是曲线?
问题描述
我一直在尝试为我拥有的数据(染色体起始位点的频率)制作 KDE 图,尽管我完全按照示例进行操作,但当我使用我的数据或生成的数据看起来像我自己的数据时,整个图就会混乱并产生只有垂直线而不是正常曲线。我希望更熟悉 scikit learn KDE 的人可以帮助我找出我做错了什么。
这是示例中生成的数据的代码,其中一切运行良好:
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from sklearn.neighbors import KernelDensity
X = np.concatenate((np.random.normal(0, 1, 14), np.random.normal(5, 1, 6)))[:, np.newaxis]
X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]
kde = KernelDensity(kernel='gaussian', bandwidth=1.0).fit(X)
log_density = kde.score_samples(X_plot)
fig, ax = plt.subplots()
plt.fill_between(X_plot[:, 0], np.exp(log_density), color="b")
plt.plot(X, np.full_like(X, -0.01), '|k', markeredgewidth=.01)
ax.set_xlim(-5, 10)
这是我生成的数据的代码,看起来像我的数据。我在数据中有 1,000 个起始站点,它们的值范围从 10000 到 824989。我更改了数据、linspace 范围和步长以及 x 轴,现在我得到的是垂直线而不是曲线。我还更改了 y 限制,因为它们变得非常奇怪。
X = np.random.normal(10000, 824989, 1000)[:, np.newaxis]
X_plot = np.linspace(10000, 824989, 100000)[:, np.newaxis]
kde = KernelDensity(kernel='gaussian', bandwidth=1.0).fit(X)
log_density = kde.score_samples(X_plot)
fig, ax = plt.subplots()
plt.fill_between(X_plot[:, 0], np.exp(log_density), color="b")
plt.plot(X, np.full_like(X, -0.01), '|k', markeredgewidth=.01)
ax.set_xlim(10000, 824989)
ax.set_ylim(-0.0001, 0.00061)
我认为它必须与linspace有关。我也不太明白为什么score_samples()
将 linspace 作为参数。
解决方案
您的代码有两个问题:
- 内核密度估计中使用的带宽需要更高,因为与示例相比,您的数据具有更大的标准偏差(您的数据的标准偏差为 824,989,而示例中使用的数据的标准偏差为 2.5)。您将需要使用大约 200,000 的带宽而不是 1 的带宽。例如,请参阅Wikipedia 关于内核密度估计的文章中的“经验法则带宽估计器”部分。
- 使用的目的
np.linspace()
是生成一组数据点,在这些数据点上kde
可以评估估计的核密度函数。为了能够可视化数据的完整分布,np.linspace()
应将 的第一个参数设置为等于数据的最小值(而不是数据的平均值),并将 的第二个参数np.linspace()
设置为等于数据(而不是数据的标准差)。
我在下面举了一个例子。
import numpy as np
import matplotlib.pyplot as plt
from sklearn.neighbors import KernelDensity
mu = 10000 # mean
sigma = 824989 # standard deviation
# generate the data
X = np.random.normal(mu, sigma, 1000)[:, np.newaxis]
# estimate the optimal bandwidth
h = 1.06 * np.std(X) * (len(X) ** (- 1 / 5))
# estimate the density function
kde = KernelDensity(kernel='gaussian', bandwidth=h).fit(X)
# evaluate the density function
x = np.linspace(np.min(X), np.max(X), 100000)[:, np.newaxis]
log_density = kde.score_samples(x)
density = np.exp(log_density)
# plot the density function
plt.plot(x, density)
推荐阅读
- python-3.x - UnicodeDecodeError:“utf-8”编解码器无法解码位置 0 的字节 0x80:读取文本文件时起始字节无效
- spring-boot - Spring Security OAuth2 支持 Facebook appsecret_proof
- json - 将 RESTResponse.Content 转换为 JSON 值或 JSON 数组 Delphi
- javascript - Javascript 无法显示倒数计时器,它也从按钮单击开始
- python - 值 161137531201111100, 1.611375312011111e+17 是否相等?
- mysql - 关于左连接中的SQL选择问题
- flutter - Flutter:如何使以下图像小部件在 Stack 中起作用
- javascript - 为什么反应库会导致服务器上的空白页?
- apache-spark - 我很好奇GCP的Data Fusion的内部工作流程
- ios - 使用 xcodebuild 构建 Swift 包管理器项目,如何忽略 xcodeproj 和 xcworkspace?