Python 获取SciPy'使用的带宽;s高斯函数

Python 获取SciPy'使用的带宽;s高斯函数,python,kernel,scipy,bandwidth,Python,Kernel,Scipy,Bandwidth,我使用SciPy函数从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(

我使用SciPy函数从
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_方法
键),函数默认使用Scott规则(请参见函数说明)。我需要的是通过
stats.gaussian_kde
函数自动获得这个带宽值

我试过使用:

print kernel.set_bandwidth()

但它总是返回
None
而不是float。

我知道了,行是:

kernel.covariance_factor()
发件人:

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

可以检查使用此带宽值生成的内核是否与使用默认带宽生成的内核相同。为此,使用
协方差系数()
给定的带宽获取一个新内核,并将其随机点上的值与原始内核进行比较:

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])

我知道了,线路是:

kernel.covariance_factor()
发件人:

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

可以检查使用此带宽值生成的内核是否与使用默认带宽生成的内核相同。为此,使用
协方差系数()
给定的带宽获取一个新内核,并将其随机点上的值与原始内核进行比较:

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])

简短回答

带宽是
kernel.convariance\u factor()
乘以您正在使用的样本的标准

(这是1D样本的情况,在默认情况下使用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))


简短回答

带宽是
kernel.convariance\u factor()
乘以您正在使用的样本的标准

(这是1D样本的情况,在默认情况下使用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))


我遇到了这个老问题,因为我也想知道Scipy的gaussian_kde使用的带宽是多少。我想补充/修正之前的答案,即Scipy的kde.py代码中使用的协方差因子为: 自协方差=自数据自协方差*自系数**2


因此,完整的内核协方差是样本协方差乘以所谓的协方差因子(Scott因子)的平方,它可以由kde.factor或kde.convariace_factor()检索。

我遇到了这个老问题,因为我还想从Scipy了解高斯_kde使用的带宽是多少。我想补充/修正之前的答案,即Scipy的kde.py代码中使用的协方差因子为: 自协方差=自数据自协方差*自系数**2


因此,完整的内核协方差是样本协方差乘以所谓的协方差因子(Scott因子)的平方,该因子可由kde.factor或kde.convariace_factor()检索。

bw_方法参数用作因子,因此设置该因子将得到相同的结果。但这不是“带宽”。我添加了一个answerbw_方法参数用作因子,因此设置因子将得到相同的结果。但这不是“带宽”。我添加了一个答案,请参阅我的最新评论。您使用的不是带宽,而是要乘以样本std的因子。您是否知道
scipy.stats.gaussian_kde
中的参数
bw_方法
sklearn.neights.KernelDensity
中的
带宽
并不代表相同的东西?请看这个问题:你要求的是带宽,不是吗?协方差系数不是带宽,我称之为“带宽”,因为docs调用
bw\u方法
“用于计算估计器带宽的方法”。从统计学上讲,你可能是对的,尽管我不确定你的答案应该是什么。你是说我接受的答案不正确吗?这取决于你问什么。如果你问如何得到因子,那么你的答案是正确的。但是如果你想知道“带宽”是多少,你就必须使用我写的东西。“带宽”是核密度估计器使用的参数的技术术语(您可以在这里查看)。如果你给bw方法一个标量,它是用来计算带宽的方式写在上面(它乘以标准),但它不是带宽本身。请参阅我的更新意见。您使用的不是带宽,而是要乘以样本std的因子。您是否知道
scipy.stats.gaussian_kde
中的参数
bw_方法
sklearn.neights.KernelDensity
中的
带宽
并不代表相同的东西?请看这个问题:你要求的是带宽,不是吗?协方差系数不是带宽,我称之为“带宽”,因为docs调用
bw\u方法
“用于计算估计器带宽的方法”。从统计学上讲,你可能是对的,尽管我不确定你的答案是什么