有时候需要观察卷积核参数的分布情况,那么就需要对于卷积核的参数进行统计学意义上的分析。

卷积核数据是随机变量,并且分布是未知的,所以要使用非参数估计的方法进行分布估计。

本文主要介绍的是Kernel Density Estimation(KDE)核密度估计的方法。

博客:https://www.jianshu.com/p/249e5ff97c04 里面有详细的数学公式的推导。

核密度估计:

核密度估计就是采用平滑的峰值函数(“核”)来拟合观察到的数据点,从而对真实的概率分布曲线进行模拟。是一种用于估计概率密度函数的非参数方法。

$x_{1}, x_{2}, ldots . . . x_{n}$为独立同分布的$n$个样本点,设其概率密度函数为$f$,核密度估计如下:

begin{equation}
hat{f}_{h}(x)=frac{1}{n} sum_{i=1}^{n} K_{h}left(x-x_{i}right)=frac{1}{n h} sum_{i=1}^{n} Kleft(frac{x-x_{i}}{h}right)
end{equation}

其中$mathrm{K}( )$为核函数,核函数的要求为符合概率密度的性质,并且均值为0.

$mathrm{h}>0$为一个平滑参数,称作带宽,也有人叫做窗口。右式中带$h$的函数为缩放核函数。

核函数的理解:如果一个数在观察中出现了,就认为这个数的概率密度比较大,如果是高斯核函数,高斯核函数在0处概率密度是最高的,所以上面就会有$x-x_{i}$这一项。如果有$n$个数据点,就把这$n$个数据点估计的密度函数取均值。

常见的核函数:

矩形核函数:

begin{equation}
K(x)=left{begin{array}{ll}{frac{1}{2}} & {text { if }|x| leq 1} \ {0} & {text { otherwise }}end{array}right.
end{equation}

高斯核函数:

begin{equation}
K(x)=frac{1}{sqrt{2 pi}} exp left(-frac{1}{2} x^{2}right)
end{equation}

 

Scikit-learn中的核函数:

Gaussian kernel、Linear kernel、Exponential kernel等等。

 

Python实现:

scikit-learn中有相关的代码,见https://scikit-learn.org/stable/modules/density.html#kernel-density-estimation

 

import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm
from sklearn.neighbors import KernelDensity

#----------------------------------------------------------------------
# Plot a 1D density example
# 总共100个点
N = 100
np.random.seed(1)
# 从双峰曲线生成数据,注意后面[:, np.newaxis]是要变换为2D
X = np.concatenate((np.random.normal(0, 1, int(0.3 * N)),
                    np.random.normal(5, 1, int(0.7 * N))))[:, np.newaxis]

# 从-5到10 等距产生1000个点
X_plot = np.linspace(-5, 10, 1000)[:, np.newaxis]

# 根据X_plot对于双峰曲线进行采样,true_dens是采样值
true_dens = (0.3 * norm(0, 1).pdf(X_plot[:, 0])
             + 0.7 * norm(5, 1).pdf(X_plot[:, 0]))

fig, ax = plt.subplots()
# 画出实际的分布状况
ax.fill(X_plot[:, 0], true_dens, fc='black', alpha=0.2,
        label='input distribution')

for kernel in ['gaussian', 'tophat', 'epanechnikov']:
    # 进行kde核函数估计
    kde = KernelDensity(kernel=kernel, bandwidth=0.5).fit(X)
    # 根据X_plot进行采样,结果为log值
    log_dens = kde.score_samples(X_plot)
    ax.plot(X_plot[:, 0], np.exp(log_dens), '-',
            label="kernel = '{0}'".format(kernel))

# 图例右上角的标注
ax.text(6, 0.38, "N={0} points".format(N))

ax.legend(loc='upper left')
# 画出图例最下面的黑色散点
ax.plot(X[:, 0], -0.005 - 0.01 * np.random.random(X.shape[0]), '+k')

ax.set_xlim(-4, 9)
ax.set_ylim(-0.02, 0.4)
plt.show()

 

卷积核分布分析