【问题标题】:Difference in bandwidth for scikit-learn KDE and multivariate KDE of statsmodelsscikit-learn KDE 和 statsmodels 的多变量 KDE 的带宽差异
【发布时间】:2026-01-30 11:15:01
【问题描述】:

我正在生成一个 5000 * 6 数组,并使用 scikit-learn 中的 KDE 和 statsmodel 中的 MultivariateKDE 来评估 ln(概率密度)。由于两者都可以处理多维数据,我希望使用这两种方法都能得到相同的结果。但是,结果是不同的。当我查看带宽的值时,我看到 scikit-learn KDE 使用标量值作为带宽,而 Multivariate KDE 使用一维数组作为带宽。

那么,哪个带宽是正确的?

我在下面附上代码sn-p,

# Generating random data
rng = np.random.RandomState(42)
X = rng.random_sample((5000,6))

# Using Grid search to get the best bandwidth
params = {'bandwidth': np.logspace(-1, 1, 20)}
grid = GridSearchCV(KernelDensity(), params)
grid.fit(X)
print("best bandwidth for scikit-learn: {0}".format(grid.best_estimator_.bandwidth))

# Using scikit-learn kde
kde = KernelDensity(kernel='gaussian', bandwidth=grid.best_estimator_.bandwidth).fit(X)
log_density = kde.score_samples(X)

# Using Multivariate KDE from statsmodels
kde = sm.nonparametric.KDEMultivariate(data=X, var_type='cccccc', bw='normal_reference')
log_density_stat = np.log(kde.pdf(X))
print("best bandwidth for statsmodels : ", kde.bw)

对应的输出如下,

best bandwidth for scikit-learn: 0.1
best bandwidth for statsmodels :  [0.12904    0.13105721 0.12936657 0.13071426 0.13008811 0.13102085]

【问题讨论】:

  • 您问了一个相当专业的小众问题,但到目前为止还没有答案。你实际上问了两个问题。也许您可以尝试分解您的问题并询问标签的追随者可以轻松回答的初始问题。也许先理清带宽参数之间的差异,然后单独探索哪种模型最适合您的数据。
  • 好的,我已经编辑了问题。

标签: python scikit-learn statsmodels bandwidth kernel-density


【解决方案1】:

没有“正确”的带宽本身,您刚刚从两种不同的方法获得了两个带宽值,第一个寻找唯一值(使用单变量网格搜索),第二个一个查找多个值,似乎使用Scott's rule of thumb 估计,如_normal_reference method of GenericKDE 所示。

带宽的值对应于带宽矩阵的对角线:它们都与 scikit-learn 的估计相等,并且可以与 statsmodels 的估计不同。

【讨论】:

  • 感谢您的回复。一个简单的问题 --- 在处理多维数据(维度 >= 5)时,哪种方法更受欢迎 - 来自 scikit-learn 的 KDE 还是来自 statsmodels 的 Multivariate KDE?
  • 我更喜欢 statsmodels 的 KDE,因为它处理协方差矩阵对角线上的不同值,而 scikit-learn 只允许一个唯一值。但是,鉴于在您的示例中,statsmodels 估计的带宽值非常接近,您可能会获得与 scikit-learn 一样好的结果和 0.13 的唯一带宽。如果对于其他数据,您的标准偏差在一个维度与另一个维度之间变化很大,那么我肯定会使用 statsmodels 的 KDE,因为估计的带宽也会在一个维度与另一个维度之间有很大差异。
最近更新 更多