非参数估计-高斯核平滑Gaussian kernel smoothing-非参数密度估计

↘锁芯ラ 提交于 2020-03-11 03:39:22

1 非参数回归-核平滑

1.1 概念和计算

非参数化回归是指并不需要知道总的分布的情况下进行的一种统计推断回归方法。

核平滑是一种用来估计实值方程的统计方法,其实也就是一种非参数回归。核平滑来作为周围观察数据的加权平均值。权重由核确定,比如越近的数据权重越大。估计方程式平滑的,平滑程度由一个参数控制。

当预测变量的维度小时(p < 3),这个技术是最有效的,比如对于数据可视化。

计算过程如下:
核函数
参数意义如下:
参数意义
令Y(X) 是一个关于X的连续函数。对于每一个X0,Nadaraya-Watson 加权平均值为 (smooth Y(X) estimation)
加权平均值

1.2 Nadaraya-Watson回归

Nadaraya-Watson回归(Nadaraya-Watson regression)是核回归(kernel regression)方法的一种,是使用核函数对数据进行**非参数估计(nonparametric estimation)**的回归模型。

Nadaraya-Watson回归具有非参数模型(nonparametric model)的一般性质。相比于使用参数估计的回归模型,Nadaraya-Watson回归的优势在于其复杂度由数据而不是预先给定的参数决定,且没有学习,即参数估计步骤;其不足在于模型的每次预测都需要处理所有样本,且在高维样本的情形下表现不佳

1.3 高斯核

高斯核是最常用的核函数之一,表达式如下。
高斯核
一维数据,通过高斯平滑后的结果如下:
在这里插入图片描述

2 高斯核平滑过程-Python实现

2.1 加载库和生成数据

>>> import numpy as np
>>> import matplotlib.pyplot as plt
>>> # Make numpy print 4 significant digits for prettiness
>>> np.set_printoptions(precision=4, suppress=True)
>>> np.random.seed(5) # To get predictable random numbers

>>> n_points = 40
>>> x_vals = np.arange(n_points)
>>> y_vals = np.random.normal(size=n_points)
>>> plt.bar(x_vals, y_vals)

生成数据

标准的高斯分布如下:

>>> x = np.arange(-6, 6, 0.1) # x from -6 to 6 in steps of 0.1
>>> y = 1 / np.sqrt(2 * np.pi) * np.exp(-x ** 2 / 2.)
>>> plt.plot(x, y)

高斯分布

2.2 Full Width at Half Maximum (FWHM)

在统计上,通常我们通过标准差σ来定义高斯分布的形状。不过,当高斯分布用来做平滑时,我们通常使用**Full Width at Half Maximum (FWHM)**来描述高斯分布的宽度。

FWHM是核的宽度,高斯分布高度最大值的一半的两坐标距离。因此,对于上面的标准高斯分布,最大的高度约为0.4,宽度是0.2。这时,对应的x坐标分别是x = -1.175,和x = 1.175,那么FWHM = 2.35。

FWHM 和 σ 的互换公式如下:

>>> def sigma2fwhm(sigma):
...     return sigma * np.sqrt(8 * np.log(2))

>>> def fwhm2sigma(fwhm):
...     return fwhm / np.sqrt(8 * np.log(2))

我们的例子里:

>>> sigma2fwhm(1)
2.3548200450309493

2.3 分步进行平滑

做平滑的过程很简单。我们一个点一个点的来进行处理。对于每一个数据点,我们都会生成一个新的值。这个值的生成过程如下:

首先我们使用某个函数(在高斯平滑中,这个函数就是我们的高斯分布),根据原先该点的数值和它周围的点的数值,我们生成一些数值。

比如,对于我们数据集里的第十四个点。我们使用FWHM 为4(x 轴)的高斯分布。为了生成第14个点的新值,我们将高斯分布的中心移动到x =13(第一个点为0)。(为了确保平滑后不进行值的整体缩放,我们将高斯曲线中的值除以曲线下的总面积,使这些值相加为一。)

>>> FWHM = 4
>>> sigma = fwhm2sigma(FWHM)
>>> x_position = 13 # 14th point
>>> kernel_at_pos = np.exp(-(x_vals - x_position) ** 2 / (2 * sigma ** 2))
>>> kernel_at_pos = kernel_at_pos / sum(kernel_at_pos)
>>> plt.bar(x_vals, kernel_at_pos)

13
高斯分布得到的第12 - 第16个点的值,分别是:

>>> kernel_at_pos[11:16]
array([ 0.1174,  0.1975,  0.2349,  0.1975,  0.1174])

真实数据的第12 - 第16个点的值,分别是:

>>> y_vals[11:16]
array([-0.2049, -0.3588,  0.6035, -1.6648, -0.7002])

然后,我们将高斯核的权重值,和我们原始数据相乘,对结果求和,就得到了我们平滑后的新值(对于第13个点)。

>>> y_by_weight = y_vals * kernel_at_pos # element-wise multiplication
>>> new_val = sum(y_by_weight)
>>> new_val
-0.34796859011845732

对于原始数据的每一个点,我们都重复上述的过程,就得到了高斯平滑后的数据。

>>> for x_position in x_vals:
...     kernel = np.exp(-(x_vals - x_position) ** 2 / (2 * sigma ** 2))
...     kernel = kernel / sum(kernel)
...     smoothed_vals[x_position] = sum(y_vals * kernel)
>>> plt.bar(x_vals, smoothed_vals)

平滑
平滑也可以被实现并理解为卷积(convolution)

2.4 二维平滑

这时高斯分布不再是一个曲线,而是一个圆锥形。

>>> fig = plt.figure()
>>> ax = fig.add_subplot(111, projection='3d')
>>> dx = 0.1
>>> dy = 0.1
>>> x = np.arange(-6, 6, dx)
>>> y = np.arange(-6, 6, dy)
>>> x2d, y2d = np.meshgrid(x, y)
>>> kernel_2d = np.exp(-(x2d ** 2 + y2d ** 2) / (2 * sigma ** 2))
>>> kernel_2d = kernel_2d / (2 * np.pi * sigma ** 2) # unit integral
>>> ax.plot_surface(x2d, y2d, kernel_2d)

和一维数据一样,对于每一个点,我们将kernel的值和原始数据值相乘,来得到这个点平滑之后的值。

2.5 为什么要进行平滑

主要原因是增加信噪比(signal to noise)

比如下面的例子。

生成的一维信号如下所示:

>>> FWHM = 8
>>> sigma = fwhm2sigma(FWHM)
>>> x_position = 13 # 14th point
>>> sim_signal = np.exp(-(x_vals - x_position) ** 2 / (2 * sigma ** 2))
>>> plt.bar(x_vals, sim_signal)

信号
然后我们向信号中增加噪音:

>>> noise = np.random.normal(size=n_points)
>>> sim_data = sim_signal + noise
>>> plt.bar(x_vals, sim_data)

增加噪音
下面使用高斯平滑

>>> smoothed_sim_data = np.zeros(y_vals.shape)
>>> for x_position in x_vals:
...     kernel = np.exp(-(x_vals - x_position) ** 2 / (2 * sigma ** 2))
...     kernel = kernel / sum(kernel)
...     smoothed_sim_data[x_position] = sum(sim_data * kernel)
>>> plt.bar(x_vals, smoothed_sim_data)

平滑后-滤波

3 非参数密度估计(Non-parametric density estimation)

讲得非常明白的课件:http://courses.cs.tamu.edu/rgutier/csce666_f13/l7.pdf

3.1 直方图

这是最简单的非参数密度估计方法。

将样本空间分成很多个柱子(bins),通过将落入相应bin的样本数量和训练样本的数量相比,得到该bin的密度。

公式
直方图估计得到下面的结果。
在这里插入图片描述
直方图方法很简单,但是有很多不足。

  1. 密度估计依赖bin起始位置。对于多元变量数据,密度分布也会被bin的方向影响。
  2. 估计的不连续,不是由于潜在的密度,只是由于选择的bin的位置。
  3. 维度灾难。因为bins的数量,会随着数据维度的增加而迅速呈指数增加。

因此,直方图分布不适合在现实中使用(除非是一维或二维可视化的需要)。

3.2 非参数密度估计的通常形式

从分布P(x) 中提取的向量x 落入样本空间的给定区域R 的概率为
概率
假设从分布中得到的N 向量{X1,X2,……,XN},这N 向量里面的k 个落在R 区域的概率为二项分布,如下:
二项分布
根据二项分布的性质,得到了k / N 的平均值和方差。

均值-方差
计算过程
计算过程2
计算3
计算4
计算5

3.3 Parzen windows

计算1

计算2
计算3
Pkde(X) 的期望,其实就是真实P(X) 和核函数的卷积

Parzen windows 的具体计算过程:
在这里插入图片描述

3.4 Smooth kernels

3.4.1 概念-为什么选择?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.4.2 如何选择Bandwidth

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

4 总结

总的来说,通过样本来估计未知分布函数或位置概率密度的方法,叫做非参数估计

非参数估计中包括非参数回归非参数密度估计

其中,非参数回归中的一种是核平滑。分参数密度估计的一种是核密度估计

之所以搞混的原因,其实就是因为他们都使用了核函数。使用核函数进行上面两类计算的时候,其实都类似于卷积的操作,也就是求加权平均值

参考资料:
https://matthew-brett.github.io/teaching/smoothing_intro.html#smoothing-as-convolution
https://en.wikipedia.org/wiki/Kernel_smoother
http://courses.cs.tamu.edu/rgutier/csce666_f13/l7.pdf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!