# coding: utf-8

# DO NOT EDIT
# Autogenerated from the notebook kernel_density.ipynb.
# Edit the notebook and then sync the output with this file.
#
# flake8: noqa
# DO NOT EDIT

# # 核密度估计
#
# 核密度估计是使用 *核函数* $K(u)$ 估计一个未知概率密度函数的过程。 直方图可以对任意区域中数据点的数量进行计数，
# 而核密度估计是定义每个数据点的核函数之和的函数。 核函数通常具有以下属性：
#
# 1. 对称，使得 $K(u) = K(-u)$.
# 2. 标准化，使得 $\int_{-\infty}^{\infty} K(u) \ du = 1$ .
# 3. 当 $u > 0$时，单调递减，使得 $K'(u) < 0$ 
# 4. 期望值等于 0，使得 $\mathrm{E}[K] = 0$.
#
# 有关核密度估计的更多信息，请参见示例 [维基百科-核密度估计](https://en.wikipedia.org/wiki/Kernel_density_estimation).
#
# 单变量核密度估计在 `sm.nonparametric.KDEUnivariate` 中实现。 在此示例中，我们将展示如下内容：
#
# * 基本用法，如何拟合估计器。
# * 使用 `bw` 参数改变核带宽的影响。
# * 使用 `kernel` 参数可以使用各种核函数。

import numpy as np
from scipy import stats
import statsmodels.api as sm
import matplotlib.pyplot as plt
from statsmodels.distributions.mixture_rvs import mixture_rvs

# ## 单变量示例

np.random.seed(
    12345)  # 设置随机数生成器种子，使结果可重现

# 创建一个双峰分布：两个正态分布的混合体，其位置分别为 `-1` 和 `1`。


# 两种分布的位置、比例和权重
dist1_loc, dist1_scale, weight1 = -1, .5, .25
dist2_loc, dist2_scale, weight2 = 1, .5, .75

# 混合分布样本
obs_dist = mixture_rvs(
    prob=[weight1, weight2],
    size=250,
    dist=[stats.norm, stats.norm],
    kwargs=(dict(loc=dist1_loc, scale=dist1_scale),
            dict(loc=dist2_loc, scale=dist2_scale)))

# 密度估计最简单的非参数技术是直方图。

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

# 数据样本的散点图和直方图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)),
    zorder=15,
    color='red',
    marker='x',
    alpha=0.5,
    label='Samples')
lines = ax.hist(obs_dist, bins=20, edgecolor='k', label='Histogram')

ax.legend(loc='best')
ax.grid(True, zorder=-5)

# ## 以默认参数拟合

# 上面的直方图是不连续的。如要计算一个连续概率密度函数，我们可以使用核密度估计。
#
# 我们使用 `KDEUnivariate` 来初始化单变量内核密度估计器。


kde = sm.nonparametric.KDEUnivariate(obs_dist)
kde.fit()  # 估计密度

# 绘制一张符合真实分布的拟合图

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

# 绘制直方图
ax.hist(
    obs_dist,
    bins=20,
    normed=True,
    label='Histogram from samples',
    zorder=5,
    edgecolor='k',
    alpha=0.5)

# 使用默认参数绘制 KDE 拟合图
ax.plot(kde.support, kde.density, lw=3, label='KDE from samples', zorder=10)

# 绘制真实分布图
true_values = (
    stats.norm.pdf(loc=dist1_loc, scale=dist1_scale, x=kde.support) * weight1 +
    stats.norm.pdf(loc=dist2_loc, scale=dist2_scale, x=kde.support) * weight2)
ax.plot(kde.support, true_values, lw=3, label='True distribution', zorder=15)

# 绘制样本散点图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)) / 40,
    marker='x',
    color='red',
    zorder=20,
    label='Samples',
    alpha=0.5)

ax.legend(loc='best')
ax.grid(True, zorder=-5)

# 在上面的代码中，使用了默认参数。 如我们所见，我们还可以改变内核的带宽。

# ## 使用 `bw` 参数改变带宽

# 内核的带宽可以使用 `bw` 参数来调整。
# 在下面的示例中，`bw=0.2` 的带宽很好地拟合了数据。


fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

# 绘制直方图
ax.hist(
    obs_dist,
    bins=25,
    label='Histogram from samples',
    zorder=5,
    edgecolor='k',
    normed=True,
    alpha=0.5)

# 绘制各种带宽的 KDE 图
for bandwidth in [0.1, 0.2, 0.4]:
    kde.fit(bw=bandwidth)  # Estimate the densities
    ax.plot(
        kde.support,
        kde.density,
        '--',
        lw=2,
        color='k',
        zorder=10,
        label='KDE from samples, bw = {}'.format(round(bandwidth, 2)))

# 绘制真实分布
ax.plot(kde.support, true_values, lw=3, label='True distribution', zorder=15)

# 绘制样本散点图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)) / 50,
    marker='x',
    color='red',
    zorder=20,
    label='Data samples',
    alpha=0.5)

ax.legend(loc='best')
ax.set_xlim([-3, 3])
ax.grid(True, zorder=-5)

# ## 比较各种核函数

# 在上面的示例中，使用了 Gaussian 内核。 其他几个内核也可用。

from statsmodels.nonparametric.kde import kernel_switch
list(kernel_switch.keys())

# ### 可用的内核函数

# 创建一个空白画布
fig = plt.figure(figsize=(12, 5))

# 为内核列举每个选项
for i, (ker_name, ker_class) in enumerate(kernel_switch.items()):

    # 初始化内核对象
    kernel = ker_class()

    # 来自 domain 的样本
    domain = kernel.domain or [-3, 3]
    x_vals = np.linspace(*domain, num=2**10)
    y_vals = kernel(x_vals)

    # 创建一个子图并设置标题
    ax = fig.add_subplot(2, 4, i + 1)
    ax.set_title('Kernel function "{}"'.format(ker_name))
    ax.plot(x_vals, y_vals, lw=3, label='{}'.format(ker_name))
    ax.scatter([0], [0], marker='x', color='red')
    plt.grid(True, zorder=-5)
    ax.set_xlim(domain)

plt.tight_layout()

# ### 三个数据点上可用的内核函数

# 现在我们检查核密度估计如何拟合三个等距的数据点。

# 创建三个等距点
data = np.linspace(-1, 1, 3)
kde = sm.nonparametric.KDEUnivariate(data)

# 创建一个空白画布
fig = plt.figure(figsize=(12, 5))

# 为内核列举每个选项
for i, kernel in enumerate(kernel_switch.keys()):

    # 创建一个子图并设置标题
    ax = fig.add_subplot(2, 4, i + 1)
    ax.set_title('Kernel function "{}"'.format(kernel))

    # 拟合模型(密度估计))
    kde.fit(kernel=kernel, fft=False, gridsize=2**10)

    # 绘图
    ax.plot(
        kde.support, kde.density, lw=3, label='KDE from samples', zorder=10)
    ax.scatter(data, np.zeros_like(data), marker='x', color='red')
    plt.grid(True, zorder=-5)
    ax.set_xlim([-3, 3])

plt.tight_layout()

# ## 更加复杂的情况
#
# 拟合并不总是完美的。 请参阅下面的示例来了解更加复杂的情况。


obs_dist = mixture_rvs([.25, .75],
                       size=250,
                       dist=[stats.norm, stats.beta],
                       kwargs=(dict(loc=-1, scale=.5),
                               dict(loc=1, scale=1, args=(1, .5))))

kde = sm.nonparametric.KDEUnivariate(obs_dist)
kde.fit()

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)
ax.hist(obs_dist, bins=20, normed=True, edgecolor='k', zorder=4, alpha=0.5)
ax.plot(kde.support, kde.density, lw=3, zorder=7)
# 绘制样本散点图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)) / 50,
    marker='x',
    color='red',
    zorder=20,
    label='Data samples',
    alpha=0.5)
ax.grid(True, zorder=-5)

# ## KDE 发行版
#
# 由于 KDE 是发行版，所以我们可以访问 KDE 的属性和方法
#
# - `entropy`
# - `evaluate`
# - `cdf`
# - `icdf`
# - `sf`
# - `cumhazard`

obs_dist = mixture_rvs([.25, .75],
                       size=1000,
                       dist=[stats.norm, stats.norm],
                       kwargs=(dict(loc=-1, scale=.5), dict(loc=1, scale=.5)))
kde = sm.nonparametric.KDEUnivariate(obs_dist)
kde.fit(gridsize=2**10)

kde.entropy

kde.evaluate(-1)

# ### 累积分布，逆和生存函数

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

ax.plot(kde.support, kde.cdf, lw=3, label='CDF')
ax.plot(
    np.linspace(0, 1, num=kde.icdf.size), kde.icdf, lw=3, label='Inverse CDF')
ax.plot(kde.support, kde.sf, lw=3, label='Survival function')
ax.legend(loc='best')
ax.grid(True, zorder=-5)

# ### 累积 Hazard 函数

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)
ax.plot(kde.support, kde.cumhazard, lw=3, label='Cumulative Hazard Function')
ax.legend(loc='best')
ax.grid(True, zorder=-5)

# coding: utf-8

# DO NOT EDIT
# Autogenerated from the notebook kernel_density.ipynb.
# Edit the notebook and then sync the output with this file.
#
# flake8: noqa
# DO NOT EDIT

# # 核密度估计
#
# 核密度估计是使用 *核函数* $K(u)$ 估计一个未知概率密度函数的过程。 直方图可以对任意区域中数据点的数量进行计数，
# 而核密度估计是定义每个数据点的核函数之和的函数。 核函数通常具有以下属性：
#
# 1. 对称，使得 $K(u) = K(-u)$.
# 2. 标准化，使得 $\int_{-\infty}^{\infty} K(u) \ du = 1$ .
# 3. 当 $u > 0$时，单调递减，使得 $K'(u) < 0$ 
# 4. 期望值等于 0，使得 $\mathrm{E}[K] = 0$.
#
# 有关核密度估计的更多信息，请参见示例 [维基百科-核密度估计](https://en.wikipedia.org/wiki/Kernel_density_estimation).
#
# 单变量核密度估计在 `sm.nonparametric.KDEUnivariate` 中实现。 在此示例中，我们将展示如下内容：
#
# * 基本用法，如何拟合估计器。
# * 使用 `bw` 参数改变核带宽的影响。
# * 使用 `kernel` 参数可以使用各种核函数。

import numpy as np
from scipy import stats
import statsmodels.api as sm
import matplotlib.pyplot as plt
from statsmodels.distributions.mixture_rvs import mixture_rvs

# ## 单变量示例

np.random.seed(
    12345)  # 设置随机数生成器种子，使结果可重现

# 创建一个双峰分布：两个正态分布的混合体，其位置分别为 `-1` 和 `1`。


# 两种分布的位置、比例和权重
dist1_loc, dist1_scale, weight1 = -1, .5, .25
dist2_loc, dist2_scale, weight2 = 1, .5, .75

# 混合分布样本
obs_dist = mixture_rvs(
    prob=[weight1, weight2],
    size=250,
    dist=[stats.norm, stats.norm],
    kwargs=(dict(loc=dist1_loc, scale=dist1_scale),
            dict(loc=dist2_loc, scale=dist2_scale)))

# 密度估计最简单的非参数技术是直方图。

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

# 数据样本的散点图和直方图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)),
    zorder=15,
    color='red',
    marker='x',
    alpha=0.5,
    label='Samples')
lines = ax.hist(obs_dist, bins=20, edgecolor='k', label='Histogram')

ax.legend(loc='best')
ax.grid(True, zorder=-5)

# ## 以默认参数拟合

# 上面的直方图是不连续的。如要计算一个连续概率密度函数，我们可以使用核密度估计。
#
# 我们使用 `KDEUnivariate` 来初始化单变量内核密度估计器。


kde = sm.nonparametric.KDEUnivariate(obs_dist)
kde.fit()  # 估计密度

# 绘制一张符合真实分布的拟合图

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

# 绘制直方图
ax.hist(
    obs_dist,
    bins=20,
    normed=True,
    label='Histogram from samples',
    zorder=5,
    edgecolor='k',
    alpha=0.5)

# 使用默认参数绘制 KDE 拟合图
ax.plot(kde.support, kde.density, lw=3, label='KDE from samples', zorder=10)

# 绘制真实分布图
true_values = (
    stats.norm.pdf(loc=dist1_loc, scale=dist1_scale, x=kde.support) * weight1 +
    stats.norm.pdf(loc=dist2_loc, scale=dist2_scale, x=kde.support) * weight2)
ax.plot(kde.support, true_values, lw=3, label='True distribution', zorder=15)

# 绘制样本散点图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)) / 40,
    marker='x',
    color='red',
    zorder=20,
    label='Samples',
    alpha=0.5)

ax.legend(loc='best')
ax.grid(True, zorder=-5)

# 在上面的代码中，使用了默认参数。 如我们所见，我们还可以改变内核的带宽。

# ## 使用 `bw` 参数改变带宽

# 内核的带宽可以使用 `bw` 参数来调整。
# 在下面的示例中，`bw=0.2` 的带宽很好地拟合了数据。


fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

# 绘制直方图
ax.hist(
    obs_dist,
    bins=25,
    label='Histogram from samples',
    zorder=5,
    edgecolor='k',
    normed=True,
    alpha=0.5)

# 绘制各种带宽的 KDE 图
for bandwidth in [0.1, 0.2, 0.4]:
    kde.fit(bw=bandwidth)  # Estimate the densities
    ax.plot(
        kde.support,
        kde.density,
        '--',
        lw=2,
        color='k',
        zorder=10,
        label='KDE from samples, bw = {}'.format(round(bandwidth, 2)))

# 绘制真实分布
ax.plot(kde.support, true_values, lw=3, label='True distribution', zorder=15)

# 绘制样本散点图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)) / 50,
    marker='x',
    color='red',
    zorder=20,
    label='Data samples',
    alpha=0.5)

ax.legend(loc='best')
ax.set_xlim([-3, 3])
ax.grid(True, zorder=-5)

# ## 比较各种核函数

# 在上面的示例中，使用了 Gaussian 内核。 其他几个内核也可用。

from statsmodels.nonparametric.kde import kernel_switch
list(kernel_switch.keys())

# ### 可用的内核函数

# 创建一个空白画布
fig = plt.figure(figsize=(12, 5))

# 为内核列举每个选项
for i, (ker_name, ker_class) in enumerate(kernel_switch.items()):

    # 初始化内核对象
    kernel = ker_class()

    # 来自 domain 的样本
    domain = kernel.domain or [-3, 3]
    x_vals = np.linspace(*domain, num=2**10)
    y_vals = kernel(x_vals)

    # 创建一个子图并设置标题
    ax = fig.add_subplot(2, 4, i + 1)
    ax.set_title('Kernel function "{}"'.format(ker_name))
    ax.plot(x_vals, y_vals, lw=3, label='{}'.format(ker_name))
    ax.scatter([0], [0], marker='x', color='red')
    plt.grid(True, zorder=-5)
    ax.set_xlim(domain)

plt.tight_layout()

# ### 三个数据点上可用的内核函数

# 现在我们检查核密度估计如何拟合三个等距的数据点。

# 创建三个等距点
data = np.linspace(-1, 1, 3)
kde = sm.nonparametric.KDEUnivariate(data)

# 创建一个空白画布
fig = plt.figure(figsize=(12, 5))

# 为内核列举每个选项
for i, kernel in enumerate(kernel_switch.keys()):

    # 创建一个子图并设置标题
    ax = fig.add_subplot(2, 4, i + 1)
    ax.set_title('Kernel function "{}"'.format(kernel))

    # 拟合模型(密度估计))
    kde.fit(kernel=kernel, fft=False, gridsize=2**10)

    # 绘图
    ax.plot(
        kde.support, kde.density, lw=3, label='KDE from samples', zorder=10)
    ax.scatter(data, np.zeros_like(data), marker='x', color='red')
    plt.grid(True, zorder=-5)
    ax.set_xlim([-3, 3])

plt.tight_layout()

# ## 更加复杂的情况
#
# 拟合并不总是完美的。 请参阅下面的示例来了解更加复杂的情况。


obs_dist = mixture_rvs([.25, .75],
                       size=250,
                       dist=[stats.norm, stats.beta],
                       kwargs=(dict(loc=-1, scale=.5),
                               dict(loc=1, scale=1, args=(1, .5))))

kde = sm.nonparametric.KDEUnivariate(obs_dist)
kde.fit()

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)
ax.hist(obs_dist, bins=20, normed=True, edgecolor='k', zorder=4, alpha=0.5)
ax.plot(kde.support, kde.density, lw=3, zorder=7)
# 绘制样本散点图
ax.scatter(
    obs_dist,
    np.abs(np.random.randn(obs_dist.size)) / 50,
    marker='x',
    color='red',
    zorder=20,
    label='Data samples',
    alpha=0.5)
ax.grid(True, zorder=-5)

# ## KDE 发行版
#
# 由于 KDE 是发行版，所以我们可以访问 KDE 的属性和方法
#
# - `entropy`
# - `evaluate`
# - `cdf`
# - `icdf`
# - `sf`
# - `cumhazard`

obs_dist = mixture_rvs([.25, .75],
                       size=1000,
                       dist=[stats.norm, stats.norm],
                       kwargs=(dict(loc=-1, scale=.5), dict(loc=1, scale=.5)))
kde = sm.nonparametric.KDEUnivariate(obs_dist)
kde.fit(gridsize=2**10)

kde.entropy

kde.evaluate(-1)

# ### 累积分布，逆和生存函数

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)

ax.plot(kde.support, kde.cdf, lw=3, label='CDF')
ax.plot(
    np.linspace(0, 1, num=kde.icdf.size), kde.icdf, lw=3, label='Inverse CDF')
ax.plot(kde.support, kde.sf, lw=3, label='Survival function')
ax.legend(loc='best')
ax.grid(True, zorder=-5)

# ### 累积 Hazard 函数

fig = plt.figure(figsize=(12, 5))
ax = fig.add_subplot(111)
ax.plot(kde.support, kde.cumhazard, lw=3, label='Cumulative Hazard Function')
ax.legend(loc='best')
ax.grid(True, zorder=-5)

# coding: utf-8 # DO NOT EDIT # Autogenerated from the notebook kernel_density.ipynb. # Edit the notebook and then sync the output with this file. # # flake8: noqa # DO NOT EDIT # # 核密度估计 # # 核密度估计是使用 *核函数* $K(u)$ 估计一个未知概率密度函数的过程。 直方图可以对任意区域中数据点的数量进行计数， # 而核密度估计是定义每个数据点的核函数之和的函数。 核函数通常具有以下属性： # # 1. 对称，使得 $K(u) = K(-u)$. # 2. 标准化，使得 $\int_{-\infty}^{\infty} K(u) \ du = 1$ . # 3. 当 $u > 0$时，单调递减，使得 $K'(u) < 0$ # 4. 期望值等于 0，使得 $\mathrm{E}[K] = 0$. # # 有关核密度估计的更多信息，请参见示例 [维基百科-核密度估计](https://en.wikipedia.org/wiki/Kernel_density_estimation). # # 单变量核密度估计在 `sm.nonparametric.KDEUnivariate` 中实现。 在此示例中，我们将展示如下内容： # # * 基本用法，如何拟合估计器。 # * 使用 `bw` 参数改变核带宽的影响。 # * 使用 `kernel` 参数可以使用各种核函数。 # ## 单变量示例 # 设置随机数生成器种子，使结果可重现 # 创建一个双峰分布：两个正态分布的混合体，其位置分别为 `-1` 和 `1`。 # 两种分布的位置、比例和权重 # 混合分布样本 # 密度估计最简单的非参数技术是直方图。 # 数据样本的散点图和直方图 # ## 以默认参数拟合 # 上面的直方图是不连续的。如要计算一个连续概率密度函数，我们可以使用核密度估计。 # # 我们使用 `KDEUnivariate` 来初始化单变量内核密度估计器。 # 估计密度 # 绘制一张符合真实分布的拟合图 # 绘制直方图 # 使用默认参数绘制 KDE 拟合图 # 绘制真实分布图 # 绘制样本散点图 # 在上面的代码中，使用了默认参数。 如我们所见，我们还可以改变内核的带宽。 # ## 使用 `bw` 参数改变带宽 # 内核的带宽可以使用 `bw` 参数来调整。 # 在下面的示例中，`bw=0.2` 的带宽很好地拟合了数据。 # 绘制直方图 # 绘制各种带宽的 KDE 图 # Estimate the densities # 绘制真实分布 # 绘制样本散点图 # ## 比较各种核函数 # 在上面的示例中，使用了 Gaussian 内核。 其他几个内核也可用。 # ### 可用的内核函数 # 创建一个空白画布 # 为内核列举每个选项 # 初始化内核对象 # 来自 domain 的样本 # 创建一个子图并设置标题 # ### 三个数据点上可用的内核函数 # 现在我们检查核密度估计如何拟合三个等距的数据点。 # 创建三个等距点 # 创建一个空白画布 # 为内核列举每个选项 # 创建一个子图并设置标题 # 拟合模型(密度估计)) # 绘图 # ## 更加复杂的情况 # # 拟合并不总是完美的。 请参阅下面的示例来了解更加复杂的情况。 # 绘制样本散点图 # ## KDE 发行版 # # 由于 KDE 是发行版，所以我们可以访问 KDE 的属性和方法 # # - `entropy` # - `evaluate` # - `cdf` # - `icdf` # - `sf` # - `cumhazard` # ### 累积分布，逆和生存函数 # ### 累积 Hazard 函数