2.8. 密度估计#

密度估计介于无监督学习、特征工程和数据建模之间。一些最流行和最有用的密度估计技术是混合模型,例如高斯混合模型(GaussianMixture),以及基于邻域的方法,例如核密度估计(KernelDensity)。高斯混合模型在聚类的上下文中进行了更充分的讨论,因为该技术也可用作无监督聚类方案。

密度估计是一个非常简单的概念,大多数人已经熟悉一种常见的密度估计技术:直方图。

2.8.1. 密度估计:直方图#

直方图是数据的简单可视化,其中定义了箱,并计算每个箱内的数据点数。下图左上角面板显示了一个直方图示例。

hist_to_kde

然而,直方图的一个主要问题是,分箱的选择会对最终的可视化结果产生不成比例的影响。考虑上图的右上角面板。它显示了相同数据的直方图,但箱向右移动了。这两个可视化的结果看起来完全不同,并可能导致对数据的不同解释。

直观地说,也可以将直方图视为一堆块,每个点一个块。通过将块堆叠在适当的网格空间中,我们可以恢复直方图。但是,如果我们不将块堆叠在规则网格上,而是将每个块的中心放在它所代表的点上,并对每个位置的总高度求和呢?这个想法导致了左下方的可视化。它可能不如直方图清晰,但数据驱动块位置的事实意味着它是对底层数据更好的表示。

此可视化是*核密度估计*的一个示例,在本例中使用的是顶帽核(即每个点的方形块)。我们可以通过使用更平滑的核来恢复更平滑的分布。右下图显示了高斯核密度估计,其中每个点对总和贡献一条高斯曲线。结果是一个从数据导出的平滑密度估计,它充当对点分布的强大非参数模型。

2.8.2. 核密度估计#

scikit-learn 中的核密度估计在KernelDensity估计器中实现,该估计器使用球树或 KD 树进行高效查询(有关这些的讨论,请参见最近邻)。尽管上面的示例为了简单起见使用了 1D 数据集,但可以在任意维数中执行核密度估计,尽管在实践中,维数灾难会导致其性能在高维中下降。

下图中,从双峰分布中抽取了 100 个点,并显示了三种核函数的核密度估计结果。

kde_1d_distribution

很明显,核的形状会影响结果分布的平滑度。scikit-learn 的核密度估计器使用方法如下:

>>> from sklearn.neighbors import KernelDensity
>>> import numpy as np
>>> X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
>>> kde = KernelDensity(kernel='gaussian', bandwidth=0.2).fit(X)
>>> kde.score_samples(X)
array([-0.41075698, -0.41075698, -0.41076071, -0.41075698, -0.41075698,
       -0.41076071])

这里我们使用了 kernel='gaussian',如上所示。在数学上,核是一个正函数 \(K(x;h)\),它由带宽参数 \(h\) 控制。给定此核函数形式,在一组点 \(x_i; i=1\cdots N\) 中,点 \(y\) 处的密度估计由下式给出:

\[\rho_K(y) = \sum_{i=1}^{N} K(y - x_i; h)\]

这里的带宽充当平滑参数,控制结果中偏差和方差之间的权衡。较大的带宽会导致非常平滑(即高偏差)的密度分布。较小的带宽会导致不平滑(即高方差)的密度分布。

参数 bandwidth 控制此平滑度。可以手动设置此参数,也可以使用 Scott 和 Silverman 的估计方法。

KernelDensity 实现了几种常见的核函数形式,如下图所示

kde_kernels

核函数的数学表达式#

这些核函数的形式如下:

  • 高斯核 (kernel = 'gaussian')

    \(K(x; h) \propto \exp(- \frac{x^2}{2h^2} )\)

  • 均匀核 (kernel = 'tophat')

    \(K(x; h) \propto 1\) 如果 \(x < h\)

  • Epanechnikov 核 (kernel = 'epanechnikov')

    \(K(x; h) \propto 1 - \frac{x^2}{h^2}\)

  • 指数核 (kernel = 'exponential')

    \(K(x; h) \propto \exp(-x/h)\)

  • 线性核 (kernel = 'linear')

    \(K(x; h) \propto 1 - x/h\) 如果 \(x < h\)

  • 余弦核 (kernel = 'cosine')

    \(K(x; h) \propto \cos(\frac{\pi x}{2h})\) 如果 \(x < h\)

核密度估计可以与任何有效的距离度量一起使用(有关可用度量的列表,请参见 DistanceMetric),尽管只有对于欧几里德度量,结果才能正确归一化。一个特别有用的度量是 Haversine 距离,它测量球面上两点之间的角度距离。以下是一个使用核密度估计可视化地理空间数据的示例,在本例中是南美大陆上两种不同物种的观测分布。

species_kde

核密度估计的另一个有用应用是学习数据集的非参数生成模型,以便有效地从此生成模型中抽取新的样本。以下是如何使用此过程创建新的手写数字集的示例,该示例使用在数据的 PCA 投影上学习的高斯核。

digits_kde

“新”数据由输入数据的线性组合组成,其权重根据 KDE 模型概率地得出。

示例