python(sklearn)中的二维核密度估计如何工作?

Posted

技术标签:

【中文标题】python(sklearn)中的二维核密度估计如何工作?【英文标题】:how does 2d kernel density estimation in python (sklearn) work? 【发布时间】:2017-05-25 11:11:43 【问题描述】:

对于这个可能很愚蠢的问题,我很抱歉,但我现在正在尝试几个小时来估计一组二维数据的密度。假设我的数据由数组给出:sample = np.random.uniform(0,1,size=(50,2))。我只想使用 scipys scikit learn 包来估计样本数组的密度(这里当然是二维均匀密度),我正在尝试以下操作:

import numpy as np
from sklearn.neighbors.kde import KernelDensity
from matplotlib import pyplot as plt
sp = 0.01

samples = np.random.uniform(0,1,size=(50,2))  # random samples
x = y = np.linspace(0,1,100)
X,Y = np.meshgrid(x,y)     # creating grid of data , to evaluate estimated density on

kde = KernelDensity(kernel='gaussian', bandwidth=0.2).fit(samples) # creating density from samples

kde.score_samples(X,Y) # I want to evaluate the estimated density on the X,Y grid

但最后一步总是会产生错误:score_samples() takes 2 positional arguments but 3 were given

所以可能 .score_samples 不能将网格作为输入,但是没有针对 2d 案例的教程/文档,所以我不知道如何解决这个问题。如果有人可以提供帮助,那就太好了。

【问题讨论】:

那是因为kde.score_samples 只接受一个参数X。您是否尝试阅读文档?对于几乎所有 sklearn 模型,您必须致电 model.fit(X,Y) 然后您才能在 X 上使用 score_samples 【参考方案1】:

查看Kernel Density Estimate of Species Distributions 示例,您必须将 x,y 数据打包在一起(训练数据和新样本网格)。

下面是一个简化 sklearn API 的函数。

from sklearn.neighbors import KernelDensity

def kde2D(x, y, bandwidth, xbins=100j, ybins=100j, **kwargs): 
    """Build 2D kernel density estimate (KDE)."""

    # create grid of sample locations (default: 100x100)
    xx, yy = np.mgrid[x.min():x.max():xbins, 
                      y.min():y.max():ybins]

    xy_sample = np.vstack([yy.ravel(), xx.ravel()]).T
    xy_train  = np.vstack([y, x]).T

    kde_skl = KernelDensity(bandwidth=bandwidth, **kwargs)
    kde_skl.fit(xy_train)

    # score_samples() returns the log-likelihood of the samples
    z = np.exp(kde_skl.score_samples(xy_sample))
    return xx, yy, np.reshape(z, xx.shape)

这为您提供了散点图或 pcolormesh 图等所需的 xx、yy、zz。我已经从 gaussian_kde 函数的 scipy 页面复制了示例。

import numpy as np
import matplotlib.pyplot as plt

m1 = np.random.normal(size=1000)
m2 = np.random.normal(scale=0.5, size=1000)

x, y = m1 + m2, m1 - m2

xx, yy, zz = kde2D(x, y, 1.0)

plt.pcolormesh(xx, yy, zz)
plt.scatter(x, y, s=2, facecolor='white')

【讨论】:

非常感谢@geoff! 非常感谢!请注意,您对np.random.rand 的使用现在是np.random.normal @Alex,确实感谢您的关注。我已经纠正了错误。 您的示例比他们的文档更简单,因此更易于使用:)

以上是关于python(sklearn)中的二维核密度估计如何工作?的主要内容,如果未能解决你的问题,请参考以下文章

机器学习sklearn简单易懂核密度估计KernelDensity

使用 scipy 的 gaussian_kde 和 sklearn 的 KernelDensity 进行核密度估计会导致不同的结果

`python`中的加权高斯核密度估计

Python中的多变量核密度估计

在 R 中为 2D 核密度估计实现不同的核

scipy.stats :高斯核密度估计器中的带宽因子