John Kruschke在他的《做贝叶斯数据分析》一书中指出,使用R中的JAGS
...根据MCMC样本进行的模式估算可能相当不稳定,因为该估算基于平滑算法,该算法对MCMC样本中的随机隆起和波动敏感。(进行贝叶斯数据分析,第205页,第8.2.5.1节)
虽然我对Metropolis算法和Gibbs采样之类的精确形式有所了解,但我也不熟悉所提到的平滑算法,以及为什么这意味着从MCMC样本中估计模式是不稳定的。是否有人能够直观地了解平滑算法的作用以及为什么会使模式的估计不稳定?
John Kruschke在他的《做贝叶斯数据分析》一书中指出,使用R中的JAGS
...根据MCMC样本进行的模式估算可能相当不稳定,因为该估算基于平滑算法,该算法对MCMC样本中的随机隆起和波动敏感。(进行贝叶斯数据分析,第205页,第8.2.5.1节)
虽然我对Metropolis算法和Gibbs采样之类的精确形式有所了解,但我也不熟悉所提到的平滑算法,以及为什么这意味着从MCMC样本中估计模式是不稳定的。是否有人能够直观地了解平滑算法的作用以及为什么会使模式的估计不稳定?
Answers:
我手头没有书,所以我不确定Kruschke使用哪种平滑方法,但是出于直觉,请考虑从标准法线中抽取的100个样本的图表,以及使用从0.1到1.0的各种带宽的高斯核密度估计。(简而言之,高斯KDE是一种平滑的直方图:它们通过为每个数据点添加一个高斯来估计密度,平均值为观察值。)
您可以看到,即使平滑创建了单峰分布,该模式通常也低于已知值0。
更多,这是使用相同样本的用于估计密度的内核带宽估算模式(y轴)的图。希望这可以使估算值随平滑参数的变化而有所直观。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Feb 1 09:35:51 2017
@author: seaneaster
"""
import numpy as np
from matplotlib import pylab as plt
from sklearn.neighbors import KernelDensity
REAL_MODE = 0
np.random.seed(123)
def estimate_mode(X, bandwidth = 0.75):
kde = KernelDensity(kernel = 'gaussian', bandwidth = bandwidth).fit(X)
u = np.linspace(-3,3,num=1000)[:, np.newaxis]
log_density = kde.score_samples(u)
return u[np.argmax(log_density)]
X = np.random.normal(REAL_MODE, size = 100)[:, np.newaxis] # keeping to standard normal
bandwidths = np.linspace(0.1, 1., num = 8)
plt.figure(0)
plt.hist(X, bins = 100, normed = True, alpha = 0.25)
for bandwidth in bandwidths:
kde = KernelDensity(kernel = 'gaussian', bandwidth = bandwidth).fit(X)
u = np.linspace(-3,3,num=1000)[:, np.newaxis]
log_density = kde.score_samples(u)
plt.plot(u, np.exp(log_density))
bandwidths = np.linspace(0.1, 3., num = 100)
modes = [estimate_mode(X, bandwidth) for bandwidth in bandwidths]
plt.figure(1)
plt.plot(bandwidths, np.array(modes))
肖恩·复活节(Sean Easter)提供了一个很好的答案。这是Kruschke随书附带的R脚本实际上是如何完成的。该plotPost()
函数在名为的R脚本中定义DBDA2E-utilities.R
。它显示估计的模式。在函数定义中,有以下两行:
mcmcDensity = density(paramSampleVec)
mo = mcmcDensity$x[which.max(mcmcDensity$y)]
该density()
函数带有R的基本stats包,并实现了Sean Easter描述的那种内核密度过滤器。对于平滑内核的带宽以及要使用的内核类型,它具有可选参数。它默认为高斯内核,并具有一些寻找合适带宽的内在魔力。该density()
函数返回一个对象,该对象的组件名为y
,具有在各种值下的平滑密度x
。上面的第二行代码只是找到x
其中y
的最大值。