Python科学计算(第2版)
上QQ阅读APP看书,第一时间看更新

3.4.3 核密度估计

在上面的例子中,由于每个取样都是离散的,因此其平均值也是离散的,对这样的数据进行直方图统计很容易出现许多离散点恰巧聚集到同一区间的现象。为了更平滑地显示样本的概率密度,可以使用kde.gaussian_kde( )进行核密度估计。在图3-12中,直方图统计的结果有很大的起伏,而核密度估计与拟合的正态分布十分接近,因此验证了中心极限定理。

图3-12 核密度估计能更准确地表示随机变量的概率密度函数

    _, bins, step = pl.hist(
        samples_mean, bins=100, normed=True, histtype="step", label=u"直方图统计")
    kde = stats.kde.gaussian_kde(samples_mean)
    x = np.linspace(bins[0], bins[-1], 100)
    pl.plot(x, kde(x), label=u"核密度估计")
    mean, std = stats.norm.fit(samples_mean)
    pl.plot(x, stats.norm(mean, std).pdf(x), alpha=0.8, label=u"正态分布拟合")
    pl.legend( )

核密度估计算法在每个数据点处放置一条核函数曲线,最终的核密度估计就是所有这些核函数曲线的叠加。gaussian_kde( )的核函数为高斯曲线,其bw_method参数决定核函数的宽度,即高斯曲线的方差。bw_method参数可以是如下几种情况:

●当为'scott'、'silverman'时将采用相应的公式根据数据个数和维数决定核函数的宽度系数。

●当为函数时将调用此函数计算曲线宽度系数,函数的参数为gaussian_kde对象。

●当为数值时,将直接使用此数值作为宽度系数。

核函数的方差由数据的方差和宽度系数决定。

下面的程序比较宽度系数对核密度估计的影响。当宽度系数较小时,可以看到在三个数据点处的高斯曲线的峰值,而当宽度逐渐变大时,这些峰值就合并成一个统一的峰值了。

    for bw in [0.2, 0.3, 0.6, 1.0]:
        kde = stats.gaussian_kde([-1, 0, 1], bw_method=bw)
        x = np.linspace(-5, 5, 1000)
        y = kde(x)
        pl.plot(x, y, lw=2, label="bw={}".format(bw), alpha=0.6)
    pl.legend(loc="best")

图3-13显示bw_method参数越大,核密度估计曲线越平滑。

图3-13 bw_method参数越大,核密度估计曲线越平滑