【问题标题】:Getting bandwidth used by SciPy's gaussian_kde function获取 SciPy 的 gaussian_kde 函数使用的带宽
【发布时间】:2014-07-01 02:00:34
【问题描述】:

我正在使用 SciPy 的 stats.gaussian_kde 函数从 x,y 点的数据集生成核密度估计 (kde) 函数。

这是我的代码的简单 MWE:

import numpy as np
from scipy import stats

def random_data(N):
    # Generate some random data.
    return np.random.uniform(0., 10., N)

# Data lists.
x_data = random_data(100)
y_data = random_data(100)

# Obtain the gaussian kernel.
kernel = stats.gaussian_kde(np.vstack([x_data, y_data]))

由于我没有手动设置带宽(通过bw_method 键),该函数默认使用 Scott 规则(参见函数说明)。我需要的是获得stats.gaussian_kde函数自动设置的这个带宽值。

我尝试过使用:

print kernel.set_bandwidth()

但它总是返回 None 而不是浮点数。

【问题讨论】:

    标签: python kernel scipy bandwidth


    【解决方案1】:

    我遇到了这个老问题,因为我也想知道 Scipy 的 gaussian_kde 使用的带宽是多少。我想添加/修改以前的答案,即协方差因子在 Scipy 的 kde.py 代码中使用为: self.covariance = self._data_covariance * self.factor**2

    因此,完整的核协方差是样本协方差乘以所谓的协方差因子(Scott 因子)的平方,可以通过 kde.factor 或 kde.covariance_factor() 检索。 p>

    【讨论】:

      【解决方案2】:

      简答

      带宽是kernel.covariance_factor() 乘以您正在使用的样本的标准

      (这是一维样本的情况,默认情况下使用 Scott 的经验法则计算)。

      示例:

      from scipy.stats import gaussian_kde
      sample = np.random.normal(0., 2., 100)
      kde = gaussian_kde(sample)
      f = kde.covariance_factor()
      bw = f * sample.std()
      

      你得到的pdf是这样的:

      from pylab import plot
      x_grid = np.linspace(-6, 6, 200)
      plot(x_grid, kde.evaluate(x_grid))
      

      你可以这样检查,如果你使用一个新函数来创建一个 kde,比如说,sklearn:

      from sklearn.neighbors import KernelDensity
      def kde_sklearn(x, x_grid, bandwidth):
          kde_skl = KernelDensity(bandwidth=bandwidth)
          kde_skl.fit(x[:, np.newaxis])
          # score_samples() returns the log-likelihood of the samples
          log_pdf = kde_skl.score_samples(x_grid[:, np.newaxis])
          pdf = np.exp(log_pdf)
          return pdf
      

      现在使用与上面相同的代码:

      plot(x_grid, kde_sklearn(sample, x_grid, f))
      

      plot(x_grid, kde_sklearn(sample, x_grid, bw))
      

      【讨论】:

      • 查看我的更新评论。您使用的不是带宽,而是与样本的标准相乘的因子
      • 您知道scipy.stats.gaussian_kde 中的参数bw_methodsklearn.neighbors.KernelDensity 中的bandwidth 不代表相同的东西吗?请看这个问题:stackoverflow.com/q/21000140/1391441
      • 您要求的是带宽,不是吗? covariance_factor 不是带宽
      • 我称之为“带宽”,因为文档调用bw_method“用于计算估计器带宽的方法”。从统计学上讲,您可能是对的,尽管我不确定您的答案应该做什么。你是说我接受的答案不正确吗?
      • 这取决于你问什么。如果您问如何获得因子,那么您的答案是正确的。但是如果你想知道什么是“带宽”,你必须使用我写的。 “带宽”是内核密度估计器使用的参数的技术术语(您可以在此处查看en.wikipedia.org/wiki/Kernel_density_estimation)。如果给bw-method一个标量,就是用上面写的方式计算带宽(乘以std),但不是带宽本身。
      【解决方案3】:

      我知道了,行是:

      kernel.covariance_factor()
      

      来自scipy.stats.gaussian_kde.covariance_factor

      计算乘以数据协方差矩阵以获得核协方差矩阵的系数 (kde.factor)。默认值为scotts_factor。子类可以覆盖此方法以提供不同的方法,或通过调用 kde.set_bandwidth 来设置它。

      可以检查使用此带宽值生成的内核是否等同于使用默认带宽生成的内核。为此,获取具有covariance_factor() 给定带宽的新内核,并将其在随机点上的值与原始内核进行比较:

      kernel = stats.gaussian_kde(np.vstack([x_data, y_data]))
      print kernel([0.5, 1.3])
      
      bw = kernel.covariance_factor()    
      kernel2 = stats.gaussian_kde(np.vstack([x_data, y_data]), bw_method=bw)
      print kernel2([0.5, 1.3])
      

      【讨论】:

      • bw_method 参数用作因子,因此设置因子会给您相同的结果。但这不是“带宽”。我添加了一个答案
      猜你喜欢
      • 1970-01-01
      • 2015-05-04
      • 2014-11-03
      • 1970-01-01
      • 2021-06-10
      • 1970-01-01
      • 2019-03-21
      • 2023-03-06
      • 2019-08-17
      相关资源
      最近更新 更多