我手头没有这本书,所以我不确定 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))