为什么我的kde图显示为垂直线而不是曲线



我一直在尝试为我所拥有的数据(染色体起始位点的频率(绘制KDE图,尽管我完全遵循了这些例子,但当我使用我的数据或生成的看起来像我自己的数据时,整个图会混乱,只生成垂直线,而不是法线。我希望有一个更熟悉scikit学习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)

这是我生成的数据看起来像我的数据的代码。我在数据中有1000个起始站点,它们的值从10000到824989不等。我更改了数据、林空间范围和步长以及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) 

我想这一定和林斯佩斯有关。我也不太明白score_samples()为什么把linspace作为一个参数。

您的代码有两个问题:

  1. 内核密度估计中使用的带宽需要更高,因为与示例相比,您的数据的标准差要大得多(您的数据标准差为824989,而示例中使用的数据标准偏差为2.5(。您需要使用大约200000的带宽,而不是1的带宽。例如,请参阅维基百科关于内核密度估计的文章中关于"经验法则带宽估计器"的部分
  2. 使用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)

最新更新